[ABAP] OpenSQL: Unterschied SELECT, SELECT SINGLE, SELECT DISTINCT

SELECT

* Selektiert alle Einträge für 'DE' und 'US', mit Mehrfachnennungen
SELECT cityto
  INTO TABLE @DATA(it_dest)
  FROM spfli
  WHERE countryfr = 'DE'
     OR countryfr = 'US'.

*CITYTO:
*SAN FRANCISCO
*NEW YORK
*FRANKFURT
*SAN FRANCISCO
*NEW YORK
*TOKYO
*NEW YORK
*FRANKFURT
*NEW YORK
*BERLIN
*FRANKFURT
*SINGAPORE
*SINGAPORE
*SAN FRANCISCO
*FRANKFURT
*FRANKFURT
*NEW YORK

cl_demo_output=>display_data( it_dest ).

SELECT DISTINCT

* Selektiert alle Einträge für 'DE' und 'US', ohne Mehrfachnennungen
SELECT DISTINCT cityto
  INTO TABLE @DATA(it_dest)
  FROM spfli
  WHERE countryfr = 'DE'
     OR countryfr = 'US'.

*CITYTO:
*TOKYO
*BERLIN
*NEW YORK
*SINGAPORE
*FRANKFURT
*SAN FRANCISCO
cl_demo_output=>display_data( it_dest ).

SELECT SINGLE

* Selektiert den ersten Datensatz für 'DE' und 'US'
SELECT SINGLE cityto
  INTO @DATA(lv_dest)
  FROM spfli
  WHERE countryfr = 'DE'
     OR countryfr = 'US'.

*CITYTO:
*SAN FRANCISCO
cl_demo_output=>display_data( lv_dest ).

[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] Abbildung von boolschen Werten im ABAP

Typen

Typ          Herkunft                  Anmerkung
----------------------------------------------------------------------------------------------------------------------------------
abap_bool    Typegruppe ABAP           empfohlen in den offiziellen ABAP Programming Guidelines
                                       Ab Release 7.40 sind bei Predicative Method Calls Rückgabewerte vom Typ ABAP_BOOL notwendig
                                       https://help.sap.com/doc/abapdocu_752_index_htm/7.52/de-DE/abenpredicative_method_calls.htm
boolean      Datenelement BOOLEAN      hat keine Feldbezeichner
xfeld        Datenelement XFELD        hat keine Feldbezeichner
os_boolean   Datenelement OS_BOOLEAN
wdy_boolean  Datenelement WDY_BOOLEAN
ddbool_d     Datenelement DDBOOL_D

Werte

boolscher Typ  ABAP-Konstante                ABAP-Wert  Definition         Datentyp  Länge
------------------------------------------------------------------------------------------
true           abap_true                     'X'        Typegruppe ABAP    char      1
false          abap_false                    ' '        Typegruppe ABAP    char      1
               abap_undefined                '-'        Typegruppe ABAP    char      1
true           cl_abap_typedescr=>true       'X'        cl_abap_typedescr  char      1
false          cl_abap_typedescr=>false      ' '        cl_abap_typedescr  char      1
               cl_abap_typedescr=>undefined  '-'        cl_abap_typedescr  char      1

[ABAP] Interne Tabellen: Schleifen mit FOR, THEN, WHILE, GROUPS, IN GROUP

Variante 1 (FOR … WHILE)

DATA(it_strings) = VALUE stringtab( ).

it_strings = VALUE #(
* For i = 1 To 10
                      FOR i = 1 WHILE i < 11
                      (
                        |{ i }|
                      )
                    ).

cl_demo_output=>display( it_strings ).

Variante 2 (FOR … WHILE mit Schrittweite)

                        
DATA(it_strings) = VALUE stringtab( ).

it_strings = VALUE #(
* For i = 1 To 10 Step 2
                      FOR i = 1 THEN i + 2 WHILE i < 11
                      (
                        |{ i }|
                      )
                    ).

cl_demo_output=>display( it_strings ).

Variante 3 (NESTED FOR)

                        
SELECT * FROM sflight INTO TABLE @DATA(it_sflight).
SELECT * FROM spfli INTO TABLE @DATA(it_spfli).

