[ABAP] Einfaches Popupfenster mit Texteditor anzeigen

Variante 1 (cl_gui_dialogbox_container)

DATA: o_cnt TYPE REF TO cl_gui_dialogbox_container.
DATA: o_edit TYPE REF TO cl_gui_textedit.
DATA: it_editor TYPE STANDARD TABLE OF char1024.

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

CLASS lcl_events IMPLEMENTATION.
* Event, wenn auf das Schließen-Kreuz geklickt wird
  METHOD on_close.
    IF NOT o_edit IS INITIAL.
* vor dem Schließen Text aus dem Editor holen
      o_edit->get_text_as_stream( IMPORTING text = it_editor ).

      sender->free( ).
    ENDIF.
  ENDMETHOD.
ENDCLASS.

* Button Pos 2 Länge 20, sendet Kommando 'CMD_SHOW'
SELECTION-SCREEN: PUSHBUTTON 2(20) btn1 USER-COMMAND cmd_show.

INITIALIZATION.
* Button-Text setzen
  btn1 = |{ icon_activity }Popup anzeigen|.

AT SELECTION-SCREEN.
* wenn Button-Kommando 'CMD_SHOW'
  IF sy-ucomm = 'CMD_SHOW'.

    o_cnt = NEW #( no_autodef_progid_dynnr = abap_true
                   caption = 'Texteditor'
                   top = 100
                   left = 200
                   width = 640
                   height = 240 ).

* on_close Handler setzen
    SET HANDLER lcl_events=>on_close FOR o_cnt.

* neues Editorobjekt erzeugen (überschreibt vorherige Referenz!)
    o_edit = NEW #( wordwrap_mode = cl_gui_textedit=>wordwrap_at_windowborder
                    wordwrap_to_linebreak_mode = cl_gui_textedit=>true
                    parent = o_cnt ).

* feste Zeichenbreite
    o_edit->set_font_fixed( mode = cl_gui_textedit=>true ).
  ENDIF.

START-OF-SELECTION.
  LOOP AT it_editor ASSIGNING FIELD-SYMBOL(<l>).
    WRITE: / <l>.
  ENDLOOP.

Variante 2 (SELECTION-SCREEN)

DATA: it_editor TYPE STANDARD TABLE OF char1024.

* Button Pos 2 Länge 20, sendet Kommando 'CMD_SHOW'
SELECTION-SCREEN: PUSHBUTTON 2(20) btn1 USER-COMMAND cmd_show.

* Popup-Fenster (Selektionsbild 100) deklarieren
SELECTION-SCREEN BEGIN OF SCREEN 100 TITLE title.
SELECTION-SCREEN END OF SCREEN 100.

INITIALIZATION.
* Fenstertitel
  title = 'Texteditor'.
* Button-Text setzen
  btn1 = |{ icon_activity }Popup anzeigen|.

AT SELECTION-SCREEN.
* wenn Button-Kommando 'CMD_SHOW'
  IF sy-ucomm = 'CMD_SHOW'.
* cl_gui_container=>screen1 == SELECTION-SCREEN 100
    DATA(o_edit) = NEW cl_gui_textedit( wordwrap_mode = cl_gui_textedit=>wordwrap_at_windowborder
                                        wordwrap_to_linebreak_mode = cl_gui_textedit=>true
                                        parent = cl_gui_container=>screen1 ).

* feste Zeichenbreite
    o_edit->set_font_fixed( mode = cl_gui_textedit=>true ).

* Popup-Fenster (Selektionsbild 100) anzeigen -> cl_gui_container=>screen1 wird erzeugt
    CALL SELECTION-SCREEN 100 STARTING AT 10 5 ENDING AT 100 20.

* Text aus dem Editor holen
    o_edit->get_text_as_stream( IMPORTING text = it_editor ).

* Editorobjekt freigeben
    FREE: o_edit.
  ENDIF.

START-OF-SELECTION.
  LOOP AT it_editor ASSIGNING FIELD-SYMBOL(<l>).
    WRITE: / <l>.
  ENDLOOP.

[ABAP] Message-Log als Popup: Sammeln und Ausgeben von Nachrichten

*--------------------------------------------------------------------*
* Klasse zur Anzeige eines Nachrichtenprotokolls (Logs)
*
* Kapselt folgende FuBas:
* MESSAGES_INITIALIZE
* MESSAGE_STORE
* MESSAGES_STOP
* MESSAGES_SHOW
*--------------------------------------------------------------------*
CLASS lcl_msg_log DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS: init
      RETURNING VALUE(rv_ok) TYPE boolean.

    CLASS-METHODS: add
      IMPORTING
                i_arbgb      TYPE smesg-arbgb
                i_msgty      TYPE smesg-msgty
                i_txtnr      TYPE string
                i_zeile      TYPE i DEFAULT 0
                i_msgv1      TYPE string DEFAULT ''
                i_msgv2      TYPE string DEFAULT ''
                i_msgv3      TYPE string DEFAULT ''
                i_msgv4      TYPE string DEFAULT ''
      RETURNING VALUE(rv_ok) TYPE boolean.

    CLASS-METHODS: show
      IMPORTING
                i_show_amodal TYPE boolean DEFAULT abap_false
      RETURNING VALUE(rv_ok)  TYPE boolean.
ENDCLASS.
*--------------------------------------------------------------------*
CLASS lcl_msg_log IMPLEMENTATION.

*--------------------------------------------------------------------*
* Nachrichtenprotokoll initialisieren
*--------------------------------------------------------------------*
  METHOD init.

    rv_ok = abap_false.

* Nachrichtenprotokoll initialisieren
    CALL FUNCTION 'MESSAGES_INITIALIZE'
      EXCEPTIONS
        log_not_active       = 1
        wrong_identification = 2
        OTHERS               = 3.

    IF sy-subrc = 0.
      rv_ok = abap_true.
    ENDIF.

  ENDMETHOD.
