ABAP Tipp - Tabelle per RFC lesen
Eine Tabelle per RFC Baustein einlesen ist sehr einfach, wenn man einen spezifischen Baustein dafür erstellt. Irgendeine Tabelle zu lesen, kann aber genau so einfach sein.
Inhaltsverzeichnis
Über verteilte Landschaften kann es ab und zu mal nötig sein, Daten aus einem anderen System zu lesen oder du willst Daten aus der Produktion in die anderen Systeme (Test, Entwicklung, etc.) verteilen. Es gibt verschiedene Szenarien bei denen du dir einen eigenen Funktionsbaustein sparen kannst, da es bereits generische Varianten zum Lesen von Tabellen gibt.
Vorteile
Die Vorteile bei der Nutzung eines generischen Bausteins liegen dabei schnell auf der Hand:
- Zeit- und Kostenersparnis durch keine eigene Programmierung
- Eine Standardprüfung gegen die Tabellenberechtigungen die sensible Daten im System schützt
- Eingrenzung der Daten und Mengen beim Select
RFC_READ_TABLE
Der Klassiker unter den RFC Funktionsbausteinen ist der RFC_READ_TABLE, da er in den meisten Fällen alle Szenarien abdeckt. Er verfügt über eine Berechtigungsprüfung, die Ausgabefelder können in Anzahl und Reihenfolge verändert werden. Die zurückgegebene Datenmenge beträgt 512 Zeichen, abzüglich der Spaltentrenner die benötigt werden.
Beispiele zur Verwendung des Funktionsbausteins gibt viele im Internet, deshalb wollen wir an dieser Stelle nur grob auf die Verwendung eingehen. Wir möchten dir aber einen Tipp zur Erzeugung der Where-Clause Tabelle nicht vorenthalten.
DATA:
lt_opt TYPE STANDARD TABLE OF rfc_db_opt,
ls_where TYPE rsds_where.
" Einschränkung erstellen
IF mt_sel IS NOT INITIAL.
CALL FUNCTION 'AIBZ_FILL_WHERE_CLAUSE'
EXPORTING
i_tabname = md_table
it_select = mt_sel
IMPORTING
es_where_clause = ls_where.
lt_opt = ls_where-where_tab.
ENDIF.
Nach Befüllung der Selektion mit den einzelnen Einschränkungen kannst du mit Hilfe der Tabelle die Where Bedingung für den RFC Funktionsbaustein generieren lassen. Auch sehr praktisch bei der Verwendung von dynamischen Selektionen.
Probleme
Solange die Breite des Datensatzes ausreicht (512 Zeichen), ist dies auch kein Problem. Aber stell dir vor du möchtest eine Tabelle lesen, bei der eine Spalte bereits über 512 Zeichen hat. Dies ist mit dem Funktionsbaustein nicht möglich und erzeugt nur einen Fehler beim Lesen der Daten.
In unserem Beispiel möchten wir IDoc Daten nachlesen und den Inhalt verifizieren. Doch das Datenfeld SDATA ist 1000 Zeichen breit und kann nicht mit dem normalen RFC Funktionsbaustein gelesen werden. Hier erreichen wir die Grenze des Bausteins.
TABLE_ENTRIES_GET_VIA_RFC
Der Funktionsbaustein prüft ebenfalls die Berechtigungen beim Lesen der Tabelle. Die Zeilenbreite liegt bei 2048 Zeichen und es werden keine Trennzeichen verwendet, um die Daten zurückzugeben. Es wird aber immer die vollständige Struktur zurückgegeben und man kann die Spalten nicht einschränken.
Außerdem hat der Funktionsbaustein ein Problem mit der Konvertierung von Zahlenfeldern, was in einem Programmabbruch endet. Von daher können wir dir den Baustein nur bedingt empfehlen.
CRM_CODEX_GET_TABLE_VIA_RFC
Sieht im Groben wie eine Kopie des Funktionsbausteins TABLE_ENTRIES_GET_VIA_RFC aus, wurde aber um entscheidende Funktionen erweitert. So wird auch eine Offset-Konvertierung vor der Datenzuweisung durchgeführt, womit Zahlen auch kein Problem bei der Übertragung mehr sind.
Für das oben genannte Beispiel haben wir deshalb einmal eine Beispielcoding erstellt, was auch die nachträgliche Konvertierung der Daten enthält.
DATA:
lt_sel TYPE STANDARD TABLE OF bdsel_stat,
lt_fields TYPE STANDARD TABLE OF bdi_mfgrp,
lt_data TYPE STANDARD TABLE OF bdi_entry,
ld_subrc TYPE sysubrc,
ld_sdata TYPE edi_sdata.
FIELD-SYMBOLS:
<ls_data> TYPE edid4,
<ls_head> TYPE e1fikpf.
" Selektion aufbauen
APPEND VALUE #( zeile = |DOCNUM EQ '0000000009991234' AND SEGNAM EQ 'E1FIKPF'| ) TO lt_sel.
" Lesen der Einträge
CALL FUNCTION 'CRM_CODEX_GET_TABLE_VIA_RFC'
EXPORTING
tabname = 'EDID4'
IMPORTING
rc = ld_subrc
TABLES
sel_tab = lt_sel
nametab = lt_fields
tabentry = lt_data
EXCEPTIONS
internal_error = 1
table_has_no_fields = 2
table_not_activ = 3
not_authorized = 4
OTHERS = 5.
IF sy-subrc <> 0.
ENDIF.
" Mapping der Zeile
TRY.
" Lesen der Zeile
DATA(ld_line) = lt_data[ 1 ]-entry.
DATA(ls_field) = lt_fields[ fieldname = 'SDATA' ].
" Mapping Feld -> Struktur
ld_sdata = ld_line ls_field-offset.
ASSIGN ld_sdata TO <ls_head> CASTING.
CATCH cx_root.
ENDTRY.
Wir lesen für ein FIDCC1 oder FIDCC2 den Kopfsatz und mappen die Zeile auf die Datenstruktur. Damit können wir den Inhalt des Kopfes überprüfen und so zum Beispiel den Buchungskreis validieren. Dies funktioniert aber genau so für andere Daten und Tabellen.
Fazit
Das Lesen von generischen Daten über Systeme hinweg sollte mit unserem kleinen Tipp kein Problem mehr für dich sein. Verwende in den meisten Fällen den Funktionsbaustein RFC_READ_TABLE, da er die meiste Flexibilität hat. Sollte die angeforderte Datenzeile doch einmal zu groß sein, kannst du nun auch auf andere Bausteine ausweichen. Hilft dies alles nicht, bleibt noch die Individualentwicklung übrig.