[ABAP] Element des Selektionsbildes lesen und Wert für dynamische F4-Suchhilfe benutzen

PARAMETERS: p_table LIKE dd02l-tabname DEFAULT 'T100'.
PARAMETERS: p_field TYPE slis_fieldname.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_field.

  DATA: it_fieldvalues TYPE STANDARD TABLE OF rsselread WITH DEFAULT KEY.
  APPEND VALUE #( name = 'P_TABLE' " Dynprofeld P_TABLE
                  kind = 'P'       " P - PARAMETER, S - SELECT-OPTION
                ) TO it_fieldvalues.

* Element des Selektionsbildes lesen
  CALL FUNCTION 'RS_SELECTIONSCREEN_READ'
    EXPORTING
      program     = sy-repid
      dynnr       = sy-dynnr
    TABLES
      fieldvalues = it_fieldvalues.

  DATA(lv_tabname) = it_fieldvalues[ 1 ]-fieldvalue.

  IF NOT lv_tabname IS INITIAL.
    TRANSLATE lv_tabname TO UPPER CASE.

    SELECT fieldname
      FROM dd03l
      INTO TABLE @DATA(it_cols)
      WHERE tabname = @lv_tabname.

    IF sy-subrc = 0.
      DATA: it_return TYPE STANDARD TABLE OF ddshretval WITH DEFAULT KEY.

* F4-Hilfe mit Übergabe der anzuzeigenden Werte in interner Tabelle
      CALL FUNCTION 'F4IF_INT_TABLE_VALUE_REQUEST'
        EXPORTING
          retfield        = 'FIELDNAME' " Rückgabewert aus dem Feld FIELDNAME
          dynpprog        = sy-repid
          dynpnr          = sy-dynnr
          dynprofield     = 'P_FIELD'   " Name des Dynpro-Feldes für die automatische Werterückgabe
          value_org       = 'S'         " Werteübergabe: C: zellenweise, S: strukturiert
          window_title    = 'Auswahl'
        TABLES
          value_tab       = it_cols     " Übergabe-Tabelle mit Werten für die Anzeige und Auswahl
          return_tab      = it_return   " Rückgabe-Tabelle mit den ausgewählten (geklickten) Elementen
        EXCEPTIONS
          parameter_error = 1
          no_values_found = 2
          OTHERS          = 3.

      IF sy-subrc = 0.
        IF lines( it_return ) > 0.
          MESSAGE it_return[ 1 ]-fieldval TYPE 'S'.
        ENDIF.
      ENDIF.
    ENDIF.
  ENDIF.

[ABAP] Docking Container (cl_gui_docking_container) maximiert darstellen

DATA: o_dock TYPE REF TO cl_gui_docking_container.
DATA: o_salv_ida TYPE REF TO if_salv_gui_table_ida.

PARAMETERS: p_name TYPE string. " Dummy-Parameter zum erzwingen des Selektionsbildes

AT SELECTION-SCREEN OUTPUT.

  IF NOT o_dock IS BOUND.
* maximierten Dockingcontainer auf dem Selektionsbild erzeugen
    o_dock = NEW #( repid     = sy-repid
                    dynnr     = sy-dynnr
                    side      = cl_gui_docking_container=>dock_at_bottom
                    extension = cl_gui_docking_container=>ws_maximizebox
*                    ratio     = 50
                  ).

* Testweise ein SALV TABLE IDA im Container einbetten
    o_salv_ida = cl_salv_gui_table_ida=>create( iv_table_name    = 'T100'
                                                io_gui_container = o_dock ).

  ENDIF.

[ABAP] Eigener Startbutton (PUSHBUTTON) für START-OF-SELECTION auf dem Selektionsbild

* http://havliczech.blogspot.com/2017/04/how-to-trigger-start-of-selection-event.html
PARAMETERS: p_string TYPE string DEFAULT 'abc' LOWER CASE.

SELECTION-SCREEN SKIP.

* PUSHBUTTON triggert Test-Kommando 'SHOW'
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN PUSHBUTTON 2(30) btn1 USER-COMMAND show.
SELECTION-SCREEN END OF LINE.

* PUSHBUTTON triggert Kommando 'ONLI' (Ausführen) auf dem Selektionsbild
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN PUSHBUTTON 2(30) bstart USER-COMMAND onli.
SELECTION-SCREEN END OF LINE.

INITIALIZATION.
  btn1 = 'Show'.
  bstart = 'Start'.