*--------------------------------------------------------------------*
* Nachricht im Protokoll ablegen
*--------------------------------------------------------------------*
  METHOD add.

    rv_ok = abap_false.

* Nachricht im Protokoll ablegen
    CALL FUNCTION 'MESSAGE_STORE'
      EXPORTING
        arbgb                  = i_arbgb
        msgty                  = i_msgty
        msgv1                  = i_msgv1
        msgv2                  = i_msgv2
        msgv3                  = i_msgv3
        msgv4                  = i_msgv4
        txtnr                  = i_txtnr
        zeile                  = i_zeile
      EXCEPTIONS
        message_type_not_valid = 1
        not_active             = 2
        OTHERS                 = 3.

    IF sy-subrc = 0.
      rv_ok = abap_true.
    ENDIF.

  ENDMETHOD.
*--------------------------------------------------------------------*
* Nachrichtenprotokoll anzeigen
*--------------------------------------------------------------------*
  METHOD show.

    rv_ok = abap_false.

* Baustein analysiert Fehlerprotokoll und gibt als Status eine Exception aus
    CALL FUNCTION 'MESSAGES_STOP'
      EXCEPTIONS
        a_message         = 1
        e_message         = 2
        w_message         = 3
        i_message         = 4
        s_message         = 5
        deactivated_by_md = 6
        OTHERS            = 7.

* Nachrichtenprotokoll anzeigen
    CALL FUNCTION 'MESSAGES_SHOW'
      EXPORTING
        i_use_grid         = abap_true
        i_amodal_window    = i_show_amodal
      EXCEPTIONS
        inconsistent_range = 1
        no_messages        = 2
        OTHERS             = 3.

    IF sy-subrc = 0.
      rv_ok = abap_true.
    ENDIF.

  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  IF abap_true = lcl_msg_log=>init( ).

    IF abap_true = lcl_msg_log=>add( i_arbgb = 'SY'
                                     i_msgty = 'E'
                                     i_txtnr = '002'
                                     i_zeile = 0
                                     i_msgv1 = 'Fehler.' ).

      IF abap_true = lcl_msg_log=>add( i_arbgb = 'SY'
                                       i_msgty = 'W'
                                       i_txtnr = '002'
                                       i_zeile = 1
                                       i_msgv1 = 'Warnung' ).

        IF abap_true = lcl_msg_log=>add( i_arbgb = 'SY'
                                         i_msgty = 'I'
                                         i_txtnr = '002'
                                         i_zeile = 2
                                         i_msgv1 = 'Info' ).

          IF abap_true = lcl_msg_log=>show( ).

          ENDIF.
        ENDIF.
      ENDIF.
    ENDIF.
  ENDIF.

[ABAP] GUI-Toolbar mit statischem Context-Menü, Eventhandling

TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      on_function_selected FOR EVENT function_selected OF cl_gui_toolbar
        IMPORTING
            fcode
            sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
* Toolbar: Button oder Menüpunkt geklickt
  METHOD on_function_selected.

* Funktionscode auswerten
    CASE fcode.
      WHEN 'BTN_CLOSE'.
        LEAVE PROGRAM.
      WHEN 'M1'.
      WHEN 'M2'.
    ENDCASE.

* fcode ausgeben
    MESSAGE fcode TYPE 'S'.

  ENDMETHOD.
ENDCLASS.

INITIALIZATION.

* Splitter erzeugen
  DATA(o_splitter) = NEW cl_gui_splitter_container( parent = cl_gui_container=>default_screen
                                                    no_autodef_progid_dynnr = abap_true
                                                    rows = 2
                                                    columns = 1 ).

* Absoluter Modus für Zeilenhöhe
  o_splitter->set_row_mode( mode = cl_gui_splitter_container=>mode_absolute ).

* Höhe absolut 24 Pixel für Splitter oben
  o_splitter->set_row_height( id = 1 height = 24 ).

* Splitter für oberen Container fest und verborgen
  o_splitter->set_row_sash( id    = 1
                            type  = cl_gui_splitter_container=>type_movable
                            value = cl_gui_splitter_container=>false ).

  o_splitter->set_row_sash( id    = 1
                            type  = cl_gui_splitter_container=>type_sashvisible
                            value = cl_gui_splitter_container=>false ).

  DATA(o_container_top) = o_splitter->get_container( row = 1 column = 1 ).
  DATA(o_container_bottom) = o_splitter->get_container( row = 2 column = 1 ).

* Toolbar hoizontal
  DATA(o_tool) = NEW cl_gui_toolbar( parent       = o_container_top
                                     display_mode = cl_gui_toolbar=>m_mode_horizontal ).

* Eventtypten müssen gesondert registriert werden
  DATA(it_events) = VALUE ty_it_events( ( eventid    = cl_gui_toolbar=>m_id_function_selected
                                          appl_event = abap_true ) ).

  o_tool->set_registered_events( events = it_events ).

* Toolbar-Buttons und Menüs hinzufügen
* Buttontypen sind in Typgruppe CNTB definiert
  o_tool->add_button( fcode       = 'BTN_MENU'
                      icon        = icon_activate
                      butn_type   = cntb_btype_menu
                      text        = 'Menü'
                      quickinfo   = 'Menü anzeigen'
                      is_checked  = abap_false
                      is_disabled = abap_false ).

* statisches Kontextmenü für Button "BTN_MENU" erstellen
  DATA(o_menu) = NEW cl_ctmenu( ).
  o_menu->add_function( fcode   = 'M1'
                        checked = abap_false
                        text    = 'Punkt1' ).

  o_menu->add_function( fcode   = 'M2'
                        checked = abap_false
                        text    = 'Punkt2' ).

* statisches Kontextmenü mit Button verknüpfen, Zuordnung erfolgt über den Namen
* daher muss "function" gleich "fcode" des Menü-Buttons sein, sonst Exception
  DATA(it_ctxmenu) = VALUE ttb_btnmnu( ( function = 'BTN_MENU'
                                         ctmenu   = o_menu ) ).

