Manchmal, aber nur manchmal… ♫
hält SAP Überraschungen bereit, das glaubt man kaum…
Aber von vorne.
In einem Projekt haben wir uns gewundert, warum es in einer dynamisch generierten internen Tabelle einen CONVERSION OVERFLOW gab, obwohl das Feld vom Typ DEC ausreichend groß dimensioniert war. Die Lösung war offensichtlich. Hinterher…
Erzeugung
Wir sind bei der Erzeugung der internen Tabelle wie folgt vorgegangen:
- Definition des Feldkataloges
- Erzeugung der internen Tabelle mit Hilfe von cl_alv_table_create=>create_dynamic_table
Beispielhaft kann die Erzeugung folgendermaßen veranschaulicht werden:
FIELD-SYMBOLS <fcat> TYPE lvc_s_fcat. DATA gt_table TYPE lvc_t_fcat. APPEND INITIAL LINE TO gt_fcat ASSIGNING . <fcat>-fieldname = 'FELD1'. <fcat>-scrtext_l = 'Feld 1: CHAR'. <fcat>-inttype = 'C'. <fcat>-intlen = 20. <fcat>-datatype = 'CHAR'. APPEND INITIAL LINE TO gt_fcat ASSIGNING . <fcat>-fieldname = 'FELD2'. <fcat>-scrtext_l = 'Feld 2: DEC'. <fcat>-inttype = 'P'. <fcat>-intlen = 16. <fcat>-datatype = 'DEC'. <fcat>-decimals = 2. CALL METHOD cl_alv_table_create=>create_dynamic_table EXPORTING it_fieldcatalog = gt_fcat i_length_in_byte = abap_true IMPORTING ep_table = gd_table EXCEPTIONS generate_subpool_dir_full = 9.
Das macht SAP
Im Debugger sieht man die erzeugte Datenstruktur im Detail.
Hier ist auch erkennbar, dass die gepackte Zahl im internen Format nicht 16 Bytes groß ist, sondern nur 8. Dadurch passt nur eine vierzehnstellige Zahl (plus Vorzeichen) in das Feld. Im Coding wurde jedoch die maximale Größe von intern 16 Bytes verwendet.
Versteckte Parameter
Ich habe mir die Erzeugung der internen Tabelle durch cl_alv_table_create=>create_dynamic_table genauer angesehen und bin dann recht schnell auf den Parameter I_LENGTH_IN_BYTE gestoßen. Dieser Parameter ist in der Schnittstelle – wie so oft – sehr anschaulich und gut dokumentiert:
boolsche Variable (X=true, space=false)
Der Parameter ist optional und hat als Vorgabewert ABAP_FALSE.
Um es vorweg zu nehmen: Nachdem wir den Parameter auf ABAP_TRUE gesetzt haben, funktionierte alles, wie erwartet.
Beim Debuggen bin ich irgendwann auf folgende Stelle gestossen:
if ls_fieldcat-inttype eq 'P'. if r_length_in_byte eq abap_true. l_leng = ls_fieldcat-intlen. else. l_leng = ( ls_fieldcat-intlen + 1 ) / 2. endif. endif.
Meiner Meinung nach ist das Coding hier verkehrt, da gepackte Zahlen immer aus Halbbytes bestehen. An dieser Stelle darf nicht einfach die Länge halbiert werden. Warum genau diese “Halbierung” statt findet, habe ich auch nicht verstanden. Es hat wahrscheinlich mit Unicode zu tun.
Fazit
Die Erzeugung von internen Tabellen sollte meiner Meinung nach eh nicht mehr mit dem erwähnten Funktion erzeugt werden, da hier im Hintergrund Subroutine-Pools generiert werden. Die Verwendung ist nur eingeschränkt möglich (maximale Anzahl Aufrufe: 36). Inzwischen sind die Möglichkeiten mit CREATE DATA & RTTC deutlich eleganter und zukunftssicherer. Allerdings habe ich die Verwendung von CREATE_DYNMIC_TABLE auch schon mal als elegant bezeichnet…
Die Methode mit CREATE_DYNAMIC_TABLE hat auch einen großen Vorteil: Bei dem Aufbau der internen Tabelle kann ich gleich semantische Informationen mitgeben/ anreichern (Titel, Texte, Suchhilfen etc.), die nicht automatisch übernommen werden. Ich dann diesen Feldkatalog nicht nur zur Erzeugung der internen Tabelle verwenden, sondern auch für die Anzeige.
Bei der Variante über CREATE DATA und RTTC werden fast ausschließlich die technischen Informationen ausgewertet. Wenn ein verwendetes Datenelement korrekte Überschriften hat, ist es okay, aber wenn ich eigene Felder mit einem generischen Datenelement aufbaue (FELD1, FELD2) und diese im gleichen Zug benennen will, dann muss ich dies separat tun.
- 7. December: Excel Racing Simulation – Root Vole Race - 7. Dezember 2024
- 5. December: ABAPConf - 5. Dezember 2024
- 4. December: Only a lazy developer is a good developer - 4. Dezember 2024