Der Schlüsselbefehl Read table im neuen ABAP mit Tabellenausdrücken

Aus SAP-Wiki
Zur Navigation springenZur Suche springen

Siehe Neues ABAP (ab Release 7.40).

Siehe Kategorie: Neues ABAP.

Siehe Prädikatfunktion LINE EXISTS.

Warum Tabellenausdrücke statt READ TABLE

Ab der ABAP-Version 7.40 gibt es auch weiter entwickelte Alternativen zu "Read table", indem in eckigen Klammern "[[ <tabellenzeile> ]]" die Tabellenzeile angesprochen wird mit einem sogenannten "Tabellenausdruck".

DATA (lv_ziel) = itab[ 5 ]-tiefestruktur[ 1 ]-spalte1.

Dieser Tabellenausdruck kann als Operantenteil von anderen Anweisungen genutzt werden und führt insofern zu kompakteren und performanteren Coding. Tabellenausdrücke können auch ineinander geschachtelt sein und insofern können tiefe Strukturen damit gelesen werden.

Es kann eine Zeile oder auch genau ein Feld einer Zeile gelesen werden.

Lesen Tabellenzeile mit Index

Alte Syntax mit "Read table index"

Um eine interne Tabelle zu lesen, wird klassisch der Schlüsselbefehl "Read table index .." genutzt.

READ TABLE itab INDEX lv_index INTO wa.

Um dann ein Feld einer anzusprechen: Die Zeile der Tabelle wird gelesen und dann aus der Struktur das Feld angesprochen und der Zielvariablen zugewiesen.

READ TABLE itab INDEX lv_index INTO wa.

lv_feld = wa-feld.

Neue Syntax mit "itab[ index ]"

Erste Zeile wird gelesen mit "[ index ]". Zwischen dem eckigen Klammern und dem Zeilenindex steht jeweils ein Leerzeichen.

Data: ls_sflight type sflight.

ls_sflight = lt_sflight[ 1 ].

Bei einer Zuweisung zu einem Field-Symbol

Assign lt_sflight[ 1 ] to <fs_sflight>.

Man kann auch gleich lediglich ein Feld der Struktur zuweisen, was sehr elegant ist

Data: lv_carrid type sflight-carrd.

lv_carrid = lt_sflight[ 1 ]-carrid.

Wenn die Zeile nicht gefunden wird, wird die Exception CX_SY_ITAB_LINE_NOT_FOUND ausgelöst.

Folglich wird auch kein SY-SUBRC gesetzt. Entweder es wird eine Zeile gefunden (SY-SUBRC bleibt bei 0) oder es wird die Exception CX_SY_ITAB_LINE_NOT_FOUND ausgelöst.

Ab ABAP 7.40 SP08 die Möglichkeit mit dem Zusatz OPTIONAL abzufangen, dass keine Zeile gefunden werden kann, ohne das die Exception ausgelöst wird. Mit dem DEFAULT kann ein Wert an die Zielvariable übertragen werden für den Fall, dass keine Tabellenzeile gefunden wurde.

Neue Syntax mit "itab[ index ]" OPTIONAL

Es ist auch möglich ohne das mögliche Auslösen der Exception CX_SY_ITAB_LINE_NOT_FOUND zu arbeiten. Dann muss man allerdings mit dem Schlüsselwort VALUE arbeiten.

ls_sflight = VALUE #( lt_sflight[ 1 ] OPTIONAL ).

Wenn hier kein Datensatz in LT_SFLIGHT ist, dann wird kein Datensatz in die Struktur LS_SFLIGHT geschrieben und die Exception CX_SY_ITAB_LINE_NOT_FOUND wird nicht ausgelöst.

Vorsicht: kein Setzen von SY-SUBRC

Beim Tabellenausdruck wird SY-SUBRC nicht ungleich 0 gesetzt, sofern kein Datensatz gefunden wurde. Syntaxfehlerfrei, aber funktional nicht korrekt wäre