* siehe auch Methode "set_static_ctxmenu"
  o_tool->assign_static_ctxmenu_table( it_ctxmenu ).

* Separator
  o_tool->add_button( fcode       = ''
                      icon        = ''
                      butn_type   = cntb_btype_sep
                      text        = ''
                      quickinfo   = ''
                      is_checked  = abap_false
                      is_disabled = abap_false ).

* Schließen-Button
  o_tool->add_button( fcode       = 'BTN_CLOSE'
                      icon        = icon_close
                      butn_type   = cntb_btype_button
                      text        = 'Schließen'
                      quickinfo   = 'Schließen'
                      is_checked  = abap_false
                      is_disabled = abap_false ).

* Eventhandler registrieren
  SET HANDLER lcl_events=>on_function_selected FOR o_tool.

* im unteren Splitter Beispieldaten anzeigen
  DATA: it_sflight TYPE STANDARD TABLE OF sflight.

  SELECT * FROM sflight INTO TABLE @it_sflight.

  DATA: o_salv TYPE REF TO cl_salv_table.

  cl_salv_table=>factory( EXPORTING
                            r_container  = o_container_bottom
                          IMPORTING
                            r_salv_table = o_salv
                          CHANGING
                            t_table      = it_sflight ).

  o_salv->get_functions( )->set_all( ).
  o_salv->display( ).

* leere Standard-Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

* Ausgabe von cl_gui_container=>default_screen erzwingen
  WRITE: space.

[ABAP] GUI-Toolbar mit dynamischen Context-Menü, Eventhandling, Umschaltung checked-state

TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.

TYPES: BEGIN OF ty_menuitem,
         fcode   TYPE ui_func,
         checked TYPE cua_active,
         text    TYPE gui_text,
       END OF ty_menuitem.

TYPES: ty_it_menuitems TYPE STANDARD TABLE OF ty_menuitem WITH DEFAULT KEY.

DATA: it_menuitems TYPE ty_it_menuitems.

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      on_function_selected FOR EVENT function_selected OF cl_gui_toolbar
        IMPORTING
            fcode
            sender.
    CLASS-METHODS:
      on_dropdown_clicked FOR EVENT dropdown_clicked OF cl_gui_toolbar
        IMPORTING
            fcode
            posx
            posy
            sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
* Toolbar: Button oder Menüpunktgeklickt
  METHOD on_function_selected.

* Checked-Status eines Dropdown-Menüpunktes umschalten
    IF line_exists( it_menuitems[ fcode = fcode ] ).
      ASSIGN it_menuitems[ fcode = fcode ] TO FIELD-SYMBOL(<mc>).
      <mc>-checked = COND #( WHEN <mc>-checked = abap_true THEN abap_false ELSE abap_true ).
    ENDIF.

* Funktionscode auswerten
    CASE fcode.
      WHEN 'BTN_CLOSE'.
        LEAVE PROGRAM.
      WHEN 'BTN_DROP'.
      WHEN 'M1'.
      WHEN 'M2'.
    ENDCASE.

* fcode ausgeben
    MESSAGE fcode TYPE 'S'.

  ENDMETHOD.
* Toolbar: Dropdown aktiviert
  METHOD on_dropdown_clicked.
* Menü erzeugen
    DATA(o_ctx_menu) = NEW cl_ctmenu( ).

    LOOP AT it_menuitems ASSIGNING FIELD-SYMBOL(<m>).
      o_ctx_menu->add_function( fcode   = <m>-fcode
                                checked = <m>-checked
                                text    = <m>-text ).
    ENDLOOP.

* Kontextmenü an der akt. Position anzeigen
    sender->track_context_menu( context_menu = o_ctx_menu
                                posx         = posx
                                posy         = posy ).
  ENDMETHOD.
ENDCLASS.

INITIALIZATION.

  it_menuitems = VALUE #( ( fcode   = 'M1'
                            checked = abap_false
                            text    = 'Punkt1' )
                          ( fcode   = 'M2'
                            checked = abap_true
                            text    = 'Punkt2' ) ).

* Splitter erzeugen
  DATA(o_splitter) = NEW cl_gui_splitter_container( parent = cl_gui_container=>default_screen
                                                    no_autodef_progid_dynnr = abap_true
                                                    rows = 2
                                                    columns = 1 ).

* Absoluter Modus für Zeilenhöhe
  o_splitter->set_row_mode( mode = cl_gui_splitter_container=>mode_absolute ).

* Höhe absolut 24 Pixel für Splitter oben
  o_splitter->set_row_height( id = 1 height = 24 ).

* Splitter für oberen Container fest und verborgen
  o_splitter->set_row_sash( id = 1
                            type = cl_gui_splitter_container=>type_movable
                            value = cl_gui_splitter_container=>false ).

  o_splitter->set_row_sash( id = 1
                            type = cl_gui_splitter_container=>type_sashvisible
                            value = cl_gui_splitter_container=>false ).

  DATA(o_container_top) = o_splitter->get_container( row = 1 column = 1 ).
  DATA(o_container_bottom) = o_splitter->get_container( row = 2 column = 1 ).

* Toolbar hoizontal
  DATA(o_tool) = NEW cl_gui_toolbar( parent = o_container_top
                                     display_mode = cl_gui_toolbar=>m_mode_horizontal ).

* Eventtypten müssen gesondert registriert werden
  DATA(it_events) = VALUE ty_it_events( ( eventid = cl_gui_toolbar=>m_id_function_selected
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_toolbar=>m_id_dropdown_clicked
                                          appl_event = abap_true ) ).

  o_tool->set_registered_events( events = it_events ).

