[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] Hilfsklasse für Enumeratoren auf Basis von statischen Objektreferenzen

* Klassenobjekte sind nur statisch verfügbar (CLASS-DATA)
* von ihr kann nicht abgeleitet werden (FINAL)
* mit NEW können keine Objektreferenzen erzeugt werden (CREATE PRIVATE)
CLASS lcl_enum_colors DEFINITION FINAL CREATE PRIVATE.
  PUBLIC SECTION.
* Konstanten vom Typ des Parameters
    CLASS-DATA: co_red TYPE REF TO lcl_enum_colors READ-ONLY.
    CLASS-DATA: co_green TYPE REF TO lcl_enum_colors READ-ONLY.
    CLASS-DATA: co_blue TYPE REF TO lcl_enum_colors READ-ONLY.

* Klassenkonstruktor
    CLASS-METHODS:
      class_constructor.
ENDCLASS.

CLASS lcl_enum_colors IMPLEMENTATION.
* Vorbelegung der Konstanten
* wird immer beim allerersten Aufruf eines Klassenelementes (Funktion, Variable, Konstante ...) ausgeführt
  METHOD class_constructor.
    co_red   = NEW #( ).
    co_green = NEW #( ).
    co_blue  = NEW #( ).
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
* Variablen vom Typ REF TO lcl_enum_colors
  DATA: lv_color_green TYPE REF TO lcl_enum_colors.
  DATA: lv_color_red TYPE REF TO lcl_enum_colors.
  DATA: lv_color_blue TYPE REF TO lcl_enum_colors.

* Variablen mit konstanten Werten vorbelegen
  lv_color_green = lcl_enum_colors=>co_green.
  lv_color_red = lcl_enum_colors=>co_red.
  lv_color_blue = lcl_enum_colors=>co_blue.

* Werteausgabe
  IF lv_color_green = lcl_enum_colors=>co_green.
    WRITE: / 'Ok.'.
  ELSE.
    WRITE: / 'Not ok.'.
  ENDIF.

  IF lv_color_green = lcl_enum_colors=>co_red.
    WRITE: / 'Ok.'.
  ELSE.
    WRITE: / 'Not ok.'.
  ENDIF.

  IF lcl_enum_colors=>co_red = lcl_enum_colors=>co_blue.
    WRITE: / 'Ok.'.
  ELSE.
    WRITE: / 'Not ok.'.
  ENDIF.

[ABAP] OO: Objektreferenzen in einer Liste verwalten, Objektsuche über Namen

* Demoklasse für Objekte, welche in einer sortierten Liste verwaltet werden
CLASS lcl_demo DEFINITION.
  PUBLIC SECTION.
    METHODS:
      constructor
        IMPORTING
          i_name TYPE string.

    METHODS:
      get_name
        RETURNING VALUE(rv_name) TYPE string.

  PRIVATE SECTION.
    DATA: gv_name TYPE string.
ENDCLASS.

CLASS lcl_demo IMPLEMENTATION.
  METHOD constructor.
    gv_name = i_name.
  ENDMETHOD.

  METHOD get_name.
    rv_name = gv_name.
  ENDMETHOD.
ENDCLASS.

* Listtyp zur Verwaltung der internen Objektreferenzen
* über "name" können die Objektreferenzen gesucht werden
TYPES: BEGIN OF ty_instances,
         name       TYPE        string,
         o_instance TYPE REF TO lcl_demo,
       END OF ty_instances.

* sortierte Liste zur Verwaltung der Objektreferenzen, Primärschlüssel ist "name"
DATA: it_instances TYPE SORTED TABLE OF ty_instances WITH UNIQUE KEY name.

START-OF-SELECTION.
* Objekte generieren und in die iTab einfügen
* iTab wird automatisch anhand der Spalte "name" sortiert
  INSERT VALUE #( name = 'REF2'
                  o_instance = NEW #( 'Udo' ) ) INTO TABLE it_instances.

  INSERT VALUE #( name = 'REF1'
                  o_instance = NEW #( 'Heinz' ) ) INTO TABLE it_instances.

  INSERT VALUE #( name = 'REF4'
                  o_instance = NEW #( 'Horst' ) ) INTO TABLE it_instances.

  INSERT VALUE #( name = 'REF3'
                  o_instance = NEW #( 'Rainer' ) ) INTO TABLE it_instances.

* Objekt anhand eines Namens suchen
  DATA(o_ref) = it_instances[ name = 'REF1' ]-o_instance.
  WRITE: / o_ref->get_name( ).

* sortierte Objektliste ausgeben
  LOOP AT it_instances ASSIGNING FIELD-SYMBOL(<fs_inst>).
    WRITE: / <fs_inst>-name, <fs_inst>-o_instance->get_name( ).
  ENDLOOP.

[ABAP] Objekt-Referenzen in interner Tabelle (Liste) speichern

TYPES: BEGIN OF ty_user,
         bname      TYPE usr21-bname,
         persnumber TYPE adr6-persnumber,
         addrnumber TYPE adr6-addrnumber,
         smtp_addr  TYPE adr6-smtp_addr,
       END OF ty_user.

CLASS cl_person DEFINITION.
  PUBLIC SECTION.
    METHODS: constructor
      IMPORTING
        i_userdata TYPE ty_user.
    METHODS: print_mail.
  private SECTION.
    DATA: userdata TYPE ty_user.
ENDCLASS.

CLASS cl_person IMPLEMENTATION.
  METHOD constructor.
    userdata = i_userdata.
  ENDMETHOD.

  METHOD print_mail.
    WRITE: / userdata-bname, userdata-smtp_addr.
  ENDMETHOD.
ENDCLASS.

DATA: it_userdata TYPE TABLE OF ty_user.

* interne Tabelle zur Speicherung der Objektreferenzen
DATA: it_persons TYPE TABLE OF REF TO cl_person.
* Objektreferenz
DATA: o_person TYPE REF TO cl_person.

START-OF-SELECTION.
* Daten holen
  SELECT u~bname, u~persnumber, u~addrnumber, a~smtp_addr
    INTO CORRESPONDING FIELDS OF TABLE @it_userdata
    FROM usr21 AS u
    INNER JOIN adr6 AS a ON a~persnumber = u~persnumber AND a~addrnumber = u~addrnumber
    UP TO 10 ROWS.

* Objekte erzeugen und an Referenztabelle anhängen
  LOOP AT it_userdata INTO DATA(wa_user).
    o_person = new cl_person( wa_user ).
    APPEND o_person TO it_persons.
  ENDLOOP.

* Referenztabelle durchloopen und Objekte aufrufen
  LOOP AT it_persons INTO o_person.
    o_person->print_mail( ).
  ENDLOOP.