DATA(it_strings) = VALUE stringtab(
* alle Einträge aus sflight ab 01.01.2013
                                    FOR <f> IN it_sflight INDEX INTO idxf WHERE ( fldate >= '20130101' )
* alle Einträge aus spfli mit den Schlüsseln wie in der Ergebnismenge des vorherigen FOR
                                      FOR <c> IN it_spfli INDEX INTO idxc WHERE ( carrid = <f>-carrid AND connid = <f>-connid )
                                      (
* Ausgabe als Stringtab
                                        |{ idxf } \| { idxc } \| { <c>-carrid } \| { <c>-connid } \| { <c>-airpfrom }|
                                      )
                                  ).

cl_demo_output=>display( it_strings ).

Variante 4 (FOR GROUPS, FOR … IN GROUP)

TYPES: BEGIN OF ty_mat,
         matnr TYPE matnr,
         mtart TYPE mtart,
         price TYPE kbetr,
       END OF ty_mat.

TYPES: ty_it_mat TYPE HASHED TABLE OF ty_mat WITH UNIQUE KEY matnr
                                             WITH NON-UNIQUE SORTED KEY key_mtart COMPONENTS mtart.

TYPES: BEGIN OF ty_mat_sum,
         mtart TYPE mtart,
         count TYPE i,
         price TYPE kbetr,
       END OF ty_mat_sum.

TYPES: ty_it_mat_sum TYPE HASHED TABLE OF ty_mat_sum WITH UNIQUE KEY mtart.

* Tabelle mit Materialien
DATA(it_mat) = VALUE ty_it_mat(
                                ( matnr = '1' mtart = 'ROH'  price = '1.56' )
                                ( matnr = '2' mtart = 'ROH'  price = '2.00' )
                                ( matnr = '3' mtart = 'NLAG' price = '3.10' )
                                ( matnr = '4' mtart = 'NLAG' price = '0.40' )
                                ( matnr = '5' mtart = 'NLAG' price = '4.10' )
                                ( matnr = '6' mtart = 'HALB' price = '1.00' )
                                ( matnr = '7' mtart = 'HALB' price = '0.10' )
                              ).

* Tabelle gruppiert nach Materialarten ohne 'HALB' und summierten Preisen
DATA(it_mat_sum) = VALUE ty_it_mat_sum(
                                        FOR GROUPS grp OF <mtart> IN it_mat WHERE ( mtart NE 'HALB' ) GROUP BY ( mtart = <mtart>-mtart size = GROUP SIZE )
                                        (
                                          mtart = grp-mtart " Materialart der Gruppe
                                          count = grp-size  " Anz. Elemente der Gruppe
                                          price = REDUCE #( " Summe über die Elemente der akt. Gruppe bilden
                                                            INIT p = '0.00'
                                                            FOR <m> IN GROUP grp WHERE ( mtart = grp-mtart )
                                                            NEXT p = p + <m>-price
                                                          )
                                        )
                                      ).

cl_demo_output=>display( it_mat_sum ).

Links

[ABAP] Nützliche ABAP-Datentypen, Domänen, Tabellentypen

* Datentypen
* DD04L
* DD04T
* DD04V

Name          Typ         Länge   Beschreibung
---------------------------------------------------------------------------
MANDT         CLNT        3       Mandant

DEC_16_01_S   DEC         16,1    Dezimalwert mit 1 Nachkommastelle
DEC_16_02_S   DEC         16,2    Dezimalwert mit 2 Nachkommastellen
DEC_16_03_S   DEC         16,3    Dezimalwert mit 3 Nachkommastellen
DEC_16_04_S   DEC         16,4    Dezimalwert mit 4 Nachkommastellen
DEC_16_05_S   DEC         16,5    Dezimalwert mit 5 Nachkommastellen
DEC_16_06_S   DEC         16,6    Dezimalwert mit 6 Nachkommastellen
DEC20_2       DEC         20,2    Dezimalwert mit 2 Nachkommastellen
DEC20_3       DEC         20,3    Dezimalwert mit 3 Nachkommastellen
DECIMAL21_7   DEC         21,7    Dezimalwert mit 7 Nachkommastellen
DEC23_2       DEC         23,2    Dezimalwert mit 2 Nachkommastellen
DEC31_14      DEC         31,14   Dezimalwert mit 14 Nachkommastellen

SURL          CHAR        255     URL Länge 255
SWK_URL       CHAR        2048    URL Länge 2048
SKWF_URL      CHAR        4096    URL Länge 4096
USS_Y_URL     CHAR        255     URL Länge 255
VBC_URL2      CHAR        1024    URL Länge 1024

