ABAP - Arbeiten mit Referenzen
Die Arbeit mit Referenzen ist in ABAP meist nicht so weit verbreitet wie die Arbeit mit Feldsymbolen. Wir möchten dir die wichtigsten Einsatzzwecke und Verwendungen zeigen.
Inhaltsverzeichnis
Wie funktionieren eigentlich genau Referenzen in ABAP und für was kann man sie alles einsetzen? Diese Frage wollen wir im heutigen Artikel klären und dir die Details zur Verwendung etwas näher bringen.
Allgemein
Wenn du mit Referenzen arbeitest funktionieren sie in den meisten Fällen wie Feldsymbole und so helfen sie dir, z.B. Inhalte von Tabellenzeilen zu ändern. Sie dienen ebfalls zu Übergabe von dynamischen Daten in Schnittstellen von Methoden. Auf die meisten Aspekte von Referenzen werden wir in diesem Artikel eingehen.
GET REFERNECE OF
Der Befehl wurde mittlerweile durch die neue Variante REF abgelöst und funktioniert damit wie ein Value oder andere Funktionen die neue Elemente generieren können. Dazu ein kleines Beispiel zur Veranschaulichung:
DATA:
lt_database TYPE STANDARD TABLE OF t001 WITH EMPTY KEY,
lr_data TYPE REF TO DATA.
" Old Style
GET REFERENCE OF lt_database INTO lr_data.
" New Style
lr_data = REF #( lt_database ).
Die Verwendung der Inline-Deklaration der Zielvariable ist bei beiden Befehlen möglich und ist entsprechend ab Release 7.40 verfügbar. Dabei wird von der Quellvariable eine Referenz erzeugt, über deren Wert der Inhalt geändert werden kann. In anderen Programmiersprachen wird dies als Pointer beschrieben.
Einsatz
Der Einsatz von Referenzen ist vielfältig im System möglich, wir wollen dir hier mal die gebräuchlichsten Fälle aufzeigen. Beachte dabei, das es sich nicht um eine vollständige Sammlung handelt.
Loop
Die Verarbeitung in einer Schleife ist die die meistgenutzte Form des Einsatzes. Im Loop kann auf einzelne Felder zugegriffen werden, so wie auf Attribute oder Methoden einer Klasse. Möchtest du die Referenz als einfach Struktur weitergeben, dann geschieht das über Dereferenzierung (->*) im Aufruf.
LOOP AT lt_database REFERENCE INTO DATA(lr_database).
" Set a new value
lr_database->butxt = 'New Value'.
" Handle the structure to a method
call_a_method( lr_data->* ).
ENDLOOP.
Tabellen
Du möchtest einen leeren Datensatz in einer Tabelle einfügen, um dann mit der Referenz weiterzuarbeiten? Kein Problem, denn es funktioniert genau so gut, wie mit Feldsymbolen.
DATA:
lt_company_code TYPE STANDARD TABLE OF t001 WITH EMPTY KEY,
lt_sorted_ccode TYPE SORTED TABLE OF t001 WITH UNIQUE-KEY bukrs.
" Insert into standard table
INSERT INITIAL LINE INTO TABLE lt_company_code REFERENCE INTO DATA(lr_standard).
" Insert into sorted table
INSERT VALUE #( bukrs = '1337' ) INTO TABLE lt_sorted_ccode REFERENCE INTO DATA(lr_sorted).
Bei einer sortierten Tabelle musst du darauf achten, dass der Schlüssel der Tabelle bereits gefüllt ist, du kannst hier keine leere Zeile anhängen, da es ansonsten zu einer Ausnahme kommt.
Tabellenzeile
Eine Zeile einer Tabelle lesen und den Inhalt dieser im Anschluss ändern, auch dies ist für Referenzen kein Problem. Nach dem Lesen der Zeile über den Index oder den Schlüssel, kann der Inhalt frei geändert werden (Schlüssel der Tabelle beachten) oder an andere Methoden zum Ändern gegeben werden.
DATA:
lt_sorted_ccode TYPE SORTED TABLE OF t001 WITH UNIQUE-KEY bukrs.
" Read per index
DATA(lr_index_line) = REF #( lt_sorted_ccode[ 1 ] ).
lr_index_line->butxt = 'New Value'.
" Read per key
DATA(lr_key_line) = REF #( lt_sorted_ccode[ bukrs = '1337' ] ).
lr_key_line->butxt = 'New Value'.
Verarbeitung
Die Verarbeitung von dynamischen Daten sollte für dich ebenfalls kein Problem darstellen. In unserem Beispiel erhalten wir Daten (eine Tabelle) als Referenz zurück. Da die Referenz auf "TYPE REF TO data" basiert, können wir in der Verarbeitung nicht einfach über die Daten loopen.
Dazu führen wir zuerst eine Dereferenzierung durch und weisen die Daten einem Feldsymbol vom entsprechenden Tabellentypen zu. Beim Loop können wir dann auf die einzelnen Felder per Assign zugreifen.
FIELD-SYMBOL:
<lt_table> TYPE STANDARD TABLE.
DATA(lr_table_ref) = get_data_by_reference( ).
ASSIGN lr_table_ref->* TO <lt_table>.
LOOP AT <lt_table> INTO FIELD-SYMBOL(<ls_table_line>).
" Work with data
ENDLOOP.
Dynamische Daten
Gern werden Referenzen auch genutzt, um dynamische Daten in Returning-Parametern zurückzugeben und diese später dynamisch zu verarbeiten (siehe Verarbeitung oben). Doch bei der Rückgabe der Referenz sollte auf einige Kleinigkeiten geachtet werden, damit dies auch klappt.
Aktuell haben wir uns dabei immer nur Beispiele angezeigt bei denen wir die Referenz direkt verwenden oder sie an eine Methode weitergeben. In diesen Fällen funktioniert die Weitergabe auch wie gewünscht, da die Variable, auf der die Referenz basiert noch existiert. Wollen wir das Ergebnis allerdings als Referenz über einen Returning Parameter zurückgeben, kommt es zu einer "Freed Reference".
" Definition
METHODS:
get_data_by_reference
RETURNING VALUE(rr_result) TYPE REF TO data.
" Implementation
METHOD get_data_by_reference.
SELECT * FROM t001 INTO TABLE @DATA(lt_company_codes).
rr_result = REF #( lt_company_codes ).
ENDMETHOD.
Das oben gezeigte Beispiel führt zu einem Fehler und einer Ausnahme, sobald du auf die Referenz zugreifen willst. Hier musst du die Referenz erst korrekt erzeugen, bevor du die Daten zuweisen kannst und diese auch aus der Methode herausgeben kannst. Eine mögliche Lösung könnte daher wie folgt aussehen:
METHOD get_data_by_reference.
SELECT * FROM t001 INTO TABLE @DATA(lt_company_codes).
CREATE DATA rr_result TYPE STANDARD TABLE OF t001.
ASSIGN rr_result->* TO FIELD-SYMBOL(<lt_result_table>).
<lt_result_table> = CORRESPONDING #( lt_company_codes ).
ENDMETHOD.
Im ersten Schritt erstellen wir eine Datenreferenz auf den richtigen Typen der Daten und geben der Referenz einen Körper mit dem Feldsymbol. Im letzten Schritt kannst du dann die Daten per CORRESPONDING übernehmen. Die Referenz kann zurückgegeben und verwendet werden.
Fazit
Die Arbeit mit Referenzen und dem neuen Standard ist recht einfach und mit etwas Übung wird dir das Ganze ins Blut übergehen. Risikolos ist die Verwendung allerdings nicht und du solltest die von uns gezeigten Regeln beachten, dann hast du mit Refernezen viel Spaß in Zukunft.