[ABAP] Daten in einem Baum/Tree in der Listanzeige darstellen und Button- und Maus-Events abfangen

* obsolete Darstellung über die FuBas RS_TREE_CONSTRUCT und RS_TREE_LIST_DISPLAY
* besser ist die Nutzung der Klassen cl_salv_tree, cl_gui_simple_tree, cl_gui_column_tree, cl_gui_list_tree
SELECT kunnr,
       land1,
       name1,
       ort01
  INTO TABLE @DATA(it_kna1)
  FROM kna1
  UP TO 25 ROWS.

SELECT vbeln,
       erdat,
       erzet,
       netwr,
       waerk,
       kunnr
  INTO TABLE @DATA(it_vbak)
  FROM vbak
  FOR ALL ENTRIES IN @it_kna1
  WHERE kunnr = @it_kna1-kunnr.

SELECT vbeln,
       posnr,
       matnr,
       netwr,
       waerk
  INTO TABLE @DATA(it_vbap)
  FROM vbap
  FOR ALL ENTRIES IN @it_vbak
  WHERE vbeln = @it_vbak-vbeln.

* Rootnode (Node-Level 1)
DATA(it_nodes) = VALUE snodetab( ( tlevel  = 1
                                   name    = 'Kundenstamm'
                                   nlength = 27
                                   color   = col_key
                                   text    = 'Verkaufs-Report'
                                   tlength = 50
                                 )
                               ).

LOOP AT it_kna1 ASSIGNING FIELD-SYMBOL(<k>).
* Node-Level 2
  DATA(lv_node_2) = VALUE snodetext( tlevel   = 2
                                     name     = <k>-kunnr
                                     nlength  = 19
                                     color    = col_key
                                     text     = <k>-land1
                                     tlength  = 5
                                     tcolor   = col_normal
                                     text1    = <k>-name1
                                     tlength1 = 40
                                     tcolor1  = col_normal
                                     text2    = <k>-ort01
                                     tlength2 = 25
                                     tcolor2  = col_normal
                                   ).

  APPEND lv_node_2 TO it_nodes.

  LOOP AT it_vbak ASSIGNING FIELD-SYMBOL(<v>) WHERE kunnr = <k>-kunnr.
* Node-Level 3
    DATA(lv_node_3) = VALUE snodetext( tlevel   = 3
                                       name     = <v>-vbeln
                                       nlength  = 15
                                       color    = col_positive
                                       text     = <v>-erdat
                                       tlength  = 12
                                       tcolor   = col_normal
                                       text1    = <v>-erzet
                                       tlength1 = 10
                                       tcolor1  = col_normal
                                       text2    = <v>-netwr
                                       tlength2 = 15
                                       tcolor2  = col_total
                                       text3    = <v>-waerk
                                       tlength3 = 5
                                       tcolor3  = col_total
                                     ).

    APPEND lv_node_3 TO it_nodes.

    LOOP AT it_vbap ASSIGNING FIELD-SYMBOL(<p>) WHERE vbeln = <v>-vbeln.
* Node-Level 4
      DATA(lv_node_4) = VALUE snodetext( tlevel   = 4
                                         name     = <p>-posnr
                                         nlength  = 11
                                         color    = col_group
                                         text     = <p>-matnr
                                         tlength  = 23
                                         tcolor   = col_normal
                                         text1    = <p>-netwr
                                         tlength1 = 15
                                         tcolor1  = col_total
                                         text2    = <p>-waerk
                                         tlength2 = 5
                                         tcolor2  = col_total
                                       ).

      APPEND lv_node_4 TO it_nodes.

    ENDLOOP.

  ENDLOOP.

ENDLOOP.

* Tree-Objekte in Funktionsgruppe SEUT
* Neue Hierarchie aufbauen bzw. Teilbaum einfügen
CALL FUNCTION 'RS_TREE_CONSTRUCT'
  TABLES
    nodetab            = it_nodes
  EXCEPTIONS
    tree_failure       = 1
    id_not_found       = 2
    wrong_relationship = 3
    OTHERS             = 4.

IF sy-subrc = 0.
* Konstanten sind in Typgruppe STREE definiert
* Hierarchie anzeigen
  CALL FUNCTION 'RS_TREE_LIST_DISPLAY'
    EXPORTING
      callback_program      = sy-repid
      callback_user_command = 'ON_USER_COMMAND' " Formroutine für Callback-Funktion für Buttons und Mausklicks
      status                = 'STANDARD'        " GUI-Status des Trees (wird für Callback benötigt, kann sonst weggelassen werden
      use_control           = stree_use_list.   " stree_use_list (Liste), stree_use_list_print (Druckausgabe), stree_use_control (Fullscreen-Control), stree_use_in_dynpro (Dynpro)