BAPI_MSG      CHAR        220     Meldungstext
ERR_TEXT      CHAR        60      Fehlertext
TEXT255       CHAR        255     Text Lowercase
TWB_S_TXT     CHAR        200     Groß / Kleinschreibung berücksichtigt
TXT50         CHAR        50      Text
VBC_TEXT      CHAR        255     Beschreibung Lowercase
VBI_TEXT      CHAR        255     Beschreibung Lowercase
VEPTEXT       CHAR        255     Kurzbeschreibung Lowercase

SYSUUID_C     CHAR        32      UUID in Character-Darstellung

EDPLINE       CHAR        72      EDIC Programm-Editor Zeile

TABNAME       CHAR        30      Tabellenname

ERNAM         CHAR        12      Name des Benutzers
XUANAME       CHAR        12      Anleger des Benutzerstamms
XUBNAME	      CHAR        12      Benutzername im Benutzerstamm
XUMODIFIER    CHAR        12      Letzter Änderer

AWKGR         CURR        15,2    Betrag
BELWER        CURR        15,2    Betrag
KWERT         CURR        13,2    Konditionswert

ABBDT         DATS        8       Beginndatum des Zeitabschnitts
ABDATUM       DATS        8       Beginn eines Zeitraumes
ADATU         DATS        8       Datum Gültigkeitsbeginn
BEGDATUM      DATS        8       Beginndatum
BEGINDATE     DATS        8       Beginndatum
ERSDA         DATS        8       Erstellungsdatum (JJJJMMDD)
LAEDA         DATS        8       Datum der letzten Änderung (JJJJMMDD)
XULDATE       DATS        8       Letzes Login-Datum (JJJJMMDD)
XUERDAT       DATS        8       Anlegedatum des Benutzerstamms (JJJJMMDD)
XUMODDATE     DATS        8       Modifikationsdatum (JJJJMMDD)

BEGINUZ       TIMS        6       Beginnuhrzeit
BEGUZ         TIMS        6       Beginnuhrzeit
XULTIME       TIMS        6       Letzte Anmeldeuhrzeit (HHMMSS)
XUMODTIME     TIMS        6       Modifikationszeit (HHMMSS)

TIMESTAMP     DEC         15      UTC-Zeitstempel in Kurzform (JJJJMMTThhmmss)
TIMESTAMPL    DEC         21,7    UTC-Zeitstempel in Langform (JJJJMMTThhmmssmmmuuun)

* Domänen
* DD01L
* DD01T
* DD01V

Name          Typ         Länge   Beschreibung
---------------------------------------------------------------------------
RSDSSELOPT    CHAR        45      Zeilentyp für RANGE-Tabelle
FUNCNAME      CHAR        30      Unterprogrammname
TDSFNAME      CHAR        30      Smart Forms: Formularname

* Strukturen
* DD02L
* DD03L
* DD03T


* Tabellentypen
* DD40L
* DD40T

Typ            Zeilentyp   Länge   Beschreibung
----------------------------------------------------------------------------
BAPIRETTAB     BAPIRET2            Tabelle mit BAPI Return Informationen
BAPIRET2_T     BAPIRET2            Returntabelle
BDCDATA_TAB    BDCDATA     309     Tabelle für Batchdaten
SOTR_TXTS      CHAR        255     Texttabelle
TTTEXT255      CHAR        255     Texttabelle
HTML_TABLE     W3HTML      255     Texttabelle für HTML
W3_HTMLTAB     W3_HTML     255     Texttabelle für HTML
INT4_TABLE     INT4        10      Standard Table of INT4
W3MIMETABTYPE  RAW         255     Tabelle für RAW-Daten
XML_RAWDATA    RAW         255     Tabelle für RAW-Daten
WD_OBJECTS     REF                 Tabelle zur Speicherung von REF TO OBJECT
RSEC_T_SPOPLI  SPOPLI      67      Auswahl von Werten
RSELOPTION     RSDSSELOPT  93      SELECT-OPTIONS Tabelle
STRINGTAB      STRING              Tabelle mit Strings
STRING_TABLE   STRING              Tabelle mit Strings
TLINE_T        TLINE               Tabelle mit TLINE
ICL_THEAD_TAB  THEAD               tabelle mit THEAD

[ABAP] OpenSQL: Vergleich von SELECT-Abfragen über RANGES, FOR ALL ENTRIES, JOINS

Allgemein

In den folgenden Beispielen werden drei der gängigen Datenbankzugriffe über ein SELECT nach Laufzeit sowie Vor- und Nachteilen verglichen.

Variante 1 (RANGE)

* Laufzeit: 0,086142s