* Toolbar-Buttons hinzufügen
* Buttontypen sind in Typgruppe CNTB definiert
  o_tool->add_button( fcode       = 'BTN_DROP'
                      icon        = icon_activate
                      butn_type   = cntb_btype_dropdown
                      text        = 'Menü'
                      quickinfo   = 'Menü anzeigen'
                      is_checked  = abap_false
                      is_disabled = abap_false ).

  o_tool->add_button( fcode       = ''
                      icon        = ''
                      butn_type   = cntb_btype_sep
                      text        = ''
                      quickinfo   = ''
                      is_checked  = abap_false
                      is_disabled = abap_false ).

  o_tool->add_button( fcode       = 'BTN_CLOSE'
                      icon        = icon_close
                      butn_type   = cntb_btype_button
                      text        = 'Schließen'
                      quickinfo   = 'Schließen'
                      is_checked  = abap_false
                      is_disabled = abap_false ).

* Eventhandler registrieren
  SET HANDLER lcl_events=>on_function_selected FOR o_tool.
  SET HANDLER lcl_events=>on_dropdown_clicked FOR o_tool.

* im unteren Splitter Beispieldaten anzeigen
  DATA: it_sflight TYPE STANDARD TABLE OF sflight.

  SELECT * FROM sflight INTO TABLE @it_sflight.

  DATA: o_salv TYPE REF TO cl_salv_table.

  cl_salv_table=>factory( EXPORTING
                            r_container    = o_container_bottom
                          IMPORTING
                            r_salv_table   = o_salv
                          CHANGING
                            t_table        = it_sflight ).

  o_salv->get_functions( )->set_all( ).
  o_salv->display( ).

* leere Standard-Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

* Ausgabe von cl_gui_container=>default_screen erzwingen
  WRITE: space.

Weiterführender Link zur Ideen-Quelle: Link

[ABAP] Erweiterte Baumansicht mit einem cl_gui_column_tree, Eventhandling

* Demoprogramm: SAPCOLUMN_TREE_CONTROL_DEMO

CONSTANTS: co_root TYPE tv_nodekey VALUE 'Root'.
CONSTANTS: co_auart TYPE tv_itmname VALUE 'Auftragsart'.
CONSTANTS: co_matnr TYPE tv_itmname VALUE 'Mat.-Nr.'.
CONSTANTS: co_arktx TYPE tv_itmname VALUE 'Kurztext'.
CONSTANTS: co_netwr TYPE tv_itmname VALUE 'Wert'.
CONSTANTS: co_flag TYPE tv_itmname VALUE 'Flag'.

DATA: it_nodes TYPE treev_ntab.
DATA: it_items TYPE STANDARD TABLE OF mtreeitm WITH DEFAULT KEY.

TYPES: ty_it_events TYPE STANDARD TABLE OF cntl_simple_event WITH DEFAULT KEY.

TYPES: BEGIN OF ty_vbak_vbap,
         auart TYPE vbak-auart,
         vbeln TYPE vbak-vbeln,
         posnr TYPE vbap-posnr,
         matnr TYPE vbap-matnr,
         arktx TYPE vbap-arktx,
         netwr TYPE vbap-netwr,
         flag  TYPE boolean,
       END OF ty_vbak_vbap.

TYPES: ty_it_vbak_vbap TYPE STANDARD TABLE OF ty_vbak_vbap WITH DEFAULT KEY.

* Eventhandlerklasse
CLASS lcl_event DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS: on_node_double_click FOR EVENT node_double_click OF cl_gui_column_tree
      IMPORTING
          node_key
          sender.
    CLASS-METHODS: on_item_double_click FOR EVENT item_double_click OF cl_gui_column_tree
      IMPORTING
          node_key
          item_name
          sender.
    CLASS-METHODS: on_expand_no_children FOR EVENT expand_no_children OF cl_gui_column_tree
      IMPORTING
          node_key
          sender.
    CLASS-METHODS: on_header_click FOR EVENT header_click OF cl_gui_column_tree
      IMPORTING
          header_name
          sender.
    CLASS-METHODS: on_button_click FOR EVENT button_click OF cl_gui_column_tree
      IMPORTING
          node_key
          item_name
          sender.
    CLASS-METHODS: on_link_click FOR EVENT link_click OF cl_gui_column_tree
      IMPORTING
          node_key
          item_name
          sender.
    CLASS-METHODS: on_checkbox_change FOR EVENT checkbox_change OF cl_gui_column_tree
      IMPORTING
          node_key
          item_name
          checked
          sender.
    CLASS-METHODS: on_dft_context_menu_req FOR EVENT default_context_menu_request OF cl_gui_column_tree
      IMPORTING
          menu
          sender.
    CLASS-METHODS: on_dft_context_menu_sel FOR EVENT default_context_menu_select OF cl_gui_column_tree
      IMPORTING
          fcode
          sender.
    CLASS-METHODS: on_node_context_menu_req FOR EVENT node_context_menu_request OF cl_gui_column_tree
      IMPORTING
          node_key
          menu
          sender.
    CLASS-METHODS: on_node_context_menu_sel FOR EVENT node_context_menu_select OF cl_gui_column_tree
      IMPORTING
          node_key
          fcode
          sender.
    CLASS-METHODS: on_item_context_menu_req FOR EVENT item_context_menu_request OF cl_gui_column_tree
      IMPORTING
          node_key
          item_name
          menu
          sender.
    CLASS-METHODS: on_item_context_menu_sel FOR EVENT item_context_menu_select OF cl_gui_column_tree
      IMPORTING
          node_key
          item_name
          fcode
          sender.
    CLASS-METHODS: on_header_context_menu_req FOR EVENT header_context_menu_request OF cl_gui_column_tree
      IMPORTING
          header_name
          menu
          sender.
    CLASS-METHODS: on_header_context_menu_sel FOR EVENT header_context_menu_select OF cl_gui_column_tree
      IMPORTING
          header_name
          fcode
          sender.
ENDCLASS.

CLASS lcl_event IMPLEMENTATION.
* Doppelklick auf Icon
  METHOD on_node_double_click.
    MESSAGE node_key TYPE 'S'.
  ENDMETHOD.
