[ABAP] Konvertierung einer Struktur in Binärdaten (x, xstring) und zurück

Variante 1 (FIELD-SYMBOLS, CASTING: Struktur <-> Typ x)

* einfachen Typ deklarieren
TYPES: BEGIN OF ty_struct,
         matnr TYPE matnr,
         int   TYPE i,
         float TYPE f,
         text  TYPE char10,
       END OF ty_struct.

* Feldsymbol für Binärdaten
FIELD-SYMBOLS <x> TYPE x.
* Feldsymbol für Strukturdaten
FIELD-SYMBOLS <s> TYPE ty_struct.

* Struktur anlegen, deren Daten kovertiert werden soll
DATA(lv_s) = VALUE ty_struct( matnr = '1234567890'
                              int   = 1
                              float = '1.1'
                              text  = 'abc' ).

* Struktur in Binärdaten umwandeln
ASSIGN lv_s TO <x> CASTING.
IF <x> IS ASSIGNED.
* Binärdaten in Struktur umwandeln
  ASSIGN <x> TO <s> CASTING.
  IF <s> IS ASSIGNED.
    DATA(lv_s2) = <s>.
* Datenausgabe
    WRITE: / lv_s2-matnr.
    WRITE: / lv_s2-int.
    WRITE: / lv_s2-float.
    WRITE: / lv_s2-text.
  ENDIF.
ENDIF.

Variante 2 (xstring -> Struktur)

* https://www.consolut.com/s/sap-ides-zugriff/d/e/doc/M-CL_ABAP_CONV_IN_CE/
* einfachen Typ deklarieren
TYPES: BEGIN OF ty_struct,
         text TYPE char5,
         int  TYPE i,
       END OF ty_struct.

* Zielstruktur
DATA(lv_s) = VALUE ty_struct( ).

* Konverterobjekt mit UTF-8 und Little Endian Konvertierung
DATA(o_conv) = cl_abap_conv_in_ce=>create( encoding = 'UTF-8' endian = 'L' ).
* View-Objekt
DATA(o_view) = cl_abap_view_offlen=>create_legacy_view( lv_s ).
* Eingabepuffer mit Binärdaten
DATA(lv_buffer) = CONV xstring( '616263202000000005000000' ).

* Konvertierung xstring -> Struct
*  in: HEX: 616263202000000005000000
* out: Struct: text: abc
*               ínt: 5
o_conv->convert_struc( EXPORTING
                         input = lv_buffer
                         view  = o_view
                       IMPORTING
                         data  = lv_s ).

* Datenausgabe
WRITE: / lv_s-text.
WRITE: / lv_s-int.

Variante 3 (Struktur -> xstring)

* https://www.consolut.com/s/sap-ides-zugriff/d/e/doc/M-CL_ABAP_CONV_OUT_CE/
* einfachen Typ deklarieren
TYPES: BEGIN OF ty_struct,
         text TYPE char5,
         int  TYPE i,
       END OF ty_struct.

* Struktur mit Quelldaten
DATA(lv_s) = VALUE ty_struct( text = 'abc'
                              int  = 5 ).

* Konverterobjekt mit UTF-8 und Little Endian Konvertierung
DATA(o_conv) = cl_abap_conv_out_ce=>create( encoding = 'UTF-8' endian = 'L' ).
* View-Objekt
DATA(o_view) = cl_abap_view_offlen=>create_legacy_view( lv_s ).
* Ausgabepuffer für Binärdaten
DATA: lv_buffer type xstring.

* Konvertierung Struct -> xstring
*  in: Struct: text: abc
*               ínt: 5
* out: HEX: 616263202000000005000000
o_conv->convert_struc( EXPORTING
                         data   = lv_s
                         view   = o_view
                       IMPORTING
                         buffer = lv_buffer ).

* Datenausgabe
WRITE: / lv_buffer.

[ABAP] Vergleich Feldsymbole (FIELD-SYMBOLS) und Datenreferenzen (REF TO)

Feldsymbole (FIELD-SYMBOLS)

  • Alias / Referenz auf Datenbereich
  • im Ggs. zu Referenzen nur Wertvergleich möglich, kein Vergleich der Referenz
  • Zuweisung erfolgt zur Laufzeit
  • Casting möglich: ASSIGN … TO CASTING TYPE typename.

Datenreferenzen (REF TO)

  • Pointer auf Datenobjekte
  • im Ggs. zu Feldsymbolen ist der Vergleich von Referenzen und Werten möglich
  • typisiert: … TYPE REF TO typename.
  • untypisiert: … TYPE REF TO data.
  • dynamische Speicherallokation über NEW
  • Casting möglich: CAST, ?=
  • Zurgiff erfolgt immer über Dereferenzierung (->, ->*)

[ABAP] Eine Tabellenzeile einer internen Tabelle an ein Feldsymbol binden (Table Expressions)

DATA: itab TYPE STANDARD TABLE OF ...
FIELD-SYMBOLS: <fs1> TYPE ...

* Zeile mit Index 1 an Feldsymbol
ASSIGN itab[ 1 ] TO FIELD-SYMBOL(<fs1>).

FIELD-SYMBOLS: <fs2> TYPE ...

* Komponente 1 aus Zeile 2 an Feldsymbol
ASSIGN COMPONENT 1 OF STRUCTURE itab[ 2 ] TO FIELD-SYMBOL(<fs2>).

* Komponente 'NAME' aus Zeile 1 an Feldsymbol
ASSIGN COMPONENT 'NAME' OF STRUCTURE itab[ 1 ] TO FIELD-SYMBOL(<fs2>).

[ABAP] Generische Verarbeitung von internen Tabellen / Verwendung von Referenzen

