ABAP neues VALUE Schlüsselwort als Wertoperator

In ABAP 740 gibt es eine weitere Bedeutung des Schlüsselwortes VALUE. Dieses kann jetzt als Wertoperator (Konstruktor) dazu verwendet werden, neue Datenelemente eines bestimmten Types zu erzeugen. Unter anderem können damit interne Tabellen mit Datensätzen initialisiert werden.

Anstatt die Datensätze beim Initialisieren mit mehreren APPEND Anweisungen anzulegen

DATA: ls_itab TYPE ty_mydata.

ls_itab-matnr = '123456'.
APPEND ls_itab TO gt_mydata.
ls_itab-matnr = '789012'.
APPEND ls_itab TO gt_mydata.
ls_itab-matnr = '345678'.
APPEND ls_itab TO gt_mydata.
ls_itab-matnr = '901234'.
APPEND ls_itab TO gt_mydata.

kann man es auch so machen

    gt_mydata = VALUE tyt_mydata( ( matnr = '123456')
                                  ( matnr = '789012')
                                  ( matnr = '345678')
                                  ( matnr = '901234')
                                 ).

Besonderheit

In der Literatur (unter anderem auch in der ABAP Schlüsselworthilfe) wird die Verwendung oft so gezeigt

    DATA(gt_mydata) = VALUE tyt_mydata( ( matnr = '123456')
                                        ( matnr = '789012')
                                        ( matnr = '345678')
                                        ( matnr = '901234')
                                      ).

Hier wird neben dem Schlüsselwort VALUE noch das Schlüsselwort DATA() verwendet. Dies führt dazu, dass eine völlig neue interne Tabelle definiert und mit Daten versorgt wird. Eine bestehende (z.B. global definierte) wird dabei verdeckt. Im Beispiel weiter unten wird der Unterschied dargestellt. Die dort verwendete Klasse hat ein globales Attribut, welches mit Werten versorgt werden soll. Die Methode FILL_ITAB_WRONG füllt diese aber nicht. Statt dessen wird eine neue, gleichnamige Tabelle definiert, die nur innerhalb der Methode und deren Call-Stack bekannt ist. Das globale Attribut wird also verdeckt.

Damit eine interne Tabelle mit Datensätzen initialisiert werden kann, muss ein Schlüssel definiert sein.
Folgende Definition erzeugt den Syntaxfelher "Ein Wert des generischen Typs 'TYT_MYDATA' kann nicht konstruiert werden."

TYPES tyt_mydata TYPE STANDARD TABLE OF ty_mydata.

Während diese Definitionen korrekt sind

TYPES tyt_mydata TYPE STANDARD TABLE OF ty_mydata with key matnr.
TYPES tyt_mydata TYPE STANDARD TABLE OF ty_mydata with DEFAULT KEY. 

Einschränkungen

Das Schlüsselwort kann nur dazu verwendet werden, eine Tabelle zu initialisieren. Es können keine Datensätze an eine bestehende Tabelle angefügt werden. Der Operator erzeugt stets ein neues Objekt des angegebenen Datentyps, belegt die Werte und liefert das fertige Objekt zurück. Durch die Wertzuweisung an die Variable werden die bisherigen Daten überschrieben.

Anwendungsfall

Das Schlüsselwort kann sehr gut dazu verwendet werden, eine interne Tabelle mit bestimmten Werten vorzubelegen. Beispielsweise kann damit eine Liste für ein DropDown Feld mit bestimmten Werken vorbelegt werden. Es lassen sich damit auch sehr gut Testfälle für einen ABAP Unit Test erstellen.

Beispiel

Der Report zeigt die Verwendung des VALUE Schlüsselwortes als Wertoperator.