* Doppelklick auf Item
  METHOD on_item_double_click.

    CASE item_name.
* wenn Item für Wert NETWR editiert werden soll
      WHEN co_netwr.
* Text aus der Nodes-Tabelle lesen
        ASSIGN it_items[ node_key = node_key item_name = item_name ] TO FIELD-SYMBOL(<i>).

        DATA: lv_changed TYPE as4flag.
        DATA: lv_value TYPE string.

        lv_value = condense( <i>-text ).

* Popup für Werte-Eingabe
        CALL FUNCTION 'CC_POPUP_STRING_INPUT'
          EXPORTING
            property_name = 'NETWR:'
          IMPORTING
            value_changed = lv_changed
          CHANGING
            string_value  = lv_value.

        IF lv_changed = abap_true.
* Text in der Item Table anpassen
          <i>-text = lv_value.

* Text in der Node anpassen
          sender->item_set_text( node_key  = node_key
                                 item_name = item_name
                                 text      = |{ <i>-text }| ).
        ENDIF.
    ENDCASE.

    MESSAGE |{ item_name }_{ node_key }| TYPE 'S'.
  ENDMETHOD.
* bei Expandierung eines Baumelements ohne Unterelemente
* hier können evtl. Daten nachgeladen werden
  METHOD on_expand_no_children.
    MESSAGE node_key TYPE 'S'.
  ENDMETHOD.
* Header-Klick
  METHOD on_header_click.
    MESSAGE |{ header_name }| TYPE 'S'.
  ENDMETHOD.
* Button-Klick
  METHOD on_button_click.
    MESSAGE |{ item_name }_{ node_key }| TYPE 'S'.
  ENDMETHOD.
* Link-Klick
  METHOD on_link_click.
    MESSAGE |{ item_name }_{ node_key }| TYPE 'S'.
  ENDMETHOD.
* Checkbox Change
  METHOD on_checkbox_change.
    MESSAGE |{ item_name }_{ node_key }: { checked }| TYPE 'S'.
  ENDMETHOD.
* Freier Klickbereich: Kontextmenu füllen
  METHOD on_dft_context_menu_req.

    menu->add_function( text = 'Message'
                        fcode = 'MSG' ).

    menu->add_function( text = 'Exit'
                        fcode = 'EXIT' ).

  ENDMETHOD.
* Freier Klickbereich: Klick im Kontextmenu auswerten
  METHOD on_dft_context_menu_sel.

    CASE fcode.

      WHEN 'MSG'.
        MESSAGE 'Message' TYPE 'S'.
      WHEN 'EXIT'.
        LEAVE PROGRAM.

    ENDCASE.

  ENDMETHOD.
* Node: Kontextmenu füllen
  METHOD on_node_context_menu_req.

    menu->add_function( text = |{ node_key }|
                        fcode = 'NODE' ).

  ENDMETHOD.
* Node: Klick im Kontextmenu auswerten
  METHOD on_node_context_menu_sel.

    CASE fcode.

      WHEN 'NODE'.
        MESSAGE node_key TYPE 'S'.

    ENDCASE.

  ENDMETHOD.
* Item: Kontextmenu füllen
  METHOD on_item_context_menu_req.

    menu->add_function( text = |{ node_key }_{ item_name }|
                        fcode = 'NODE_ITEM' ).

  ENDMETHOD.
* Item: Klick im Kontextmenu auswerten
  METHOD on_item_context_menu_sel.

    CASE fcode.

      WHEN 'NODE_ITEM'.
        MESSAGE |{ node_key }_{ item_name }| TYPE 'S'.

    ENDCASE.

  ENDMETHOD.
* Header: Kontextmenu füllen
  METHOD on_header_context_menu_req.

    menu->add_function( text = |{ header_name }|
                        fcode = 'HEADER' ).

  ENDMETHOD.
* Header: Klick im Kontextmenu auswerten
  METHOD on_header_context_menu_sel.

    CASE fcode.

      WHEN 'HEADER'.
        MESSAGE |{ header_name }| TYPE 'S'.

    ENDCASE.

  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  DATA: it_vbak_vbap TYPE ty_it_vbak_vbap.

* Daten holen -> bei zu vielen Elementen (-> 450?) kommt es zum Absturz der Trees
  SELECT vbak~auart, vbak~vbeln, vbap~posnr, vbap~matnr, vbap~arktx, vbap~netwr FROM vbak
    INNER JOIN vbap ON vbak~vbeln = vbap~vbeln
    INTO CORRESPONDING FIELDS OF TABLE @it_vbak_vbap
    UP TO 100 ROWS.

  SORT: it_vbak_vbap BY auart vbeln posnr.

* 1. Spalte des Trees
  DATA(lv_thhdr) = VALUE treev_hhdr( heading = co_auart
                                     width   = 50 ).

* Tree-Objekt im default_screen einbetten
  DATA(o_tree) = NEW cl_gui_column_tree( parent                = cl_gui_container=>default_screen
                                         node_selection_mode   = cl_gui_column_tree=>node_sel_mode_single
                                         item_selection        = abap_true
                                         hierarchy_column_name = co_auart
                                         hierarchy_header      = lv_thhdr ).

* Eventtypten müssen gesondert registriert werden
  DATA(it_events) = VALUE ty_it_events( ( eventid = cl_gui_column_tree=>eventid_node_double_click
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_item_double_click
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_expand_no_children
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_link_click
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_button_click
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_checkbox_change
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_header_click
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_def_context_menu_req
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_node_context_menu_req
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_item_context_menu_req
                                          appl_event = abap_true )
                                        ( eventid = cl_gui_column_tree=>eventid_header_context_men_req
                                          appl_event = abap_true ) ).

* Events registrieren
  o_tree->set_registered_events( events = it_events ).