AT SELECTION-SCREEN.
* User-Command prüfen
  CASE sy-ucomm.
    WHEN 'ONLI'.
      MESSAGE 'Springe jetzt zu START-OF-SELECTION.' TYPE 'S'.
    WHEN 'SHOW'.
      MESSAGE p_string TYPE 'I'.
  ENDCASE.

START-OF-SELECTION.
* Wenn User-Command 'ONLI' (Ausführen) getriggert wurde
  WRITE: 'Fertig.'.

[ABAP] Button Ausführen (F8) entfernen und eigenen Startbutton auf dem Selektionbild anzeigen

* http://zevolving.com/2014/07/selection-screen-disable-standard-toolbar-button/
* https://www.saptutorial.org/hide-execute-button-selection-screen/
PARAMETERS: p_string TYPE string DEFAULT 'Test'.

* Eigener Startbutton: Triggert das Kommando 'ONLI' (Ausführen (F8)) -> START-OF-SELECTION
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN PUSHBUTTON 2(30) b_start USER-COMMAND onli.
SELECTION-SCREEN END OF LINE.

INITIALIZATION.
  b_start   = 'Start'.

AT SELECTION-SCREEN OUTPUT.
  DATA: it_ucomm TYPE STANDARD TABLE OF sy-ucomm WITH DEFAULT KEY.
* Standard-Button Ausführen (F8) in der Toolbar entfernen
  APPEND 'ONLI' TO it_ucomm.

  CALL FUNCTION 'RS_SET_SELSCREEN_STATUS'
    EXPORTING
      p_status  = sy-pfkey
    TABLES
      p_exclude = it_ucomm.

START-OF-SELECTION.
  WRITE: / p_string.

[ABAP] Interne Tabellen: OPTIONAL – Leere Datensätze bei Table Expressions

TYPES: BEGIN OF ty_person,
         name TYPE string,
         age  TYPE i,
       END OF ty_person.

TYPES: ty_it_persons TYPE STANDARD TABLE OF ty_person WITH DEFAULT KEY.

DATA(it_persons) = VALUE ty_it_persons(
                                        ( name = 'Hugo' age = 40 )
                                        ( name = 'Ede' age = 65 )
                                        ( name = 'Ina' age = 35 )
                                      ).

* Datensatz für Person 'Heiner' ist nicht vorhanden -> leeren Datensatz zurückgeben
DATA(lv_p) = VALUE #( it_persons[ name = 'Heiner' ] OPTIONAL ).

WRITE: / lv_p-name.
WRITE: / lv_p-age.

* Datensatz mit Index 4 ist nicht vorhanden -> leeren Wert zurückgeben
DATA(lv_age) = VALUE #( it_persons[ 4 ]-age OPTIONAL ).

WRITE: / lv_age.

[ABAP] Covers Pattern: Testen, ob ein String eine bestimmte Pattern enthält (Vergleichsoperator CP für zeichenartige Datentypen)

Variante 1 (Testen, ob ein String (Dateiname) auf einen bestimmten String (Dateiendung) endet (endswith))

* Dateiname
DATA(lv_filename) = |c:\\test\\file.txt|.
* Dateiendung
DATA(lv_fileext) = |txt|.

* prüft, ob lv_filename auf .lv_fileext endet
* '*' ist dabei der Platzhalter für eine bel. Anzahl Zeichen incl. Leerzeichen
IF NOT ( lv_filename CP |*.{ lv_fileext }| ).
  WRITE: / |'{ lv_filename }' endet nicht auf '{ lv_fileext }'|.
ELSE.
  WRITE: / |'{ lv_filename }' endet auf '{ lv_fileext }'|.
ENDIF.

Variante 2: (Prüft, Pattern in einem String vorkommt)