ls_sflight = VALUE #( lt_sflight[ 1 ] OPTIONAL ).

if sy-subrc <> 0.
   ...
endif.

Dann würde man eher folgendes Coding schreiben

ls_sflight = VALUE #( lt_sflight[ 1 ] OPTIONAL ).

if ls_sflight is initial.
   ...
endif.

Dann müsste man allerdings kritisch hinterfragen, ob bei einem Finden eines Datensatzes einer internen Tabelle auch wirklich immer die Zielstruktur ungleich initial sein muss. Sonst könnte es zu einer falschen Schlussfolgerung kommen. Dann sollte man ohne den Zusatz OPTIONAL arbeiten (mit der Ausnahme CX_SY_ITAB_LINE_NOT_FOUND) oder z. B. den klassischen READ TABLE verwenden

read table lt_sflight index 1 into ls_sflight.

if sy-subrc <> 0.
  ..
endif.

Lesen Tabellenzeile mit Bedingung

Struktur einer Tabelle lesen

Es können mehrere Felder innerhalb der Klammern abgefragt werden.

wa = itab[ feld1 = .. feld2 = .. ].

oder auch auf mehrere Zeilen verteilt

wa = itab[ feld1 = ..
           feld2 = .. ].

Bei einer Zuweisung zu einem Field-Symbol

Assign itab[ feld1 = ..
             feld2 = .. ] to <fs>.

Bei einer Zuweisung zu einem Field-Symbol mit inline-Deklaration

Assign itab[ feld1 = ..
             feld2 = .. ] to field-symbol(<fs>).

Feld einer Struktur einer Tabelle lesen

Sehr elegant ist in der neuen Syntax, dass man den Rückgabewert einer Abfrage einer internen Tabelle als Bedingung nutzen kann.

Die Bedingung steht in "[ <Bedingung> ]".

Hier wird von der internen Tabelle LT_SVAL mit dessen Feld TABNAME abgefragt ob hier "EKPO" steht und ob der Wert des Feldes VALUE initial ist.

IF lt_sval[ tabname = 'EKPO' ]-value IS INITIAL.
  RETURN.
ENDIF.

oder hier wird der Warenempfänger aus der internen Tabelle LT_PARTN gelesen.

Data(lv_kunwe) = lt_partn[ PARTN_ROLE = 'WE' ]-PARTN_NUMB.

Keine Zeile gefunden - Ausnahme CX_SY_ITAB_LINE_NOT_FOUND

Man muss beim Tabellenausdruck mit der neuen ABAP-Syntax vorsichtig sein, wenn ein gesuchter Datensatz nicht vorhanden ist. Wenn der Datensatz nicht vorhanden ist, wird eine Ausnahme "CX_SY_ITAB_LINE_NOT_FOUND" ausgelöst und wenn man diese Ausnahme nicht abfängt, kommt es zu einem Laufzeitfehler.

cs_adressen-kunnr_mf = lt_vbpa[ parvw = 'MF' ]-kunnr.

Ausnahme

Hier war ein Partner "MF" nicht in der internen Tabelle LT_VBPA vorhanden.

Tabellenausdruck1.JPG

Behandlung mit TRY-ENDTRY-Fehlerbehandlung

Man könnte die Ausnahme abfangen mit einer TRY-ENDTRY-Fehlerbehandlung.

try.
  cs_adressen-kunnr_mf = lt_vbpa[ parvw = 'MF' ]-kunnr.

  catch CX_SY_ITAB_LINE_NOT_FOUND.
   ... (Fehlerbehandlung)
endtry.

Tabellenausdruck mit Zusatz OPTIONAL

Eleganter ist ab ABAP 7.40 SP8 der Zusatz "optional". Der Befehl funktioniert allerdings nur in Kombination mit "VALUE".

cs_adressen-kunnr_mf = value #( lt_vbpa[ parvw = 'MF' ]-kunnr OPTIONAL )

Web-Links

Literatur