Beispiel für "call-sap-rfc"

Der Aufruf der Funktion call-sap-rfc(alias a,rfc b,[inMap c,timeout d,filter e,outList f,debug g,h,i,j,k]) soll am Beispiel RFC_READ_TABLE gezeigt werden, dessen originale Schnittstellendefinition über Lobster_data abgerufen werden kann und wie folgt aussieht.

RFC_READ_TABLE

Input Parameters

Parameters: INPUT

Index:

1

2

3

4

5

Name:

DELIMITER

NO_DATA

QUERY_TABLE

ROWCOUNT

ROWSKIPS

Type:

CHAR

CHAR

CHAR

INT

INT

Size:

1

1

30

4

4

Offset:

0

1

2

32

36

Decimals:

0

0

0

0

0

Default:

SPACE

SPACE


0

0

Value:



" "



Output Parameters

None

Table Parameters

Parameters: TABLES

Index:

1

2

3

Name:

DATA

FIELDS

OPTIONS

Type:

TABLE

TABLE

TABLE

Size:

4

6

7

Offset:

0

4

10

Decimals:

0

0

0

Value:

TAB512

RFC_DB_FLD

RFC_DB_OPT

Table: DATA (TAB512) No. of Rows: 0 Row-length: 512 (chars) 512 (bytes)

Index:

1

Name:

WA

Type:

CHAR

Size:

512

Offset:

0

Decimals:

0

Table: FIELDS (RFC_DB_FLD) No. of Rows: 0 Row-length: 103 (chars) 103 (bytes)

Index:

1

2

3

4

5

Name:

FIELDNAME

OFFSET

LENGTH

TYPE

FIELDTEXT

Type:

CHAR

NUM

NUM

CHAR

CHAR

Size:

30

6

6

1

60

Offset:

0

30

36

42

43

Decimals:

0

0

0

0

0

Table: OPTIONS (RFC_DB_OPT) No. of Rows: 0 Row-length: 72 (chars) 72 (bytes)

Index:

1

Name:

TEXT

Type:

CHAR

Size:

72

Offset:

0

Decimals:

0


Aus der Beschreibung des Funktionsbaustein ergeben sich die folgenden zu füllenden Parameter.


Parametername

Typ

Bedeutung

Feldnamen innerhalb des Parameters

DELIMITER

Feld Char(1)

Das zwischen den Spalten in der Antwortzeile zu verwendende Trennzeichen.

n.a.

NO_DATA

Feld Char(1)

x, wenn keine Daten, sondern nur Feldinformationen gewünscht sind.

n.a.

QUERY_TABLE

Feld Char(30)

Name der auszulesenden Datenbank-Tabelle.

n.a.

ROWCOUNT

Feld Integer

Anzahl der zu lesenden Zeilen.

n.a.

ROWSKIPS

Feld Integer

Zu überspringende Zeilen bevor ROWCOUNT Zeilen gelesen werden.

n.a.

DATA

Tabelle(OUT)

Enthält nach erfolgreichem Aufruf die ausgelesenen Zeilen.

WA Char(512)

FIELDS

Tabelle(INOUT)

Informationen über die Spalten der ausgelesenen Tabelle bzw. beim Request die Spalten, die beim Ergebnis ausgegeben werden sollen.

FIELDNAME Char(30)

OFFSET Numeric(6)

LENGTH Numeric(6)

TYPE Char(1)

FIELDTEXT Char(60)

OPTIONS

Tabelle(IN)

Text, der dem intern gebildeten SQL-Statement als WHERE-Bedingung hinzugefügt wird.

TEXT Char(72)

Für die Vorbereitung und Durchführung des RFC-Calls kann eine Zielstruktur beispielsweise wie im Folgenden gezeigt aufgebaut sein.


images/download/attachments/62864482/867-version-1-modificationdate-1651132426446-api-v2.png


Grundsätzlich kann der Knoten CallSapRfc in zwei Hauptbereiche unterteilt werden.


  1. Erzeugen der Map, die alle Parameterwerte enthält. Da im vorliegenden Beispiel keine Strukturen als Parameter erwartet werden, beschränkt sich dies hier auf das Füllen der Eingangsfelder (über fill_INPUT_PARAMS) und Tabellen (über fill_TABLE_PARAMS).

  2. Ausführen des RFC-Aufrufs über den Knoten CALL, in dem sich ein zusätzliches Feld dumpParamsKeys befindet, das zum Zwecke des Debuggings die in der Map enthaltenen Schlüssel und Werte ausgibt und z. B. im Mappingtest angezeigt werden.