* Eventhandler für Klicks und Kontextmenüs
  SET HANDLER lcl_event=>on_node_double_click FOR o_tree.
  SET HANDLER lcl_event=>on_item_double_click FOR o_tree.
  SET HANDLER lcl_event=>on_expand_no_children FOR o_tree.
  SET HANDLER lcl_event=>on_header_click FOR o_tree.
  SET HANDLER lcl_event=>on_button_click FOR o_tree.
  SET HANDLER lcl_event=>on_link_click FOR o_tree.
  SET HANDLER lcl_event=>on_checkbox_change FOR o_tree.
  SET HANDLER lcl_event=>on_dft_context_menu_req FOR o_tree.
  SET HANDLER lcl_event=>on_dft_context_menu_sel FOR o_tree.
  SET HANDLER lcl_event=>on_node_context_menu_req FOR o_tree.
  SET HANDLER lcl_event=>on_node_context_menu_sel FOR o_tree.
  SET HANDLER lcl_event=>on_item_context_menu_req FOR o_tree.
  SET HANDLER lcl_event=>on_item_context_menu_sel FOR o_tree.
  SET HANDLER lcl_event=>on_header_context_menu_req FOR o_tree.
  SET HANDLER lcl_event=>on_header_context_menu_sel FOR o_tree.

* weitere Spalten entsprechend der Reihenfolge
  o_tree->add_column( name        = co_matnr
                      width       = 30
                      header_text = CONV #( co_matnr ) ).

  o_tree->add_column( name        = co_arktx
                      width       = 70
                      header_text = CONV #( co_arktx ) ).

  o_tree->add_column( name        = co_netwr
                      width       = 30
                      header_text = CONV #( co_netwr ) ).

  o_tree->add_column( name        = co_flag
                      width       = 5
                      header_text = CONV #( co_flag ) ).

* Inhalt des Trees komplett löschen
*  o_tree->delete_all_nodes( ).

* Rootnode einfügen
  it_nodes = VALUE #( ( node_key  = co_root
                        isfolder  = abap_true ) ).

* Items der Rootnode
  it_items = VALUE #( ( node_key  = co_root
                        item_name = co_auart
                        class     = cl_gui_column_tree=>item_class_text
                        text      = co_root
                        font      = cl_gui_column_tree=>item_font_fixed
                        style     = cl_gui_column_tree=>style_intensified )

                      ( node_key  = co_root
                        item_name = co_matnr
                        class     = cl_gui_column_tree=>item_class_text
                        text      = '' )

                      ( node_key  = co_root
                        item_name = co_arktx
                        class     = cl_gui_column_tree=>item_class_text
                        text      = '' )

                      ( node_key  = co_root
                        item_name = co_netwr
                        class     = cl_gui_column_tree=>item_class_text
                        text      = '' )

                      ( node_key  = co_root
                        item_name = co_flag
                        class     = cl_gui_column_tree=>item_class_text
                        text      = '' ) ).

* Unternodes: Auftragsarten <a> -> Belege <v> -> Positionen <p>
  LOOP AT it_vbak_vbap ASSIGNING FIELD-SYMBOL(<a>) GROUP BY <a>-auart ASCENDING.
* Node für Auftragsarten
    APPEND VALUE #( node_key  = <a>-auart
                    relatkey  = co_root
                    relatship = cl_gui_column_tree=>relat_last_child
                    isfolder  = abap_true
                    expander  = abap_true ) TO it_nodes.

* Items für Auftragsarten
    APPEND VALUE #( node_key  = <a>-auart
                    item_name = co_auart
                    class     = cl_gui_column_tree=>item_class_text
                    text      = <a>-auart
                    font      = cl_gui_column_tree=>item_font_fixed ) TO it_items.

    APPEND VALUE #( node_key  = <a>-auart
                    item_name = co_matnr
                    class     = cl_gui_column_tree=>item_class_text
                    text      = '' ) TO it_items.

    APPEND VALUE #( node_key  = <a>-auart
                    item_name = co_arktx
                    class     = cl_gui_column_tree=>item_class_text
                    text      = '' ) TO it_items.

    APPEND VALUE #( node_key  = <a>-auart
                    item_name = co_netwr
                    class     = cl_gui_column_tree=>item_class_text
                    text      = '' ) TO it_items.

    APPEND VALUE #( node_key  = <a>-auart
                    item_name = co_flag
                    class     = cl_gui_column_tree=>item_class_text
                    text      = '' ) TO it_items.

    LOOP AT GROUP <a> ASSIGNING FIELD-SYMBOL(<v>) GROUP BY <v>-vbeln ASCENDING.
* Node für Belegnummern
      APPEND VALUE #( node_key  = <v>-vbeln
                      relatkey  = <a>-auart
                      relatship = cl_gui_column_tree=>relat_last_child
                      isfolder  = abap_true
                      expander  = abap_true ) TO it_nodes.

* Items für Belegnummern
      APPEND VALUE #( node_key  = <v>-vbeln
                      item_name = co_auart
                      class     = cl_gui_column_tree=>item_class_text
                      text      = <v>-vbeln
                      font      = cl_gui_column_tree=>item_font_fixed ) TO it_items.

      APPEND VALUE #( node_key  = <v>-vbeln
                      item_name = co_matnr
                      class     = cl_gui_column_tree=>item_class_text
                      text      = '' ) TO it_items.

      APPEND VALUE #( node_key  = <v>-vbeln
                      item_name = co_arktx
                      class     = cl_gui_column_tree=>item_class_text
                      text      = '' ) TO it_items.

      APPEND VALUE #( node_key  = <v>-vbeln
                      item_name = co_flag
                      class     = cl_gui_column_tree=>item_class_text
                      text      = '' ) TO it_items.

      DATA(lv_sum_netwr) = VALUE vbap-netwr( ).
      DATA(lv_cnt) = 0.

      LOOP AT GROUP <v> ASSIGNING FIELD-SYMBOL(<p>).