ELSE.
  WRITE: / 'Fehler:', sy-subrc.
ENDIF.

* Form ON_USER_COMMAND
* Callback-Funktion für Buttons und Mausklicks
FORM on_user_command TABLES   node STRUCTURE seucomm
                     USING    command
                     CHANGING exit
                              list_refresh.

* Messagetext ausgeben, um geklicktes Element zu identifizieren
  MESSAGE |{ node-name }, { command }| TYPE 'S'.
ENDFORM.

[ABAP] Popup-Dialog zur Anzeige von BAPI-Meldungen

DATA(it_bapi_ret) = VALUE bapiret2_t( ( type       = 'S'
                                        id         = '01'
                                        number     = '319'
                                        message_v1 = 'Test'
                                      )
                                      ( type       = 'S'
                                        id         = '01'
                                        number     = '319'
                                        message_v1 = 'Test2'
                                      )
                                    ).

Variante 1 (cl_rmsl_message)

cl_rmsl_message=>display( it_bapi_ret ).

Variante 2 (cl_tex_message_handler)

cl_tex_message_handler=>display_bapiret2( it_bapi_ret ).

Variante 3 (C14ALD_BAPIRET2_SHOW)

* EHS: Anzeige einer BAPI-Fehlermeldungstabelle (BAPIRET2)
CALL FUNCTION 'C14ALD_BAPIRET2_SHOW'
  TABLES
    i_bapiret2_tab = it_bapi_ret.

Variante 4 (BSSP2_MESSAGE_POPUP)

DATA: lv_ef_continue TYPE boolean.

DATA(it_message) = VALUE bssp_t_message( ( msgid = 'SY' msgty = 'E' msgno = 100 msgv1 = 'Text1' msgv2 = '' msgv3 = '' msgv4 = '' row = 0 fieldname = '' )
                                         ( msgid = 'SY' msgty = 'W' msgno = 101 msgv1 = 'Text2' msgv2 = '' msgv3 = '' msgv4 = '' row = 0 fieldname = '' )
                                         ( msgid = 'SY' msgty = 'i' msgno = 102 msgv1 = 'Text3' msgv2 = '' msgv3 = '' msgv4 = '' row = 0 fieldname = '' ) ).

CALL FUNCTION 'BSSP2_MESSAGE_POPUP'
  EXPORTING
    it_message        = it_message
    if_save_necessary = abap_true
  IMPORTING
    ef_continue       = lv_ef_continue.

IF lv_ef_continue = abap_true.
* Sichern
ELSE.
* Abbrechen
ENDIF.

Variante 5 (C14Z_MESSAGES_SHOW_AS_POPUP)

DATA(it_messages) = VALUE esp1_message_tab_type( ( msgid = 'SY' msgno = '002' msgty = 'I' msgv1 = |Text1| lineno = 1 )
                                                 ( msgid = 'SY' msgno = '002' msgty = 'I' msgv1 = |Text2| lineno = 2 )
                                               ).

* EHS: eine oder mehrere Nachrichten in einem Popup anzeigen
CALL FUNCTION 'C14Z_MESSAGES_SHOW_AS_POPUP'
  TABLES
    i_message_tab = it_messages.

Variante 6 (cf_reca_message_list / RECA_GUI_MSGLIST_POPUP)

* Message-Collector Objekt
DATA(o_msg_list) = cf_reca_message_list=>create( ).

TRY.
* Division durch Null provozieren
    DATA(lv_div) = 1 / 0.
  CATCH cx_root INTO DATA(e_txt).
* Exception an den Collector übergeben
    o_msg_list->add_from_exception( e_txt ).
ENDTRY.

* Protokoll als Applikation bzw. Popup anzeigen
CALL FUNCTION 'RECA_GUI_MSGLIST_POPUP'
  EXPORTING
    io_msglist = o_msg_list.

Links

[ABAP] Zwei SALV-Grids in einem Splittercontainer anzeigen

* Daten für SALV-Grid oben
SELECT *
  INTO TABLE @DATA(it_scarr)
  FROM scarr.

* Daten für SALV-Grid unten
SELECT *
  INTO TABLE @DATA(it_sflight)
  FROM sflight.

* Referenzen auf GUI-Objekte
* Splitter
DATA: o_splitter_main TYPE REF TO cl_gui_splitter_container.
* Splitter-Container oben
DATA: o_container_o   TYPE REF TO cl_gui_container.
* Splitter-Container unten
DATA: o_container_u   TYPE REF TO cl_gui_container.