* irgendeine interne Tablelle anlegen
DATA: it_tab TYPE STANDARD TABLE OF ...
* generische Tabellenreferenz anlegen
DATA: o_ref_table TYPE REF TO data.
 
...
 
* Tabellenreferenz übergeben
o_ref_table = REF #( it_tab ).
 
* Referenz auf generisches Feldsymbol mappen
FIELD-SYMBOLS: <tab> TYPE ANY TABLE.
ASSIGN o_ref_table->* TO <tab>.
 
* Tabellen-Zeile erzeugen
* muss hier erfolgen, damit man ein "greifbares" Tabellen-Zeilen-Objekt
* für die Strukturermittlung (describe_by_data) hat
DATA: o_row TYPE REF TO data.
CREATE DATA o_row LIKE LINE OF <tab>.
FIELD-SYMBOLS: <row> TYPE any.
ASSIGN o_row->* TO <row>.
 
* Komponenten (Spalten) einer Tabellenzeile ermitteln
DATA(o_struct) = CAST cl_abap_structdescr( cl_abap_typedescr=>describe_by_data( <row> ) ).
DATA(it_comp_tab) = o_struct->get_components( ).
 
* Anzahl Spalten der Tabellen-Zeile holen
DATA(lv_colcnt) = lines( it_comp_tab ).
 
* Tabelle durchloopen
LOOP AT <tab> ASSIGNING <row>.

* Spalten der akt. Zeile durchgehen
  DO lv_colcnt TIMES.
* Zelle: n-tes Element der akt. Zeile holen
    ASSIGN COMPONENT sy-index OF STRUCTURE <row> TO FIELD-SYMBOL(<cell>).
    
* Trennzeichen vor die Spalte einfügen, wenn nicht 1. Spalte
    IF sy-index > 1.
      WRITE: '|'.
    ENDIF.

* Achtung: Zell-Typ beachten! Es können hier nur flache Typen (Keine Strukturen, Tabellen) ausgegeben werden, der Rest muss gesondert behandelt werden
    IF CAST cl_abap_elemdescr( it_comp_tab[ sy-index ]-type )->kind = cl_abap_elemdescr=>kind_elem.
* Ausgabe Zellinhalt mit vordefinierter Spaltenbreite
      WRITE: |{ <cell> WIDTH = 20 |.
    ENDIF.
  ENDDO.

  NEW-LINE.
ENDLOOP.

[ABAP] Referenzen, Dereferenzierung, Feldsymbole, Typecast

* allg. Referenz auf irgendwas (data)
DATA: lo_data TYPE REF TO data.

* Referenz auf den allg. Typ object
DATA: lo_obj TYPE REF TO object.

* allg. Feldsymbol
FIELD-SYMBOLS: <fs_any> TYPE ANY.

* dynamic Typecast
lo_obj ?= <fs_any>.

IF lo_obj IS BOUND. " != null
  " lo_obj ist instanziiert

  " Dereferenzierung, Wert an der Stelle der Referenz
  lo_obj->* ...
ELSE.
  " lo_obj ist nicht instanziiert
ENDIF.

[ABAP] Interne Tabelle mit NEW-Operator erstellen / Zugriff über Feldsymbole und Table Expressions

* Zeile
TYPES: BEGIN OF ty_data,
         kunnr TYPE i,
         name TYPE string,
         ort TYPE string,
       END   OF ty_data.
* Tabellentyp
TYPES: it_itab TYPE STANDARD TABLE OF ty_data WITH DEFAULT KEY.
* Feldsymbol für Zugriff
FIELD-SYMBOLS: <lt_text> TYPE it_itab.

* neue interne Tabelle mit Inhalt erstellen
DATA(dref) = NEW it_itab( ( kunnr = '123' name = 'ABCD' ort = 'LV' )
                          ( kunnr = '456' name = 'XYZ'  ort = 'LA' ) ).

* Zuweisung Feldsymbol
ASSIGN dref->* TO <lt_text>.

* Zugriff auf Inhalt der internen Tabelle über Feldsymbol und Table Expression
WRITE: / <lt_text>[ 1 ]-ort.

[ABAP] Daten einer internen Tabelle verändern (Index, Key, Feldsymbol)

* Tabelleninhalt über Index modifizieren
MODIFY itab FROM struct INDEX 1.

* Eintrag in der Tabelle über ein Feldsymbol direkt ändern
FIELD-SYMBOLS: <z2> LIKE LINE OF itab.
READ TABLE itab WITH TABLE KEY keyname = 'Wert' ASSIGNING <z2>.
<z2>-Element = 'Wert'.

* Änderung einer Tabellenspalte (struct-element) über Bedingung
MODIFY itab FROM struct TRANSPORTING element WHERE keyname = 'Wert'.

[ABAP] Verwendung von Feldsymbolen (Zeiger)

* Zeilentyp
TYPES: BEGIN OF ty_data,
         name TYPE string,
         ort TYPE string,
       END   OF ty_data.

* Tabellentyp
TYPES: ty_it_itab TYPE STANDARD TABLE OF ty_data WITH DEFAULT KEY.

* Tabelle
DATA: it_itab TYPE ty_it_itab.

* Feldsymbol definieren
FIELD-SYMBOLS: <fs_line> TYPE ty_data.

* Beispielausgabe 1 mit Feldsymbol
LOOP AT itab ASSIGNING <fs_line>.
  WRITE: / <fs_line>-name, <fs_line>-ort.
ENDLOOP.

* Beispielausgabe 2 mit Inline-Feldsymbol
LOOP AT itab ASSIGNING FIELD-SYMBOL(<fs_inline>).
  WRITE: / <fs_inline>-name, <fs_inline>-ort.
ENDLOOP.