* String mit <text>-Tags
PARAMETERS: p_str type string DEFAULT '<text>ABC</text>'.
* Pattern, die auf Öffnen/Schließen-Tags prüft
DATA(lv_pattern) = |<*>*</*>|.

* prüft, Pattern in einem String vorkommt
* '*' ist dabei der Platzhalter für eine bel. Anzahl Zeichen incl. Leerzeichen
IF NOT ( p_str CP lv_pattern ).
  WRITE: / |String beinhaltet nicht die Pattern ({ lv_pattern }).|.
ELSE.
  WRITE: / |String beinhaltet die Pattern ({ lv_pattern }).|.
ENDIF.

[Paint.NET] Portable Modus aktivieren

Ab Version 4.0.17 kann man aus jeder installierten Version von Pain.NET eine Portable Version erstellen.

  • Paint.NET installieren
  • Im Installationsordner die Datei PaintDotNet.exe.config editieren und im Abschnitt appSettings den Eintrag add key="PaintDotNet.EnablePortableMode" value="true" hinzufügen:
    <?xml version="1.0"?>
    <configuration>
      <runtime>
        <gcAllowVeryLargeObjects enabled="true"/>
        <generatePublisherEvidence enabled="false"/>
        <legacyCorruptedStateExceptionsPolicy enabled="true"/>
        <loadFromRemoteSources enabled="true"/>
      </runtime>
      <startup useLegacyV2RuntimeActivationPolicy="true">
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7"/>
      </startup>
      <appSettings>
        <add key="EnableWindowsFormsHighDpiAutoResizing" value="true"/>
        <add key="PaintDotNet.EnablePortableMode" value="true" />
      </appSettings>
    </configuration>
    
  • Datei PaintDotNet.exe.config speichern
  • Der Installationsordner kann nun auf ein beliebiges USB-LAufwerk kopiert und PaintDotNet.exe von dort gestartet werden

[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] GUI-Controls stapeln

* Quelle: https://www.tricktresor.de/blog/controls-stapeln/

DATA: it_mara TYPE STANDARD TABLE OF mara WITH DEFAULT KEY.
DATA: o_dock TYPE REF TO cl_gui_docking_container.
DATA: o_txt TYPE REF TO cl_gui_textedit.
DATA: o_alv TYPE REF TO cl_gui_alv_grid.

PARAMETERS: rb_txt RADIOBUTTON GROUP rbg DEFAULT 'X' USER-COMMAND rbc.
PARAMETERS: rb_alv RADIOBUTTON GROUP rbg.

INITIALIZATION.
  IF NOT o_dock IS BOUND.
* Containerobjekt erzeugen
    o_dock = NEW #( side  = cl_gui_docking_container=>dock_at_bottom
                    ratio = 90 ).

* Texteditor erzeugen
    o_txt = NEW #( parent = o_dock ).

* Daten für ALV holen
    SELECT *
      INTO TABLE @it_mara
      FROM mara
      UP TO 100 ROWS.

* ALV-Gitter erzeugen
    o_alv = NEW #( i_parent = o_dock ).
    o_alv->set_table_for_first_display( EXPORTING
                                          i_structure_name = 'MARA'
                                        CHANGING
                                          it_outtab = it_mara ).
  ENDIF.

AT SELECTION-SCREEN.
* wenn Radiobuttons geklickt
  IF sy-ucomm = 'RBC'.
* je nach Radiobutton die GUI-Controls ein-/ausblenden
    CASE abap_true.
      WHEN rb_txt.
        o_txt->set_visible( abap_true ).
        o_alv->set_visible( abap_false ).
      WHEN rb_alv.
        o_txt->set_visible( abap_false ).
        o_alv->set_visible( abap_true ).
    ENDCASE.
  ENDIF.

[ABAP] Globale Objekte eines Programms ermitteln und Infos anzeigen

Variante 1 (lokale Infoklasse)

* Quellen: https://blogs.sap.com/2018/08/27/sapgui-is-dying-but-still-secrets-to-reveal.../
*          https://github.com/tricktresor/container_hierarchy

CLASS lcl_global_symbols DEFINITION.
  PUBLIC SECTION.
    TYPES: BEGIN OF ty_obj_info,
             name          TYPE rfieldlist-name,
             type          TYPE rfieldlist-type,
             reftypeloc    TYPE rfieldlist-reftypeloc,
             global_name   TYPE string,
             relative_name TYPE string,
             object_name   TYPE string,
             object_id     TYPE i,
             reference     TYPE REF TO object,
             error         TYPE string,
           END OF ty_obj_info.

    TYPES: ty_it_obj_info TYPE STANDARD TABLE OF ty_obj_info WITH DEFAULT KEY.

    CONSTANTS: null TYPE REF TO object VALUE IS INITIAL.

    CLASS-METHODS:
      get_obj_info
        IMPORTING
                  iv_name               TYPE rfieldlist-name
                  iv_type               TYPE rfieldlist-type DEFAULT 'r'
                  iv_reftypeloc         TYPE rfieldlist-reftypeloc DEFAULT 'CLAS'
        RETURNING VALUE(rv_it_obj_info) TYPE ty_it_obj_info.
ENDCLASS.

CLASS lcl_global_symbols IMPLEMENTATION.
  METHOD get_obj_info.
    DATA: it_fieldlist TYPE STANDARD TABLE OF rfieldlist WITH DEFAULT KEY.
* Liste der globalen Daten eines Programms
    CALL FUNCTION 'GET_GLOBAL_SYMBOLS'
      EXPORTING
        program      = sy-repid
        name_pattern = '*'
      TABLES
        fieldlist    = it_fieldlist.

    DATA(lv_where) = ||.

    IF NOT iv_name IS INITIAL.
      lv_where = |name CP iv_name AND type = iv_type AND reftypeloc = iv_reftypeloc|.
    ENDIF.

    LOOP AT it_fieldlist ASSIGNING FIELD-SYMBOL(<f>) WHERE (lv_where).

      DATA(lv_global_name) = |({ sy-repid }){ <f>-name }|.
      DATA(lv_relative_name) = ||.
      DATA(lv_object_name) = ||.
      DATA(lv_error) = ||.
      DATA: lv_oid TYPE i.

* Wenn Referenztyp
      IF <f>-type = 'r'.
* Dirty Assign: Namen an Feldsymbol vom TYPE ANY binden
        ASSIGN (lv_global_name) TO FIELD-SYMBOL(<o>).

        IF NOT <o> IS INITIAL.
          IF <o> IS ASSIGNED.
            TRY.
* <o> ist eine Referenz
                IF <o> IS BOUND.
* Descriptor für Objektreferenz
                  DATA(o_desc) = cl_abap_typedescr=>describe_by_object_ref( <o> ).

                  lv_relative_name = o_desc->get_relative_name( ).

* ObjektID zur Referenz ermitteln
                  CALL 'OBJMGR_GET_INFO' ID 'OPNAME' FIELD 'GET_OBJID'
                                         ID 'OBJID'  FIELD lv_oid      " Rückgabe: ObjectID
                                         ID 'OBJ'    FIELD <o>.

                  lv_object_name = |\{O:{ lv_oid }*{ o_desc->absolute_name }|.
                ENDIF.
              CATCH cx_root INTO DATA(e_txt).
                lv_error = e_txt->get_text( ).
            ENDTRY.
          ENDIF.
        ENDIF.
      ENDIF.

      APPEND VALUE #(
                      name          = <f>-name
                      type          = <f>-type
                      reftypeloc    = <f>-reftypeloc
                      global_name   = lv_global_name
                      relative_name = lv_relative_name
                      object_name   = lv_object_name
                      object_id     = lv_oid
                      reference     = COND #( WHEN ( <o> IS ASSIGNED AND NOT <o> IS INITIAL ) THEN <o> ELSE null )
                      error         = lv_error
                    ) TO rv_it_obj_info.
    ENDLOOP.
  ENDMETHOD.
ENDCLASS.

DATA: o_dock TYPE REF TO cl_gui_docking_container.
DATA: o_text TYPE REF TO cl_gui_textedit.

PARAMETERS: p_matnr TYPE mara-matnr.

INITIALIZATION.

  IF NOT o_dock IS BOUND.
* GUI-Objekte für Test erzeugen
    o_dock = NEW #( side  = cl_gui_docking_container=>dock_at_bottom
                    ratio = 90 ).

    o_text = NEW #( parent = o_dock ).
  ENDIF.

START-OF-SELECTION.

* Infos zu 'o_dock' holen
  DATA(it_one) = lcl_global_symbols=>get_obj_info( iv_name = 'o_dock' ).

  LOOP AT it_one ASSIGNING FIELD-SYMBOL(<one>).

    DATA(lv_ref_one) = ||.

    IF <one>-reference IS BOUND.
      lv_ref_one = <one>-object_name.
    ENDIF.

    WRITE: / <one>-name, <one>-type, <one>-reftypeloc, <one>-global_name, <one>-relative_name, <one>-object_name, <one>-object_id, lv_ref_one, <one>-error.
  ENDLOOP.

  ULINE.

* Infos zu allen Objekten holen
  DATA(it_all) = lcl_global_symbols=>get_obj_info( iv_name = '' ).

  LOOP AT it_all ASSIGNING FIELD-SYMBOL(<o>).

    DATA(lv_ref) = ||.

    IF <o>-reference IS BOUND.
      lv_ref = <o>-object_name.
    ENDIF.

    WRITE: / <o>-name, <o>-type, <o>-reftypeloc, <o>-global_name, <o>-relative_name, <o>-object_name, <o>-object_id, lv_ref, <o>-error.
  ENDLOOP.

Variante 2 (Container)

DATA: o_dock TYPE REF TO cl_gui_docking_container.
DATA: o_text TYPE REF TO cl_gui_textedit.

DATA: it_fieldlist TYPE STANDARD TABLE OF rfieldlist WITH DEFAULT KEY.

PARAMETERS: p_matnr TYPE mara-matnr.

INITIALIZATION.

  IF NOT o_dock IS BOUND.
* GUI-Objekte für Test erzeugen
    o_dock = NEW #( side  = cl_gui_docking_container=>dock_at_bottom
                    ratio = 90 ).

    o_text = NEW #( parent = o_dock ).
  ENDIF.

AT SELECTION-SCREEN.
* Liste der globalen Daten eines Programms
  CALL FUNCTION 'GET_GLOBAL_SYMBOLS'
    EXPORTING
      program      = sy-repid
      name_pattern = '*'
    TABLES
      fieldlist    = it_fieldlist.

START-OF-SELECTION.
* globalen Daten nach Referenztypen durchloopen
  LOOP AT it_fieldlist ASSIGNING FIELD-SYMBOL(<f>) WHERE type = 'r' AND reftypeloc = 'CLAS' AND name(1) <> '%'.

    WRITE: / '         name:', <f>-name.

* Globalen Namen des Objekts ermitteln
    DATA(lv_global_name) = |({ sy-repid }){ <f>-name }|.
    WRITE: / '  global name:', lv_global_name.

* Dirty Assign: Namen an Feldsymbol vom TYPE ANY binden
    ASSIGN (lv_global_name) TO FIELD-SYMBOL(<o>).
    IF <o> IS ASSIGNED.
      TRY.
* <o> ist eine Referenz
          IF <o> IS BOUND.
* Descriptor für Objektreferenz
            DATA(o_desc) = cl_abap_typedescr=>describe_by_object_ref( <o> ).

            WRITE: / 'relative name:', o_desc->get_relative_name( ).

            DATA: lv_oid TYPE i.

* ObjektID zur Referenz ermitteln
            CALL 'OBJMGR_GET_INFO' ID 'OPNAME' FIELD 'GET_OBJID'
                                   ID 'OBJID'  FIELD lv_oid      " Rückgabe: ObjectID
                                   ID 'OBJ'    FIELD <o>.

            WRITE: / '  object name:', |\{O:{ lv_oid }*{ o_desc->absolute_name }|.

* Gegenprobe
            DATA: o_ref_weak TYPE REF TO object.

* Referenz zur ObjektID ermitteln
            CALL 'OBJMGR_GET_INFO' ID 'OPNAME' FIELD 'WEAK_REF_GET'
                                   ID 'OID'    FIELD lv_oid
                                   ID 'OBJ'    FIELD o_ref_weak. " Rückgabe: Objekt-Referenz

            IF o_ref_weak IS BOUND.
* Descriptor für Objektreferenz
              DATA(o_desc_weak) = cl_abap_typedescr=>describe_by_object_ref( o_ref_weak ).
              WRITE: / 'relative name weak:', o_desc_weak->get_relative_name( ).
              WRITE: / '  object name weak:', |\{O:{ lv_oid }*{ o_desc_weak->absolute_name }|.
            ENDIF.

* Falls cl_gui_container: Children anzeigen
            TRY.
                DATA(o_cont) = CAST cl_gui_container( <o> ).

                LOOP AT o_cont->children ASSIGNING FIELD-SYMBOL(<child>).
                  DATA(o_desc_child) = cl_abap_typedescr=>describe_by_object_ref( <child> ).
                  WRITE: / ' --> child relative name:', o_desc_child->get_relative_name( ).
                ENDLOOP.
              CATCH cx_root.
            ENDTRY.
          ELSE.
            WRITE: 'keine Referenz verfügbar.'.
          ENDIF.

        CATCH cx_root INTO DATA(e_txt).
          WRITE: / e_txt->get_text( ).
      ENDTRY.
    ELSE.
      WRITE: 'Feldsymbol nicht zugewiesen:', lv_global_name.
    ENDIF.

    ULINE.
  ENDLOOP.