* Vorteile:
*   - Aufteilen und Manipulieren von verknüpften DB-Abfragen
*   - Abfrage in einem Block -> gut für kleine Abfragen mit wenigen RANGE-Einträgen
*   - Verwendung z.B. bei Nutzung von SELECT-OPTIONS
* Nachteile:
*   - Laufzeitverhalten bei großen Abfragen
*   - keine Abhängigkeiten von zwei oder mehr Feldern in einem RANGE abbildbar (Verknüpfung in der WHERE-Clause erfolgt nur einzeln über AND/OR)
*   - RANGES werden beim SELECT in ein Statement mit vielen ORs umgewandelt
*     -> abhängig vom DB-System kommt es früher oder später zu DUMPS, wenn der RANGE zu viele Einträge beinhaltet (Speichergröße der RANGE-Table > 64kB)
DATA: lv_maktx TYPE maktx VALUE '<empty>'.

DATA(o_timer) = cl_abap_runtime=>create_hr_timer( ).
DATA(usec_start) = o_timer->get_runtime( ).

* SELECT 1: Materialnummern
SELECT m~matnr, @lv_maktx AS maktx
  INTO TABLE @DATA(it_mara)
  FROM mara AS m
  UP TO 1000 ROWS.

DATA: rg_matnr TYPE RANGE OF matnr.

* MATNR in RANGE kopieren, darauf achten, dass die Suchfelder UNIQUE sind
rg_matnr = VALUE #( FOR <m> IN it_mara
                    (
                      sign   = 'I'
                      option = 'EQ'
                      low    = <m>-matnr
                      high   = ''
                    ) ).

* SELECT 2: Kurztexte
SELECT t~matnr, t~maktx
  INTO TABLE @DATA(it_makt)
  FROM makt AS t
  WHERE t~matnr IN @rg_matnr
    AND t~spras = @sy-langu.

* Zuweisung MATNR, MAKTX
LOOP AT it_mara ASSIGNING FIELD-SYMBOL(<t>).
  IF line_exists( it_makt[ matnr = <t>-matnr ] ).
    <t>-maktx = it_makt[ matnr = <t>-matnr ]-maktx.
  ENDIF.
ENDLOOP.

DATA(usec_end) = o_timer->get_runtime( ).
DATA(usec) = CONV decfloat16( usec_end - usec_start ).
DATA(sec) = usec / 1000000.

WRITE: / 'Laufzeit: ', sec, 's'.

cl_demo_output=>display( it_mara  ).

Variante 2 (FOR ALL ENTRIES)

* Laufzeit: 0,073252s

* Vorteile:
*   - Aufteilen und Manipulieren von verknüpften DB-Abfragen
*   - mehrere FOR ALL ENTRIES können pro Statement verwendet werden
*   - Verwendung z.B. bei Verarbeitung von vielen Datensätzen
* Nachteile:
*   - Laufzeitverhalten bei großen Abfragen
*   - wenn die FOR ALL ENTRIES Liste leer ist, wir die WHERE-Clause ignoriert, was zu unerwünschten Nebeneffekten führen kann
*   - FOR ALL ENTRIES werden beim SELECT in viele einzelne Statements umgewandelt
*   - man sollte darauf achten, dass die Einträge in der FOR ALL ENTRIES-Tabelle nur einmal auftreten -> Performance
*   - Speicherverbrauch durch die vielen Abfragen
* Anmerkungen:
*   - doppelte Einträge in der FOR ALL ENTRIES Tabelle werden entfernt (SELECT DISTINCT)
*   - wichtige Parameter für die Performance von FOR ALL ENTRIES sind:
*     rsdb/max_blocking_factor
*     rsdb/min_blocking_factor
*     rsdb/max_in_blocking_factor
*     rsdb/min_in_blocking_factor
*     rsdb/prefer_in_itab_opt
*     rsdb/prefer_fix_blocking
DATA: lv_maktx TYPE maktx VALUE '<empty>'.

DATA(o_timer) = cl_abap_runtime=>create_hr_timer( ).
DATA(usec_start) = o_timer->get_runtime( ).

* SELECT 1: Materialnummern
* darauf achten, dass die Einträge in der FOR ALL ENTRIES Tabelle UNIQUE sind
SELECT m~matnr, @lv_maktx AS maktx
  INTO TABLE @DATA(it_mara)
  FROM mara AS m
  UP TO 1000 ROWS.

* Prüfung auf IS INITIAL ist wichtig, da sonst die WHERE-Clause im SELECT ignoriert würde
IF NOT it_mara IS INITIAL.