Schlüsselwort VALUE als Wertoperator
Schlüsselwort VALUE als Wertoperator
*&---------------------------------------------------------------------*
*& Report  Z_TEST_VALUE
*&
*&---------------------------------------------------------------------*
*& Report zeigt die korrekte Verwendung des neuen Schlüsselwortes VALUE
*& (ABAP 740)
*&---------------------------------------------------------------------*
REPORT z_test_value_operator.
CLASS zc_main DEFINITION.
  PUBLIC SECTION.
    TYPES: BEGIN OF ty_mydata,    " Zeilentyp der internen Tabelle
      matnr TYPE matnr,
      END OF ty_mydata.

    TYPES tyt_mydata TYPE STANDARD TABLE OF ty_mydata with DEFAULT KEY.
    DATA: gt_mydata TYPE tyt_mydata.  " Öffentliches Attribut das grfüllt werden soll
    METHODS start.                        " Hauptmethode

  PRIVATE SECTION.
    METHODS fill_itab_wrong.              " Falsche Wertzuweisung
    METHODS fill_itab_correct.            " korrekte Wertzuweisung
    METHODS fill_itab_old.                " Bisherige Wertzuweisung
    METHODS is_itab_initial               " Prüfen ob GT_MYDATA gefüllt ist
     IMPORTING iv_call_after TYPE char30.
    METHODS output_itab                   " Ausgabe der Datensätze
       IMPORTING it_itab TYPE tyt_mydata.
ENDCLASS.
CLASS zc_main IMPLEMENTATION.
*&---------------------------------------------------------------------*
*& Aufrufen der Methoden
*&---------------------------------------------------------------------*
  METHOD start.

    CLEAR gt_mydata.
    me->fill_itab_wrong( ).
    CLEAR gt_mydata.
    me->fill_itab_correct( ).
    CLEAR gt_mydata.
    me->fill_itab_old( ).
  ENDMETHOD.
*&---------------------------------------------------------------------*
*& Prüfen ob PUBLIC Attribut versorgt ist
*&---------------------------------------------------------------------*
  METHOD is_itab_initial.
    IF gt_mydata IS INITIAL.
      WRITE: / 'ITAB is initial after calling ',
               iv_call_after.
    ELSE.
      WRITE: / 'ITAB has records after calling ',
               iv_call_after.
    ENDIF.
  ENDMETHOD.
*&---------------------------------------------------------------------*
*& Ausgabe der Datensätze
*&---------------------------------------------------------------------*
  METHOD output_itab.
    FIELD-SYMBOLS:  TYPE ty_mydata.

    WRITE: / 'Content of GT_MYDATA'.
    LOOP AT it_itab ASSIGNING .
      WRITE: /30 -matnr.
    ENDLOOP.
    WRITE: /.
  ENDMETHOD.
*&---------------------------------------------------------------------*
*& Falsche Zuweisung. Es wird hier eine neue Variable GT_MYDATA vom Typ
*& TYT_MYDATA erstellt. Diese Variable verdeckt das PUBLIC Attribut
*& GT_MYDATA der Klasse
*&---------------------------------------------------------------------*
  METHOD fill_itab_wrong.
    DATA(gt_mydata) = VALUE tyt_mydata( ( matnr = '123456')
                                        ( matnr = '789012')
                                        ( matnr = '345678')
                                        ( matnr = '901234')
                                      ).
    me->is_itab_initial( 'me->fill_itab_wrong' ).
    me->output_itab( gt_mydata ).
  ENDMETHOD.
*&---------------------------------------------------------------------*
*& Korrekte Zuweisung.
*&---------------------------------------------------------------------*
  METHOD fill_itab_correct.
    gt_mydata = VALUE tyt_mydata( ( matnr = '123456')
                                  ( matnr = '789012')
                                  ( matnr = '345678')
                                  ( matnr = '901234')
                                 ).
    me->is_itab_initial( 'me->fill_itab_correct' ).
    me->output_itab( gt_mydata ).

  ENDMETHOD.
*&---------------------------------------------------------------------*
*& Bisherige Anweisungen
*&---------------------------------------------------------------------*
  METHOD fill_itab_old.

    DATA: ls_itab TYPE ty_mydata.

    ls_itab-matnr = '123456'.
    APPEND ls_itab TO gt_mydata.
    ls_itab-matnr = '789012'.
    APPEND ls_itab TO gt_mydata.
    ls_itab-matnr = '345678'.
    APPEND ls_itab TO gt_mydata.
    ls_itab-matnr = '901234'.
    APPEND ls_itab TO gt_mydata.

    me->is_itab_initial( 'me->fill_itab_old' ).
    me->output_itab( gt_mydata ).
  ENDMETHOD.
ENDCLASS.
*&---------------------------------------------------------------------*
*& Programmstart
*&---------------------------------------------------------------------*
START-OF-SELECTION.

  DATA: lcl_main TYPE REF TO zc_main.
  CREATE OBJECT lcl_main.
  lcl_main->start( ).