Füllen der Parametertabelle


Die Felder in den jeweiligen Knoten sind genauso benannt wie die Feldnamen in den jeweiligen Parameterelementen (hier Felder und Tabellen, alles was nach einem # im Namen folgt, wird ignoriert).

Ziel in diesem Beispiel ist die Menge der gelesenen Felder auf eine Teilmenge der möglichen zu reduzieren. Dies wird über eine Liste realisiert, die im Feld prepareFieldSelection vorbereitet wird.


1) save variable a(b) type-safe
a constant: VAR_FIELD_SELECTION
b constant: MANDT,CARRID,CONNID,FLDATE,PRICE,CURRENCY,PLANETYPE
 
2) add to list(a,b,c)
a result: 1
b constant: fieldList
c constant: ,
 
3) count values in list(name of list a)
a constant: fieldList
 
4) save variable a(b) type-safe
a constant: VAR_SIZE
b result: 3


Pro Durchlauf des Knotens fill_FIELDS wird dann das jeweils erste Element aus oben genannter Liste entfernt.


1) remove from list(position a, name of list b)
a constant: 1
b constant: fieldList


Im folgenden seien die Funktionen der einzelnen fill-Felder gezeigt.

In Feld fill_INPUT:


1) fill-map-from-fields( map a, prefix b, index c, hidden d )
a constant: inMap
b constant:
c constant:
d constant: false


In Feld fill_option_table:


1) fill-map-from-fields( map a, prefix b, index c, hidden d )
a constant: inMap
b constant: OPTIONS[#]
c constant: 1
d constant: true


In Feld fill_fields_table:


1) calculate and save variable(a,b,c,d,[e])
a constant: VAR_COUNTER
b constant: +
c constant: 1
d constant: true
 
2) fill-map-from-fields( map a, prefix b, index c, hidden d )
a constant: inMap
b constant: FIELDS[#]
c variable: VAR_COUNTER
d constant: true


dumpParamsKeys dient nur dem Zweck, die Parameter-Schlüssel und Werte im Log des Mappingtests auszugeben. Damit das im produktiven Lauf nicht geschieht, wird die System-Variable VAR_IS_TEST abgeprüft.


1) dump map (a,b)
a constant: inMap
b variable: VAR_IS_TEST


Das Feld callRFC enthält den eigentliche Funktion für den Aufruf des RFCs.


1) call-sap-rfc( alias a,rfc b,[inMap c],[timeout d],[filter e],[outList f],[debug g])
a constant: testsap
b constant: RFC_READ_TABLE
c constant: inMap
d constant: 8
e constant: DATA[1}
f constant: outList
g constant: true


RFC-Aufruf


Beim Starten des Tests erscheint als Ergebnis der Funktionen in dumpParamKeys in diesem Fall folgende Meldung.


[...]
[M:] Dump of map inMap:
'FIELDS[6]-LENGTH'='0'
'FIELDS[5]-FIELDTEXT'=' '
'FIELDS[3]-LENGTH'='0'
'FIELDS[7]-OFFSET'='0'
'FIELDS[1]-OFFSET'='0'
'FIELDS[1]-FIELDNAME'='MANDT'
'FIELDS[4]-LENGTH'='0'
'FIELDS[4]-FIELDNAME'='FLDATE'
'FIELDS[7]-TYPE'=' '
'QUERY_TABLE'='SFLIGHT'
'FIELDS[6]-FIELDTEXT'=' '
'FIELDS[1]-TYPE'=' '
'FIELDS[6]-TYPE'=' '
'FIELDS[7]-FIELDTEXT'=' '
'FIELDS[2]-FIELDTEXT'=' '
'FIELDS[2]-LENGTH'='0'
'OPTIONS[1]-TEXT'='CARRID = 'LH''
[...]
'FIELDS[2]-OFFSET'='0'
'FIELDS[5]-OFFSET'='0'
'FIELDS[5]-LENGTH'='0'
'FIELDS[1]-LENGTH'='0'
'FIELDS[3]-FIELDNAME'='CONNID'
'FIELDS[2]-TYPE'=' '
'ROWCOUNT'='@VAR_ROWCOUNT@'
'FIELDS[4]-OFFSET'='0'
[...]