* Splitter auf default_screen erzeugen
o_splitter_main = NEW #( parent                  = cl_gui_container=>default_screen
                         no_autodef_progid_dynnr = abap_true       " wichtig
                         rows                    = 2
                         columns                 = 1 ).

* Höhe oberer Splitter in %
o_splitter_main->set_row_height( id = 1 height = 40 ).

* REF auf oberen und unteren Splitcontainer holen
o_container_o = o_splitter_main->get_container( row = 1 column = 1 ).
o_container_u = o_splitter_main->get_container( row = 2 column = 1 ).

* SALV-Table oben mit Fluggesellschaften
DATA: o_salv_o TYPE REF TO cl_salv_table.

cl_salv_table=>factory( EXPORTING
                          r_container  = o_container_o
                        IMPORTING
                          r_salv_table = o_salv_o
                        CHANGING
                          t_table      = it_scarr ).

* Grundeinstellungen
o_salv_o->get_functions( )->set_all( abap_true ).
o_salv_o->get_columns( )->set_optimize( abap_true ).
o_salv_o->get_display_settings( )->set_list_header( 'Fluggesellschaften' ).
o_salv_o->get_display_settings( )->set_striped_pattern( abap_true ).
o_salv_o->get_selections( )->set_selection_mode( if_salv_c_selection_mode=>row_column ).

* Spaltenüberschriften: technischer Name und Beschreibungstexte
LOOP AT o_salv_o->get_columns( )->get( ) ASSIGNING FIELD-SYMBOL(<so>).
  DATA(o_col_o) = <so>-r_column.
  o_col_o->set_short_text( || ).
  o_col_o->set_medium_text( || ).
  o_col_o->set_long_text( |{ o_col_o->get_columnname( ) }| ).
ENDLOOP.

* SALV-Grid anzeigen
o_salv_o->display( ).

* SALV-Table unten mit Flügen
DATA: o_salv_u TYPE REF TO cl_salv_table.

cl_salv_table=>factory( EXPORTING
                          r_container  = o_container_u
                        IMPORTING
                          r_salv_table = o_salv_u
                        CHANGING
                          t_table      = it_sflight ).

* Grundeinstellungen
o_salv_u->get_functions( )->set_all( abap_true ).
o_salv_u->get_columns( )->set_optimize( abap_true ).
o_salv_u->get_display_settings( )->set_list_header( 'Flüge' ).
o_salv_u->get_display_settings( )->set_striped_pattern( abap_true ).
o_salv_u->get_selections( )->set_selection_mode( if_salv_c_selection_mode=>row_column ).

* Spaltenüberschriften: technischer Name und Beschreibungstexte
LOOP AT o_salv_u->get_columns( )->get( ) ASSIGNING FIELD-SYMBOL(<su>).
  DATA(o_col_u) = <su>-r_column.
  o_col_u->set_short_text( || ).
  o_col_u->set_medium_text( || ).
  o_col_u->set_long_text( |{ o_col_u->get_columnname( ) }| ).
ENDLOOP.

* SALV-Grid anzeigen
o_salv_u->display( ).

* leere Toolbar ausblenden
cl_abap_list_layout=>suppress_toolbar( ).

* Erzwingen von cl_gui_container=>default_screen
WRITE: space.

[ABAP] Popupfenster mit Eingabefeldern (cl_gui_combobox, cl_gui_input_field)

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      on_close FOR EVENT close OF cl_gui_dialogbox_container
        IMPORTING sender.

    CLASS-METHODS:
      on_select FOR EVENT selected OF cl_gui_combobox
        IMPORTING
            key
            sender.

    CLASS-METHODS:
      on_submit FOR EVENT submit OF cl_gui_input_field
        IMPORTING
            input
            sender.

    CLASS-METHODS:
      on_auto_submit FOR EVENT auto_submit OF cl_gui_input_field
        IMPORTING
            input
            sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
  METHOD on_close.
    IF sender IS NOT INITIAL.
      sender->free( ).
    ENDIF.
  ENDMETHOD.

  METHOD on_select.

    MESSAGE key && ' -> ' && sender->get_selected_item( ) TYPE 'S'.

    cl_gui_cfw=>flush( ).
  ENDMETHOD.

  METHOD on_submit.

    MESSAGE 'Submit:' && input && ' -> ' && sender->get_text( ) TYPE 'S'.

    cl_gui_cfw=>flush( ).
  ENDMETHOD.

  METHOD on_auto_submit.

    MESSAGE 'Auto-Submit:' &&  input && ' -> ' && sender->get_text( ) TYPE 'S'.

    cl_gui_cfw=>flush( ).
  ENDMETHOD.
