fill-map-from-fields( map a, prefix b, index c, hidden d, [processing e] )


Füllt die Named Map a mit Schlüssel-Wert-Paaren. Als Schlüssel werden die Namen der Felder verwendet, die sich im gleichen Knoten oberhalb des aktuellen Feldes befinden, als Wert die aktuellen Werte dieser Felder. Unterknoten und leere Felder werden ignoriert. Durch Parameter b kann optional dem Schlüssel ein Namens-Präfix vorangestellt werden. In Parameter c kann ein Index als Ganzzahl für die Verwendung im Namens-Präfix angegeben werden, falls der Wert b mit [#] endet. Wenn Parameter d den Wert true hat, werden auch Berechnungsfelder ausgewertet. Als optionaler Parameter e kann eine Anweisung hinterlegt werden, die vor Einfügen des Key-Value-Paars in die Map angewendet wird. Das Überschreiben eines Werte zu einem bereits vorhandenen Key führt zu einem Fehlerabbruch. Damit wird die Eindeutigkeit der Key-Value-Paare gesichert. Diese Prüfung kann durch Processing-Anweisungen in Parameter e teilweise oder vollständig abgeschaltet werden.

Diese Funktion wird primär für die Vorbereitung des Aufrufs von call-sap-rfc( alias a,rfc b,[inMap c],[timeout d],[filter e],[outList f],[debug g]) eingesetzt, kann aber auch anderweitig verwendet werden. Die Konvention für die Namensgebung von Schlüsseln folgt derjenigen der besagten Funktion.

Die Felder eines Knotens können verschiedene Dinge repräsentieren, um der Funktion dies mitzuteilen gilt folgende Konvention für die Parameter b und c.


Art der Felder

Parameter b

Parameter c

Resultierender Schlüssel pro Feld

Eine Liste von einzelnen Feldern.

leer

leer

Name des Feldes.

Eine Struktur, die aus einer Liste von Feldern besteht.

Strukturname

leer

Strukturname-Feldname

Eine Tabelle mit den Feldern als darin enthaltene Spalten.

Tabellenname[#]

Index der Zeile

Tabellenname[1]-Spaltenname (bei c=1).

Eine Tabelle mit den Feldern als darin enthaltene Spalten.

Tabellenname[#]

leer

Tabellenname[1]-Spaltenname (bei erster Tabellenzeile). Siehe Auto-Index.

Wenn der Namens-Präfix in b mit [#] endet, muss in Parameter c ein ganzzahliger Zeilen-Index größer als 0 angegeben werden. Dann wird der Platzhalter # durch den Index aus c ersetzt. Andernfalls erfolgt (im expliziten Modus) ein Fehler-Abbruch, falls nicht die Processing-Anweisung idx:inc für die interne Berechnung des Wertes aktiv ist.

Lässt man den Parameter b leer, wird versucht aus dem Namen des Zielknotens selbst herauszulesen, um welche Art Parameterstruktur es sich handelt (impliziter Modus). Dabei wird folgende Namenskonvention herangezogen.


  1. Knotenname beginnt mit SAP_Fields. Dann werden die Felder in diesem Knoten als Import-Parameter des RFC interpretiert.

  2. Knotenname beginnt mit SAP_Struc_Strukturname. Dann werden die Felder als Strukturkomponenten der SAP-Struktur Strukturname interpretiert.

  3. Knotenname beginnt mit SAP_Table_Tabellenname. Dann werden die Felder als Komponenten der SAP-Tabellenstruktur Tabellenname interpretiert.


Diese Namenskonvention wird automatisch erfüllt, wenn die Zielstruktur online durch Strukturimport aus der RFC-Schnittstelle erzeugt wurde. Das Präfix SAP_Fld_ wird hierbei ignoriert.

Parameterbeschreibung


Parameter

Beschreibung

a

Name der zu füllenden Map.

b

(optional) Präfix für Feldnamen.

c

(optional) Tabellenindex.

d

(optional) true, wenn auch Berechnungsfelder für das Füllen verwendet werden sollen. Default: false.

e

(optional) Spezielle Verarbeitung für Feldnamen oder Strukturnamen.


Beispiele für expliziten Modus


Der Zielknoten DestNode soll zweimal betreten worden sein, wobei folgende Felder mit folgenden Werten gemappt worden sind (bei Feld Counter handelt es sich um ein Berechnungsfeld).



Counter

Feld1

Feld2

Feld3

Durchlauf 1

1

1Wert1

1Wert2

1Wert3

Durchlauf 2

2

2Wert1

2Wert2

2Wert3

Folgende Funktionsaufrufe werden hintereinander ausgeführt.


Parameter a

Parameter b

Parameter c

Parameter d

Ergebnis

FieldMap



true

2

StructMap

MyStructure


false

2

TableMap

MyTable[#]

Zielfeld: Counter

false

2

Inhalte der Maps nach Durchlauf 1:


FieldMap

{Counter=1, Feld1=1Wert1, Feld2=1Wert2, Feld3=1Wert3}

StructMap

{MyStructure-Feld1=1Wert1, MyStructure-Feld2=1Wert2, MyStructure-Feld3=1Wert3}

TableMap

{MyTable[1]-Feld1=1Wert1, MyTable[1]-Feld2=1Wert2, MyTable[1]-Feld3=1Wert3}

Inhalte der Maps nach Durchlauf 2:


FieldMap

{Counter=2, Feld1=2Wert1, Feld2=2Wert2, Feld3=2Wert3}

StructMap

{MyStructure-Feld1=2Wert1, MyStructure-Feld2=2Wert2, MyStructure-Feld3=2Wert3}

TableMap

{MyTable[1]-Feld1=1Wert1, MyTable[1]-Feld2=1Wert2, MyTable[1]-Feld3=1Wert3, MyTable[2]-Feld1=2Wert1, MyTable[2]-Feld2=2Wert2, MyTable[2]-Feld3=2Wert3}

Beispiel für impliziten Modus


Wird die Funktion zur Vorbereitung für den call-sap-rfc-Funktion verwendet, kann das Füllen der Werte auch über den impliziten Modus erfolgen, indem Parameter b leer gelassen wird und das Ermitteln der Parametertypen über den Knotennamen erfolgt. Dies soll am Beispiel RFC_READ_TABLE gezeigt werden.

Nach Generierung der Zielstruktur über die Strukturerzeugungsfunktionalität, erhält man Zielknoten, bei der jeder Knoten entweder für eine Liste von Feldern der Eingangsparameter, für einzelne Strukturen oder ganze Tabellen steht.


images/download/attachments/189463359/733-version-1-modificationdate-1738734599477-api-v2.png


Im Anschluss können alle Felder wie gewohnt mit Werten befüllt werden.


images/download/attachments/189463359/734-version-1-modificationdate-1738734599475-api-v2.png


Nicht benötigte Strukturen oder Tabellen kann man komplett entfernen, jedoch müssen alle Komponenten (Felder) einer Struktur bzw. Tabelle mit Werten gefüllt werden, auch wenn nur ein Feld davon tatsächlich genutzt wird. Bei Textfeldern kann dies z.B. ein Leerzeichen, bei numerischen Werten eine 0 sein.

Der Aufruf der Funktion fill-map-from-fields(…) erfolgt im gezeigten Beispiel in dem zusätzlichen letzten Feld fill_FIELDS, entsprechend hat jeder andere Knoten am Ende ein äquivalentes Feld.

Da für Felder ohne zugewiesenen Wert das Key-Value-Paar gar nicht in die Map geschrieben wird, würden nicht zugewiesene Struktur- oder Tabellen-Komponenten in der Map fehlen. Um das zu vermeiden kann man entweder wirklich jeder nicht gefüllten Struktur- oder Tabellen-Komponente einen Fixwert zuordnen, oder mit der Processing-Anweisung val:addempty erreichen, dass auch leere Felder in die Map geschrieben werden. Siehe Abschnitt: Optionale Processing-Anweisungen in Parameter e.

Der als Index bei Tabellen erwartete Parameter c kann sowohl bei Verwendung des expliziten als auch impliziten Modus ebenfalls leer bleiben, wenn der Wert intern ermittelt wird (siehe: Auto-Index).

Optionale Processing-Anweisungen in Parameter e


Verarbeitungsanweisungen beginnen mit Präfix key:, con:, val: oder idx:. Alle anderen werden ignoriert. Mehrere Anweisungen können mit Pipe | getrennt hintereinander stehen.


Präfix

Wird angewendet auf

Anweisung

Wirkung

Bemerkung

key:

Feldnamen.

{description}

Anstelle des Feldnamen wird das Feld-Attribut Beschreibung verwendet, falls es nicht leer ist.


key:

Feldnamen.

{keep}

Der Feldnamen wird unverändert verwendet


key:

Feldnamen.

{sqlkey}

Anstelle des Feldnamen wird das Feld-Attribut SQL Spaltenname verwendet.


key:

Feldnamen.

regex=replacement

Der reg. Ausdruck regex im Feldnamen wird durch replacement ersetzt.


con:

Struktur-/Tabellen-Name.

{description}

Anstelle des Knotennamen wird Knoten-Attribut Beschreibung verwendet, falls es nicht leer ist.

Nur im impliziten Modus möglich.

con:

Struktur-/Tabellen-Name.

regex=replacement

Regex-Ersetzung im Struktur-/Tabellenname.

Nur im impliziten Modus möglich.

val:

Feldwert.

addempty

Fügt den Key auch für leere Felder zur Map hinzu.

Für Struktur- und Tabellentypen muss jede Komponente definiert sein.

val:

Feldwert.

fill

Füllt den Wert bis zur Feldlänge auf, entspr. Fill-Attributen des Feldes von links bzw. rechts. Wirkt nicht bei empty value.

Nur bei Feldlänge>0 und wenn Füllzeichen angegeben ist.

val:

Feldwert.

format

Füllt numerische Felder von links mit 0 und String-Felder von rechts mit SPACE. Wirkt nicht bei empty value.

Nur bei Feldlänge>0 und wenn nicht val:fill gilt.

val:

Feldwert.

overwrite

Erlaubt generell das Überschreiben existierender Werte. Erlaubt das Überschreiben eines Wertes zu einem bereits existierenden Key.


val:

Feldwert.

empty_ovw

Erlaubt das Überschreiben, wenn der alte Wert empty war. Erlaubt das Überschreiben eines Wertes zu einem bereits existierenden Key, wenn der alte Wert empty war.


val:

Feldwert.

equal_ovw

Erlaubt das Überschreiben, wenn alter und neuer Wert gleich sind. Erlaubt das Überschreiben eines Wertes zu einem bereits existierenden Key mit dem gleichen Wert.


idx:

Tabellen-Index.

inc

Bei leerem Parameter c wird der Tabellenindex (falls nötig) aus den bisherigen Tabellenzeilen berechnet, anstelle aus der Knoteniteration.

Siehe Auto-Index.

idx:

Tabellen-Index.

nochk

Im impliziten Modus (SAP-Modus) wird die Prüfung, ob der Index der Tabellenzeilen mit 1 beginnend lückenlos fortlaufend ist, abgeschalten.

Für Tabellentypen wird nicht geprüft, ob der Index lückenlos ist.

Hinweis: Mit der Instruktion val:addempty werden leere Felder hinzugefügt, die sonst ignoriert werden. Bei Struktur- oder Tabellentypen werden dann auch die nicht gefüllten Struktur-Komponenten erzeugt. Dadurch wird in der anschließend aufgerufenen Funktion call-sap-rfc(…) der Fehler vermieden: input parameter missing.

Allerdings ist es nicht möglich, zu erkennen, ob im SAP-Repository für diese Strukturkomponente ein Default existiert oder nicht. Der Wert eines leeren Feldes ist deshalb no value, aber nicht der Defaultwert, der eventuell in SAP definiert ist. Ob der RFC/BAPI dann seinerseits den leeren Komponentenwert durch den Default ersetzt, bzw. ob er überhaupt mit leeren Werten zurechtkommt, muss im Einzelfall geprüft oder getestet werden. Erklärungen zum Wert no value entnehmen Sie bitte den Hinweisen zur Funktion get empty flag(a).

Formatierungen des Feldwertes durch Processing-Anweisung val:...

Manchmal ist es notwendig, die Feldwerte zu formatieren bzw. aufzufüllen, bevor sie an den RFC gesendet werden . Da die Feldformatierungen und Fixwerte erst nach der kompletten Funktionen-Kette angewendet werden, wirken sie noch nicht zum Zeitpunkt der Ausführung dieser Funktion. Die Funktion ist aber in der Lage diese Feldattribute zu lesen und selbst entsprechende Formatierungen der in die Map geschriebenen Key-Value-Paare auszuführen, wenn die Processing-Anweisung val:fill bzw. val:format angegeben wird. Falls gleichzeitig val:fill und val:format aktiv ist (z. B. val:fillformat), hat val:fill Vorrang bei den Feldern, denen ein Füllzeichen zugeordnet ist. Bei den übrigen wirkt val:format.


Felder, Strukturen oder Tabellen mit Namespaces


In SAP können Feld-, Struktur- oder Tabellen-Namen im Kontext eines SAP Namespaces stehen.


  • /Namespace/Fieldname , z. B.: /XYZ/ADDRESS_ID

  • /Namespace/Tablename, z. B.: /ABC2/ADDRESS

     

Beim Import der RFC-Schnittstelle als Zielstruktur, wie oben beschrieben, werden die Slashes / in Unterstriche _ gewandelt, weil in einem Knoten- oder Feldnamen kein Slash vorkommen darf.

Die Tabelle /ABC2/ADDRESS wird dann als Knoten mit dem Namen SAP_Table__ABC2_ADDRESS erzeugt und das Feld darunter als SAP_Fld__XYZ_ADDRESS_ID. Ein nachfolgender Aufruf der Funktion call-sap-rfc(…) kann dann die richtigen Keys nicht in der Map finden, was entweder zu einem Fehlerabbruch führen kann, oder die entsprechenden Werte werden nicht an den RFC übergeben.

Um den richtigen Key in die Map zu schreiben, kann man die Processing-Anweisungen verwenden. Dabei wirkt die Anweisung key: auf die Feldnamen und die Anweisung con: auf die Knotennamen. Der Präfix con: steht dabei für den Kontext, also den Knoten.

Man kann entweder den richtigen Struktur- bzw. Tabellennamen mit Namespace im Knotenattribut Beschreibung hinterlegen und con:{description} als Processing verwenden. Oder man kann den Knotennamen durch einen regulären Ausdruck mit dem Processing con:regex=replacement korrigieren. Siehe auch: Reguläre Ausdrücke.

Zur Korrektur von Feldnamen bzw. Struktur- oder Tabellen-Element-Namen wirkt analog der Präfix key: anstelle con:. Bei Ziel-Feldern existiert zusätzlich das Feldattribut SQL Spaltenname, das mit dem Processing key:{sqlkey} ausgewertet wird.

Beispiel mit regulären Ausdrücken


  • Um im Knotennamen _ABC2_ durch /ABC2/ zu ersetzen, wird als Processing con:\Q_ABC2_\E=/ABC2/ verwendet.

  • Um im Feldnamen _XYZ_ durch /XYZ/ zu ersetzen, wird als Processing key:\Q_XYZ_\E=/XYZ/ verwendet.


Die gesamte Processing-Anweisung in Parameter e lautet dann con:\Q_ABC2_\E=/ABC2/|key:\Q_XYZ_\E=/XYZ/, wobei die Reihenfolge der beiden Anweisungen beliebig ist.

Hinweis: In einem regulären Ausdruck wird der zwischen \Q und \E eingeschlossene Text literal (wie er ist) verwendet.

Auto-Index für Tabellentypen


Zur Adressierung von SAP-Tabellentypen, speziell im impliziten Modus bei Tabellen, wird der Tabellen-Index entweder als Parameter c erwartet, oder bei leerem c intern berechnet. Üblicherweise wird der Index aus dem Iteration-Level des Knotens ermittelt. Falls allerdings durch eine Funktion auf dem Knoten das Betreten des Knotens verhindert wird, zählt der Iteration-Level auch für nicht betretene Iterationen weiter, obwohl keine Tabellenzeile in die Map übergeben wird. Dadurch ergibt sich in der Indexreihenfolge der Tabellenzeilen eine Lücke. In Funktion call-sap-rfc(...) wird die Tabelle an dieser Lücke beendet, weil SAP von einer lückenlosen Indexreihenfolge ausgeht. Dadurch werden nicht alle Tabellenzeilen an SAP übergeben.

Um diesen Fehler zu vermeiden, wurde eine Prüfung bei Tabellentypen implementiert, ob die Einträge lückenlos sind und mit Index 1 beginnen. Diese Prüfung erfolgt nur bei Tabellen, sowohl im expliziten, als auch impliziten Modus. Diese Prüfung ist relativ CPU-lastig und kann abgeschaltet werden, wenn sie nicht benötigt wird, mit der Processing-Anweisung idx:nochk innerhalb Parameter e.

Um eine lückenlose Indexadressierung der Tabelleneinträge auch bei teilweise nicht betretenem Knoten zu erreichen, verwenden Sie bitte entweder eine Counter-Variable in Parameter c oder - bei leerem c - den Increment-Modus mit der Processing-Anweisung idx:inc innerhalb Parameter e. Dabei wird in der Map der letzte Eintrag dieser Tabelle gesucht und daraus der aktuelle Index berechnet.

Ohne idx:inc wird bei Tabellen-Typen und leerem Parameter c der Iteration Level des Knotens verwendet (impliziter Modus), bzw. im expliziten Modus eine Exception erzeugt, weil dort die Berechnung des Index aus dem Iteration Level des Knotens nicht angeboten wird.

Hinweis: Der Increment-Modus ist CPU-lastig und sollte nur verwendet werden, wenn der Iteration Level zu Lücken in der Index-Reihenfolge führen kann und damit zu Fehlern bei der Übergabe der Tabelle an den SAP-RFC.