Aus technischen Gründen ist die Reihenfolge der Schlüssel-Wert-Paare nicht sortiert.

Der Aufruf der Funktion call-sap-rfc liefert folgende Ausgaben.


15:07:52.768 [M:] Calling SAP by RFC 'RFC_READ_TABLE'
15:07:52.893 [M:] rfc debug info: .\debug\sap\1319029672768_debug_RfcIn.xml
15:07:52.940 [M:] rfc debug info: .\debug\sap\1319029672768_debug_RfcOut.xml
15:07:52.940 [M:] Returning from SAP RFC 'RFC_READ_TABLE' after 172 ms
15:07:52.940 [M:field=callRFC] Executed function [Pos=1]call-sap-rfc( alias a,rfc b,[inMap c],[timeout d],[filter e],[outList f],
[debug g]), result='
DATA 000LH 040020011222 666.00 EUR A310-300
DATA 000LH 040020020119 666.00 EUR A310-300
DATA 000LH 040020020216 666.00 EUR A310-300
DATA 000LH 040020020316 666.00 EUR A310-300
DATA 000LH 040020020413 666.00 EUR A310-300


Da Parameter g fix auf true gestellt ist, werden Debug-Trace-Dateien angelegt, deren entsprechende Dateinamen angezeigt werden. Da eine Ausgabeliste angegeben ist, in der die Werte der Ausgabetabelle DATA geschrieben werden, kann der Rückgabewert der Funktion selbst - eine Fixedrecordausgabe der DATA-Tabelle getrost ignoriert bzw. für die Fehlersuche genutzt werden.

Ergebnisauswertung


Im vorliegenden Beispiel wurden die Werte aus der Ergebnistabelle DATA in die Liste outList geschrieben. Jedes Element in der Liste entspricht hierbei einer Zeile der Tabelle DATA. Die Werte der einzelnen Felder müssen hierbei selbst aus dem Text "extrahiert" werden.

Im Beispielprofil erfolgt dies im Knoten OUTPUT.


images/download/attachments/62864482/868-version-1-modificationdate-1651133030906-api-v2.png


Damit der Knoten OUTPUT so oft betreten wird, wie es Einträge in der Liste gibt, wird im Feld readSize die Anzahl in eine Integer-Variable geschrieben und diese als Pfad im Knoten OUTPUT verwendet. Das Berechnungsfeld item entfernt immer den ersten Eintrag in der Liste outList mit der Funktion remove from list an Position 1, alle nachfolgenden Felder verwenden diesen Wert dann immer mittels "Zielwert: item". Wird unter Nutzung von Parameter e mehr als ein Feld oder eine Tabelle angegeben, die in die Antwort gepackt werden soll, muss zwischen den einzelnen Ergebniszeilen unterschieden werden. Daher ist - auch wenn dies im konkreten Beispiel nicht notwendig ist - eine Funktion auf den Knoten OUTPUT gelegt.


1) starts-with( a, b )
a destination: item
b constant: DATA


Ist die Bedingung erfüllt, wird der Knoten betreten und die Zeile im Berechnungsfeld data_item um 30 Zeichen von links gekürzt, um die eigentlichen Datenfelder ab Index 1 zu erreichen.

Alle nachfolgenden Felder holen sich erst den für sie relevanten Teilstring mittels substring( a, start [,length] ) und fahren dann unter Umständen mit weiteren Funktionen mit der Konvertierung der Daten fort, wie exemplarisch am Feld FLDATE gezeigt werden soll.


1) substring( a, start [,length] )
a destination: data_item
b constant: 11
c constant: 8
 
2) create date(a, [adj. template b], template c, d [, force-empty e])
a result: 1
b constant: yyyyMMdd
c constant: dd.MM.yyyy
d constant: empty
e constant:


Ein beispielhaftes Ergebnis eines OUTPUT-Knotens kann wie folgt aussehen.


images/download/attachments/62864482/869-version-1-modificationdate-1651133889636-api-v2.png

Hinweise


Das in diesem Beispiel verwendete Profil kann hier heruntergeladen werden: Package-SAP RFC Call Example RFC_READ_TABLE.pak