* SELECT 2: Kurztexte
  SELECT t~matnr, t~maktx
    INTO TABLE @DATA(it_makt)
    FROM makt AS t
    FOR ALL ENTRIES IN @it_mara
    WHERE t~matnr = @it_mara-matnr
      AND t~spras = @sy-langu.

* Zuweisung MATNR, MAKTX
  LOOP AT it_mara ASSIGNING FIELD-SYMBOL(<m>).
    IF line_exists( it_makt[ matnr = <m>-matnr ] ).
      <m>-maktx = it_makt[ matnr = <m>-matnr ]-maktx.
    ENDIF.
  ENDLOOP.
ENDIF.

DATA(usec_end) = o_timer->get_runtime( ).
DATA(usec) = CONV decfloat16( usec_end - usec_start ).
DATA(sec) = usec / 1000000.

WRITE: / 'Laufzeit: ', sec, 's'.

cl_demo_output=>display( it_mara  ).

Variante 3 (JOIN)

* Laufzeit: 0,012196s

* Vorteile:
*   - wesentlich schneller als RANGE und FOR ALL ENTRIES
*   - eine komplexe DB-Anfrage (generisch)
*   - Verwendung bei Verarbeitung von vielen Datensätzen verteilt über viele Tabellen
* Nachteile:
*   - komplexe Statements
*   - schlecht zu Debuggen
DATA(o_timer) = cl_abap_runtime=>create_hr_timer( ).
DATA(usec_start) = o_timer->get_runtime( ).

* SELECT: Materialnummern, Kurztexte
SELECT m~matnr, t~maktx
  INTO TABLE @DATA(it_mara)
  FROM mara AS m
  RIGHT OUTER JOIN makt AS t ON ( m~matnr = t~matnr )
  UP TO 1000 ROWS
  WHERE t~spras = @sy-langu.

DATA(usec_end) = o_timer->get_runtime( ).
DATA(usec) = CONV decfloat16( usec_end - usec_start ).
DATA(sec) = usec / 1000000.

WRITE: / 'Laufzeit: ', sec, 's'.

cl_demo_output=>display( it_mara  ).

Links

[ABAP] Arbeit mit Referenzen

einfache Wertänderung über Referenz

* int-Variable anlegen, Wert 1
DATA(lv_int) = 1.
* Referenz auf int
DATA(o_int) = REF #( lv_int ).

* Änderung auf Wert 2
lv_int = 2.

* Ausgabe Wert 2
WRITE: / o_int->*.

* Änderung auf 3
o_int->* = 3.

* Ausgabe Wert 3
WRITE: / lv_int.

mehrfache Wertänderung über Referenz

* int-Variable anlegen, Wert 1
DATA(lv_int) = 1.
* generische Referenz auf die int-Variable
DATA(o_int) = REF data( lv_int ).
* Variable auf Wert 2 ändern
lv_int = 2.

* Zwei Feldsymbole (<i1> und <i2>) mit der Referenz verknüpfen
ASSIGN o_int->* TO FIELD-SYMBOL(<i1>).
ASSIGN o_int->* TO FIELD-SYMBOL(<i2>).

* den Wert eines der Feldsymbole ändern
<i1> = 4.

* es ändern sich durch den Bezug sogleich alle anderen Feldsymbole und Variablen mit :)
WRITE: / lv_int.
WRITE: / <i1>.
WRITE: / <i2>.

generische Referenz auf interne Tabelle

* Stringtable aus DDIC (gefüllt)
DATA(it_stringtab) = VALUE stringtab( ( |Udo| )
                                      ( |Heinz| )
                                      ( |Klaus| ) ).

* generische Referenz auf die Stringtable
DATA(o_tab) = REF data( it_stringtab ).

* Feldsymbol explizit als generische Table definieren
FIELD-SYMBOLS: <tab> TYPE ANY TABLE.
* Feldsymbol auf die interne Tabelle mit der generischen Referenz verknüpfen
ASSIGN o_tab->* TO <tab>.

* Tabelleninhalt darstellen
LOOP AT <tab> ASSIGNING FIELD-SYMBOL(<l>).
  WRITE: / <l>.
ENDLOOP.

referentieller Zugriff auf eine interne Tabelle

* Typdeklaration
TYPES: ty_it_sflight TYPE STANDARD TABLE OF sflight WITH DEFAULT KEY.

* Tabelle anlegen
DATA(it_sflight) = VALUE ty_it_sflight( ( carrid = 'AA' connid = '0123' )
                                        ( carrid = 'LH' connid = '3210' ) ).