* Node für Positionen
* eindeutigen Key erzeugen (max. 12 Zeichen lang)
        DATA(lv_pos_key) = |{ <p>-vbeln ALPHA = OUT }{ <p>-posnr ALPHA = OUT }|.
        APPEND VALUE #( node_key  = lv_pos_key
                        relatkey  = <v>-vbeln
                        relatship = cl_gui_column_tree=>relat_last_child
                        isfolder  = abap_false
                        expander  = abap_false ) TO it_nodes.

* Items für Positionen
        APPEND VALUE #( node_key  = lv_pos_key
                        item_name = co_auart
                        class     = cl_gui_column_tree=>item_class_button
                        text      = <p>-posnr
                        font      = cl_gui_column_tree=>item_font_default ) TO it_items.

        APPEND VALUE #( node_key  = lv_pos_key
                        item_name = co_matnr
                        class     = cl_gui_column_tree=>item_class_link
                        text      = <p>-matnr
                        style     = cl_gui_column_tree=>style_intensified
                        font      = cl_gui_column_tree=>item_font_fixed ) TO it_items.

        APPEND VALUE #( node_key  = lv_pos_key
                        item_name = co_arktx
                        class     = cl_gui_column_tree=>item_class_text
                        text      = <p>-arktx
                        font      = cl_gui_column_tree=>item_font_fixed ) TO it_items.

        APPEND VALUE #( node_key  = lv_pos_key
                        item_name = co_netwr
                        class     = cl_gui_column_tree=>item_class_text
                        text      = CONV string( <p>-netwr )
                        font      = cl_gui_column_tree=>item_font_fixed ) TO it_items.

        APPEND VALUE #( node_key  = lv_pos_key
                        item_name = co_flag
                        class     = cl_gui_column_tree=>item_class_checkbox
                        editable  = abap_true
                        text      = <p>-flag ) TO it_items.

* Summierung des NETWR für übergeordnetes Item
        lv_sum_netwr = lv_sum_netwr + <p>-netwr.
        lv_cnt = lv_cnt + 1.
      ENDLOOP.

* Ausgabe der Summe in Item für Position
      APPEND VALUE #( node_key  = <v>-vbeln
                      item_name = co_netwr
                      class     = cl_gui_column_tree=>item_class_text
                      text      = |Summe: { lv_sum_netwr } ({ lv_cnt })|
                      font      = cl_gui_column_tree=>item_font_fixed ) TO it_items.

    ENDLOOP.
  ENDLOOP.

* Nodes und Items zum Baum hinzufügen und anzeigen
  o_tree->add_nodes_and_items( node_table                = it_nodes
                               item_table                = it_items
                               item_table_structure_name = 'MTREEITM' ). " Typ muss gleich mit Zeilentyp von it_items sein

* Root-Nodes des Trees expandieren
  o_tree->expand_root_nodes( ).

* Spaltenbreiten anpassen
*  o_tree->adjust_column_width( all_columns     = abap_true
*                               include_heading = abap_true ).

* leere Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

* Erzwingung der Listenausgabe in cl_gui_container=>default_screen und Anzeige des Trees
  WRITE space.

[ABAP] ALV-Grid: Dropdown-Liste verwenden

**********************************************************************
*
* Variablen
*
**********************************************************************
DATA: gv_screen_status TYPE string VALUE 'INIT'.
DATA: gv_carrid TYPE spfli-carrid.
DATA: gv_connid TYPE spfli-connid.
DATA: o_alv TYPE REF TO cl_gui_alv_grid.
DATA: it_spfli TYPE STANDARD TABLE OF spfli WITH DEFAULT KEY.
**********************************************************************
*
* leeres Dynpro als Dummy für ALV-Grid
*
**********************************************************************
SELECTION-SCREEN BEGIN OF SCREEN 2000.
SELECTION-SCREEN END OF SCREEN 2000.
**********************************************************************
*
* SELECTION-SCREEN
*
**********************************************************************
SELECT-OPTIONS: so_carr FOR gv_carrid.
SELECT-OPTIONS: so_conn FOR gv_connid.
**********************************************************************
*
* Eventhandler
*
**********************************************************************
CLASS lcl_events DEFINITION.

  PUBLIC SECTION.

    CLASS-METHODS:
      on_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
        IMPORTING
            e_object
            e_interactive
            sender.

    CLASS-METHODS:
      on_data_changed FOR EVENT data_changed OF cl_gui_alv_grid
        IMPORTING
            er_data_changed
            sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.

  METHOD on_data_changed.
* geänderte Zellen durchgehen
    LOOP AT er_data_changed->mt_good_cells ASSIGNING FIELD-SYMBOL(<fs_changed>).
      IF <fs_changed> IS ASSIGNED.
* Zeile x aus der iTab it_mara rausholen und daraus die Zelle anhand des Spaltennamens (Feldnamens) holen
        ASSIGN COMPONENT <fs_changed>-fieldname OF STRUCTURE it_spfli[ <fs_changed>-row_id ] TO FIELD-SYMBOL(<fs_mara_field>).

* Änderungswert in die Zelle der iTab (it_mara) rückschreiben
        <fs_mara_field> = <fs_changed>-value.
      ENDIF.

    ENDLOOP.

* DB Update
    FIELD-SYMBOLS: <fs_tab> TYPE table.
    FIELD-SYMBOLS: <fs_row> TYPE spfli.

    ASSIGN er_data_changed->mp_mod_rows->* TO <fs_tab>.

    LOOP AT <fs_tab> ASSIGNING <fs_row>.
* DB Update hier
    ENDLOOP.

  ENDMETHOD.

  METHOD on_toolbar.
* alle Buttons entfernen, bis auf folgende:
    DELETE e_object->mt_toolbar WHERE
        function NE cl_gui_alv_grid=>mc_fc_refresh          " Refresh
    AND function NE cl_gui_alv_grid=>mc_mb_export           " Excel
    AND function NE cl_gui_alv_grid=>mc_fc_current_variant. " Layout

  ENDMETHOD.