ENDCLASS.

SELECTION-SCREEN: PUSHBUTTON 2(20) btn1 USER-COMMAND cmd_show.

AT SELECTION-SCREEN.
* wenn Button-Kommando 'CMD_SHOW'
  IF sy-ucomm = 'CMD_SHOW'.
* Container
    DATA(o_cnt) = NEW cl_gui_dialogbox_container( no_autodef_progid_dynnr = abap_true
                                                  caption                 = 'Werte'
                                                  top                     = 5
                                                  left                    = 5
                                                  width                   = 640
                                                  height                  = 240 ).

    SET HANDLER lcl_events=>on_close FOR o_cnt.

* Input
    DATA(o_input) = NEW cl_gui_input_field( parent               = o_cnt
                                            label_text           = 'InputLabel'
                                            label_width          = 10
                                            input_prompt_text    = 'Text'
                                            activate_find_button = abap_false
                                            activate_auto_submit = abap_true ).

    o_input->set_top( 30 ).
    o_input->set_text( '<default>' ).

    SET HANDLER lcl_events=>on_submit FOR o_input.
    SET HANDLER lcl_events=>on_auto_submit FOR o_input.

* Combobox
    DATA(o_combo) = NEW cl_gui_combobox( parent      = o_cnt
                                         label_text  = 'ComboLabel'
                                         label_width = 10 ).

    o_combo->set_items( VALUE vrm_values( ( key = 'A' text = 'Wert1' )
                                          ( key = 'B' text = 'Wert2' )
                                          ( key = 'C' text = 'Wert3' ) ) ).

    o_combo->set_selected_item( 'A' ).

    o_combo->activate_selection_event( ).

    o_combo->set_top( 10 ).

    SET HANDLER lcl_events=>on_select FOR o_combo.
  ENDIF.

[ABAP] Popup für Werteauswahl

TYPES: BEGIN OF ty_sel_list,
         l TYPE char100,
       END OF ty_sel_list.

TYPES: ty_it_sel_list TYPE STANDARD TABLE OF ty_sel_list WITH DEFAULT KEY.

TYPES: ty_it_rsvbfidesc TYPE STANDARD TABLE OF rsvbfidesc WITH DEFAULT KEY.

START-OF-SELECTION.

  DATA(lv_ln) = 0.

  DATA(it_sel_list) = VALUE ty_it_sel_list(
                                            ( l = 'Feld 1' )
                                            ( l = 'Feld 2' )
                                            ( l = 'Feld 3' )
                                            ( l = 'Feld 4' )
                                            ( l = 'Feld 5' )
                                          ).

  DATA(it_rsvbfidesc) = VALUE ty_it_rsvbfidesc( ( fieldnum = 1 display = abap_true ) ).

  CALL FUNCTION 'RS_VALUES_BOX'
    EXPORTING
      cursor_field         = 1
      cursor_line          = 1
      left_upper_col       = 10
      left_upper_row       = 5
      title                = 'Auswahl'
    IMPORTING
      linenumber           = lv_ln
    TABLES
      field_desc           = it_rsvbfidesc
      value_tab            = it_sel_list
    EXCEPTIONS
      clear_contents       = 1
      invalid_coordinates  = 2
      invalid_field_number = 3
      no_action            = 4
      no_fields            = 5
      no_markfield         = 6
      process_user_action  = 7
      value_tab_empty      = 8
      value_tab_too_long   = 9
      OTHERS               = 10.

  IF sy-subrc = 0.
    WRITE: / 'Auswahl:', lv_ln.
  ENDIF.

[ABAP] Popup für Ausgabe von einfachen Textlisten im Format der F1-Hilfe

* Anzeigetext
DATA(it_text) = VALUE tline_t( ( tdformat = 'U1' tdline = 'Zeile 1' )
                               ( tdformat = '' tdline = 'Zeile 2' )
                               ( tdformat = '' tdline = 'Zeile 3' ) ).

* Kommando bei Buttonklick
DATA: lv_ret_code TYPE sy-ucomm.

* Popup zur Anzeige einer Textliste (Texte in einer Tabelle)
* task: 'DECIDE':  Popup mit zwei Buttons 'Übernehmen' und 'Ändern'
*       'DISPLAY': Popup mit Ok- und Scrollbuttons
CALL FUNCTION 'COPO_POPUP_TO_DISPLAY_TEXTLIST'
  EXPORTING
    task       = 'DECIDE' " 'DISPLAY' oder 'DECIDE'
    titel      = 'Anzeige'
  IMPORTING
    function   = lv_ret_code
  TABLES
    text_table = it_text.

WRITE: / lv_ret_code.

[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] 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.