* generische Referenz auf die Table
DATA(o_tab) = REF data( it_sflight ).

* Feldsymbol explizit als generische Table definieren
FIELD-SYMBOLS: <tab> TYPE ty_it_sflight. " hier auch STANDARD TABLE möglich
* Feldsymbol auf die interne Tabelle mit der generischen Referenz verknüpfen
ASSIGN o_tab->* TO <tab>.

* wenn Zeilen in der Tabelle vorhanden
IF lines( <tab> ) > 0.
* erste Zeile holen und mit Feldsymbol verknüpfen
  ASSIGN <tab>[ 1 ] TO FIELD-SYMBOL(<row>).
* Struktur (Felder) der ersten Zeile ermitteln
  DATA(o_struct) = CAST cl_abap_structdescr( cl_abap_typedescr=>describe_by_data( <row> ) ).
* Anzahl Felder in der Struktur ermitteln
  DATA(lv_cnt) = lines( o_struct->get_components( ) ).

* Tabelleninhalt darstellen
  LOOP AT <tab> ASSIGNING <row>.

    DATA(lv_row) = ||.

* Felder durchgehen
    DO lv_cnt TIMES.
* Zellen einer zeile holen
      ASSIGN COMPONENT sy-index OF STRUCTURE <row> TO FIELD-SYMBOL(<cell>).
* Zellinhalt ausgeben
      IF sy-index = 0.
        lv_row = |{ <cell> }|.
      ELSE.
        lv_row = |{ lv_row } \| { <cell> }|.
      ENDIF.
    ENDDO.

    WRITE: / lv_row.
  ENDLOOP.

ENDIF.

[ABAP] OO: Variablen, Strukturen, interne Tabellen, Objektreferenzen anlegen

Variable anlegen

* int
DATA(lv_int) = 1.
DATA(lv_int_empty) = VALUE i( ).
 
* float
DATA(lv_float_empty) = VALUE f( ).
DATA(lv_float) = CONV f( '0.1' ).
 
* char
DATA(lv_char) = 'ABCD'.
 
* string
DATA(lv_empty_string) = ||.
DATA(lv_string) = |Text|.
 
* bool
DATA(lv_bool) = abap_true.
 
* DDIC-Typ (z.B. MATNR)
DATA(lv_matnr) = CONV matnr( '1234567890' ).
DATA(lv_matnr_empty) = VALUE matnr( ).

Struktur anlegen

* definiert vom Anwender
TYPES: BEGIN OF ty_sflight,
         carrid TYPE sflight-carrid,
         connid TYPE sflight-connid,
       END OF ty_sflight.

DATA(lv_struct) = VALUE ty_sflight( carrid = 'LH'
                                    connid = '0123' ).

* Strukturtyp aus DDIC (leer)
DATA(lv_headdata_empty) = VALUE bapimathead( ).

* Strukturtyp aus DDIC (gefüllt)
DATA(lv_headdata) = VALUE bapimathead( material      = '1234567890'
                                       basic_view    = abap_true
                                       purchase_view = abap_true
                                       account_view  = abap_true ).

interne Tabelle anlegen

* definiert vom Anwender
TYPES: BEGIN OF ty_sflight,
         carrid TYPE sflight-carrid,
         connid TYPE sflight-connid,
       END OF ty_sflight.

TYPES: ty_it_sflight TYPE STANDARD TABLE OF ty_sflight WITH DEFAULT KEY.

DATA(it_tab) = VALUE ty_it_sflight( ( carrid = 'LH' connid = '0123' )
                                    ( carrid = 'AA' connid = '3210' ) ).

* Stringtable aus DDIC (leer)
DATA(it_stringtab_empty) = VALUE stringtab( ).

* Stringtable aus DDIC (gefüllt)
DATA(it_stringtab) = VALUE stringtab( ( |Udo| )
                                      ( |Heinz| )
                                      ( |Klaus| ) ).

Objektreferenz anlegen

* Objektreferenz auf Klasse ALV-Grid
DATA(o_alv) = NEW cl_gui_alv_grid( i_parent      = cl_gui_container=>default_screen
                                   i_appl_events = abap_true ).

* Referenz auf int
DATA(lv_int) = 1.
DATA(o_int) = REF #( lv_int ).

* Referenz auf stringtab
DATA(it_stringtab) = VALUE stringtab( ).
DATA(o_tab) = REF #( it_stringtab ).