ENDCLASS.
**********************************************************************
*
* INITIALIZATION
*
**********************************************************************
INITIALIZATION.

* Vorbelegungen für Selektionsbild
  so_carr[] = VALUE #( ( sign = 'I' option = 'EQ' low = 'LH' ) ).

**********************************************************************
*
* AT SELECTION-SCREEN OUTPUT
*
**********************************************************************
AT SELECTION-SCREEN OUTPUT.

* Wenn vorher das Selektionsbild 1000 angezeigt wurde
  IF gv_screen_status = 'IN_SELECTION'.
* Daten holen
    SELECT * FROM spfli INTO TABLE @it_spfli
       WHERE carrid IN @so_carr
         AND connid IN @so_conn.
* ALV-Gitter anzeigen
    o_alv = NEW #( i_parent      = cl_gui_container=>default_screen
                   i_appl_events = abap_true ).

* Eventhandler registrieren
    SET HANDLER lcl_events=>on_toolbar FOR o_alv.
    SET HANDLER lcl_events=>on_data_changed FOR o_alv.

* Ereignisse registrieren
    o_alv->register_edit_event( i_event_id = cl_gui_alv_grid=>mc_evt_enter ).
    o_alv->register_edit_event( i_event_id = cl_gui_alv_grid=>mc_evt_modified ).

* ALV-Grid selektionsbereit setzen
    o_alv->set_ready_for_input( i_ready_for_input = 1 ).

* Layout des ALV setzen
    DATA(lv_layout) = VALUE lvc_s_layo( zebra      = abap_true
                                        cwidth_opt = 'A'
                                        grid_title = 'Flugverbindungen' ).

* Feldkatalog automatisch durch SALV erstellen lassen
    DATA: o_salv TYPE REF TO cl_salv_table.

    cl_salv_table=>factory( IMPORTING
                              r_salv_table = o_salv
                            CHANGING
                              t_table      = it_spfli ).

    DATA(it_fcat) = cl_salv_controller_metadata=>get_lvc_fieldcatalog( r_columns      = o_salv->get_columns( )
                                                                       r_aggregations = o_salv->get_aggregations( ) ).

* Drop-Down-Liste definieren und an das ALV-Gitter übergeben
    DATA(it_dropdown) = VALUE lvc_t_drop( ( handle = 1
                                            value  = 'BERLIN' )
                                          ( handle = 1
                                            value  = 'FRANKFURT' )
                                          ( handle = 1
                                            value  = 'NEW YORK' ) ).

    o_alv->set_drop_down_table( it_drop_down = it_dropdown ).

* im Feldkatalog alle Zellen der Spalte "CITYFROM" des ALV-Grids auf
* editierbar stellen, die restlichen Zellen sind nicht editierbar
    LOOP AT it_fcat ASSIGNING FIELD-SYMBOL(<fcat>).
      CASE <fcat>-fieldname.
        WHEN 'CITYFROM'.
          <fcat>-edit = abap_true.
          <fcat>-drdn_hndl = 1.      " Drop-Down-Liste mit Handle = 1 für die Zelle setzen
          <fcat>-outputlen = 10.
        WHEN OTHERS.
          <fcat>-edit = abap_false.
      ENDCASE.
    ENDLOOP.

* ALV anzeigen
    o_alv->set_table_for_first_display( EXPORTING
                                          i_bypassing_buffer = abap_false
                                          i_save             = 'A'
                                          is_layout          = lv_layout
                                        CHANGING
                                          it_fieldcatalog    = it_fcat
                                          it_outtab          = it_spfli ).

* Focus auf ALV setzen
    cl_gui_alv_grid=>set_focus( control = o_alv ).

* leere SAP-Toolbar ausblenden
    cl_abap_list_layout=>suppress_toolbar( ).

* Flag für Screen-Status auf ALV-Anzeige setzen
    gv_screen_status = 'IN_ALV'.
  ENDIF.
**********************************************************************
*
* START-OF-SELECTION
*
**********************************************************************
START-OF-SELECTION.

* Wir befinden uns im Anzeigebereich des Selektionsbildes
  gv_screen_status = 'IN_SELECTION'.

* Trick: leeren Dummy-Screen 2000 anzeigen und intern für das ALV-Grid in
* AT SELECTION-SCREEN OUTPUT als cl_gui_container=>default_screen nutzen
  CALL SELECTION-SCREEN 2000.

[ABAP] SAP-GUI anzeigen / verbergen

* SAP-GUI anzeigen
CALL FUNCTION 'SAPGUI_SET_PROPERTY' DESTINATION 'SAPGUI'
  EXPORTING
    property              = 'VISIBLE'
    value                 = abap_true
  EXCEPTIONS
    system_failure        = 1
    communication_failure = 2
    OTHERS                = 3.

* SAP-GUI verbergen
CALL FUNCTION 'SAPGUI_SET_PROPERTY' DESTINATION 'SAPGUI'
  EXPORTING
    property              = 'VISIBLE'
    value                 = abap_false
  EXCEPTIONS
    system_failure        = 1
    communication_failure = 2
    OTHERS                = 3.

[ABAP] SAP-GUI aktivieren / deaktivieren

* SAP-GUI deaktivieren
CALL FUNCTION 'SAPGUI_SET_PROPERTY' DESTINATION 'SAPGUI'
  EXPORTING
    property              = 'ACTIVATE'
    value                 = abap_false
  EXCEPTIONS
    system_failure        = 1
    communication_failure = 2
    OTHERS                = 3.

* SAP-GUI aktivieren
CALL FUNCTION 'SAPGUI_SET_PROPERTY' DESTINATION 'SAPGUI'
  EXPORTING
    property              = 'ACTIVATE'
    value                 = abap_true
  EXCEPTIONS
    system_failure        = 1
    communication_failure = 2
    OTHERS                = 3.