Modernes ABAP

Inline Declaration mit DATA() und FIELD-SYMBOLS()

(C) Brandeis Consulting.

Das Problem mit der Deklaration

An vielen Stellen im ABAP Code benötigen wir eine Variable mit exakt passendem Datentyp. Diese musste früher vorher passend deklariert werden. Das hat unter anderem die folgenden Nachteile:

  • Die Deklaration kostet Zeit, insbesondere wenn der exakte Datentyp zuvor noch ermittelt werden musste
  • Die Deklaration braucht Platz im Quellcode, der ohne eigentliche Logik ist. Bei skalaren Typen eine Zeile, bei Strukturen auch schnell sehr viele Zeilen.
  • Es gibt eine starke Kopplung zwischen unterschiedlichen Codestellen, teilweise klassenübergreifend.
    TYPES: BEGIN OF linetype,
             task_id  TYPE zbc_tasks-task_id,
             status   TYPE zbc_tasks-status,
             solution TYPE zbc_tasks-solution,
           END OF linetype.

    DATA tasks TYPE STANDARD TABLE OF linetype 
      WITH DEFAULT KEY.

    SELECT task_id,
           status,
           solution
      FROM zbc_tasks
      INTO TABLE @tasks.

    out->write( tasks ).

  ENDMETHOD.
(C) Brandeis Consulting.

Die Lösung: Inline Declaration

Konzept

An Ort und Stelle, wo eine Variable das erste Mal gebraucht wird, d.h. bei der Zuweisung eines Wertes, wird diese auch deklariert.
Voraussetzung: Der Datentyp lässt sich eindeutig* Ermitteln.

*Zumindest teilweise.

    SELECT task_id, 
           status,
           solution
      FROM zbc_tasks
      INTO TABLE @DATA(tasks).

    out->write( tasks ).
(C) Brandeis Consulting.

Im direkten Vergleich

Mit Vorabdeklaration

    TYPES: BEGIN OF linetype,
             task_id  TYPE zbc_tasks-task_id,
             status   TYPE zbc_tasks-status,
             solution TYPE zbc_tasks-solution,
           END OF linetype.

    DATA tasks TYPE STANDARD TABLE OF linetype 
      WITH DEFAULT KEY.

    SELECT task_id,
           status,
           solution
      FROM zbc_tasks
      INTO TABLE @tasks.

    out->write( tasks ).

  ENDMETHOD.

Mit Inline Declaration

    SELECT task_id, 
           status,
           solution
      FROM zbc_tasks
      INTO TABLE @DATA(tasks).

    out->write( tasks ).
(C) Brandeis Consulting.

Der Kontext ist wichtig

Damit Inline Declaration funktionieren, muss der Datentyp bei der Zuweisung anhand der Position von DATA(<Variable>) ausreichend klar sein.

Die SAP spricht hierbei von Declaration Positions.

(C) Brandeis Consulting.

Beispiele: Inline Declarations bei einfachen Zuweisungen

Der Datentyp ergibt sich aus dem Ausdruck der rechten Seite eindeutig.

DATA(textvar) = 'Zeichenkette'.

DATA(typedescr) = cl_abap_typedescr=>describe_by_data( some_data ).

DATA(gross_amount) = net_amount * (taxrate/100+1) .

Der Datentyp passt sich automatisch an, wenn auf der Rechten Seite eine Veränderung ist. Z.B. eine Factory-Methode eine anderen Rückgabetypen hat oder eine Zeichenkette länger wird.

(C) Brandeis Consulting.

Beispiele: Inline Declarations bei Methodenaufrufen

Der Datentyp ergibt sich aus der Deklaration der Methode.

Deklaration der Methode

    methods exporting_many_params  
       exporting chicken type chickentype
                 cow     type cowtype
                 dog     type dogtype
                 bird    type birdtype. 

Mit Inline Declaration

my_method( IMPORTING chicken = data(chicken)
                     cow     = data(cow)
                     dog     = data(dog)
                     bird    = data(bird) ).

Mit Vorabdeklaration

DATA chicken TYPE chickentype  .
DATA cow     TYPE cowtype      .
DATA dog     TYPE dogtype      .
DATA bird    TYPE birdtype     .
    
my_method( IMPORTING chicken =  chicken 
                     cow     =  cow     
                     dog     =  dog     
                     bird    =  bird ).
(C) Brandeis Consulting.

Beispiele: In LOOPs

Vorteil im LOOP: Keine 2 Definitionen mehr notwendig.

DATA lt_tasks TYPE STANDARD TABLE OF zbc_tasks.
"DATA ls_tasks LIKE LINE OF lt_tasks.  "Überflüssig

...
LOOP AT tasks INTO DATA(ls_task).

ENDLOOP.

...
READ TABLE lt_tasks INTO DATA(ls_task) WITH KEY task_id = 10.
READ TABLE lt_tasks ASSIGNING FIELD-SYMBOL(<ls_task>) WITH KEY task_id = 10.

(C) Brandeis Consulting.

Und 100 andere Positionen

  • Fehlerhandling: CATCH cx_root INTO DATA(exception)
  • Anweisungen zur Stringverarbeitung:
    • FIND
    • REPLACE
    • CONCATENATE --> INTO Position
    • SPLIT
  • Zeitstempel Verarbeitung:
    • GET TIME STAMP FIELD DATA(mytimestamp).

...
Vollständige Liste in der SAP Dokumentation

(C) Brandeis Consulting.

Risiken und Nebenwirkungen

  • Es darf keine Variable DATA geben, sonst wird DATA(vname) als Zugriff mit Offset bzw. begrenzter Länge verstanden.
  • Es werden immer nur interne Tabellen vom Typ Standard erzeugt. Falls leseoptimiert zugegriffen werden muss, ist eine explizite Deklaration notwendig. Z.B. als HASHED TABLE oder SORTED TABLE mit passender Schlüsseldefinition und ggf. Sekundärindex.
  • Inline Declarations funktionieren nicht in obsoleten Konstrukten.
  • Inline Declarations erschweren die Arbeit des Refactoring Assistenten. Falls die Daten außerhalb des extrahierten Bereichs weiter verwendet werden, sollte die Variable vorab deklariert sein.
(C) Brandeis Consulting.