[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] SALV-Table: Eigenen Button einfügen und Ereignis abfangen

* http://ajanzen.com/pdf_dokumente/sap_abap/alv/alv_sel_mode_own_funct.pdf

* Eventhandler für neuen Button
CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
* Bezeichner des Buttons
    CONSTANTS: co_btn_xl_export TYPE string VALUE 'BTN_XL_EXPORT'.

    CLASS-METHODS : on_toolbar_click FOR EVENT added_function OF cl_salv_events_table
      IMPORTING
          e_salv_function
          sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
  METHOD on_toolbar_click.
    CASE e_salv_function.
      WHEN co_btn_xl_export.
        MESSAGE co_btn_xl_export TYPE 'S'.
    ENDCASE.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

* Toolbar der Listausgabe unterdrücken
  cl_abap_list_layout=>suppress_toolbar( ).

  DATA: o_alv TYPE REF TO cl_salv_table.
  DATA: it_tab TYPE ...

  cl_salv_table=>factory( EXPORTING
                            r_container = cl_gui_container=>default_screen
                          IMPORTING
                            r_salv_table = o_alv
                          CHANGING
                            t_table = it_tab ).

* Standardbuttons der SALV-Table ausblenden
  o_alv->get_functions( )->set_all( abap_false ).

* Eigenen SALV-Button hinzufügen
* das Hinzufügen des Buttons funktioniert nur, wenn die SALV-Table innerhalb eines Containers (z.B. cl_gui_container=>default_screen) eingebettet ist
  o_alv->get_functions( )->add_function( name = |{ lcl_events=>co_btn_xl_export }|
                                         icon = |{ icon_export }|
                                         text = 'Export'
                                         tooltip = 'Daten exportieren'
                                         position = if_salv_c_function_position=>right_of_salv_functions ).

* Eventhandler für Klicks in die Toolbar des SALV-Grids setzen
  SET HANDLER lcl_events=>on_toolbar_click FOR o_alv->get_event( ).

* SALV anzeigen
  o_alv->display( ).

* Listausgabe erzwingen für Erzeugung von cl_gui_container=>default_screen
  WRITE: space.

[ABAP] GUI-Simple-Tree und SALV-Grid in Split-Container ohne Dynpro anzeigen, Eventhandling

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

DATA: o_salv TYPE REF TO cl_salv_table.
DATA: it_tree_spfli TYPE STANDARD TABLE OF spfli.
DATA: it_salv_spfli TYPE STANDARD TABLE OF spfli.
DATA: it_nodes TYPE ty_it_nodes.

CLASS lcl_events DEFINITION.
  PUBLIC SECTION.
* GUI Simple Tree
    CLASS-METHODS: on_keypress FOR EVENT node_keypress OF cl_gui_simple_tree
      IMPORTING
          node_key
          key
          sender.
    CLASS-METHODS: on_selection_changed FOR EVENT selection_changed OF cl_gui_simple_tree
      IMPORTING
          node_key
          sender.
    CLASS-METHODS: on_expand_no_children FOR EVENT expand_no_children OF cl_gui_simple_tree
      IMPORTING
          node_key
          sender.
* ALV-Events für das SALV-Grid
    CLASS-METHODS: on_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
      IMPORTING
          e_object
          sender.
    CLASS-METHODS: on_user_command FOR EVENT user_command OF cl_gui_alv_grid
      IMPORTING
          e_ucomm
          sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
* Tastendruck
  METHOD on_keypress.
    MESSAGE |Node: { node_key } Taste: { key }| TYPE 'S'.
  ENDMETHOD.
* Klick auf ein aktives Baumelement
  METHOD on_selection_changed.
* Element in der Nodes-Tabelle lesen
    ASSIGN it_nodes[ node_key = node_key ] TO FIELD-SYMBOL(<fs_node>).

* iTab für SALV-Table neu aufbauen
    CLEAR: it_salv_spfli.

    LOOP AT it_tree_spfli ASSIGNING FIELD-SYMBOL(<fs_line>) WHERE carrid = <fs_node>-text.
      APPEND <fs_line> TO it_salv_spfli.
    ENDLOOP.

* SALV-Table neu anzeigen
    o_salv->refresh( ).
  ENDMETHOD.
* bei Expandierung eines Baumelements ohne Unterelemente
  METHOD on_expand_no_children.
    MESSAGE |Node: { node_key }| TYPE 'S'.
  ENDMETHOD.

* Toolbar-Buttons hinzufügen:
* butn_type   Bezeichung
* 0           Button (normal)
* 1           Menü + Defaultbutton
* 2           Menü
* 3           Separator
* 4           Radiobutton
* 5           Auswahlknopf (Checkbox)
* 6           Menüeintrag
  METHOD on_toolbar.
* Separator hinzufügen
    APPEND VALUE #( butn_type = 3 ) TO e_object->mt_toolbar.
* Edit-Button hinzufügen
    APPEND VALUE #( butn_type = 5 text = 'Daten anzeigen' icon = icon_icon_list function = 'SHOW_DATA' quickinfo = 'Daten anzeigen' disabled = ' ' ) TO e_object->mt_toolbar.
  ENDMETHOD.
* Benutzerkommando (Button-Klick)
  METHOD on_user_command.
    CASE e_ucomm.
      WHEN 'SHOW_DATA'.
        DATA: lv_row TYPE i. " Zeile auf Grid
        DATA: lv_value TYPE char255. " Wert
        DATA: lv_col TYPE i. " Spalte auf Grid
        DATA: lv_row_id TYPE lvc_s_row. " Zeilen-Id
        DATA: lv_col_id TYPE lvc_s_col. " Spalten-Id
        DATA: lv_row_no TYPE lvc_s_roid. " Numerische Zeilen ID

        sender->get_current_cell( IMPORTING
                                    e_row = lv_row
                                    e_value = lv_value
                                    e_col = lv_col
                                    es_row_id = lv_row_id
                                    es_col_id = lv_col_id
                                    es_row_no = lv_row_no ).

        MESSAGE |Zeile: { lv_row }, Spalte: { lv_col }, Wert: { lv_value }, Spaltenname: { lv_col_id-fieldname }| TYPE 'S'.
    ENDCASE.
  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.

  SELECT * INTO TABLE it_tree_spfli FROM spfli.

* Splitter auf screen0 erzeugen
  DATA(o_split) = NEW cl_gui_splitter_container( parent = cl_gui_container=>screen0
                                                 no_autodef_progid_dynnr = abap_true
                                                 rows = 1
                                                 columns = 2 ).

* Breite in % (linke Spalte für den Tree)
  o_split->set_column_width( id = 1 width = 15 ).

* linken und rechten Splitcontainer holen
  DATA(o_spl_left) = o_split->get_container( row = 1 column = 1 ).
  DATA(o_spl_right) = o_split->get_container( row = 1 column = 2 ).

  TRY.
* Tree-Objekt erzeugen
      DATA(o_tree) = NEW cl_gui_simple_tree( parent = o_spl_left
                                             node_selection_mode = cl_gui_simple_tree=>node_sel_mode_single ).


* Eventtypten müssen gesondert registriert werden
      DATA(it_events) = VALUE ty_it_events( ( eventid = cl_gui_simple_tree=>eventid_node_keypress
                                              appl_event = abap_true )
                                            ( eventid = cl_gui_simple_tree=>eventid_selection_changed
                                              appl_event = abap_true )
                                            ( eventid = cl_gui_simple_tree=>eventid_expand_no_children
                                              appl_event = abap_true ) ).

      o_tree->set_registered_events( events = it_events ).

      o_tree->add_key_stroke( cl_gui_simple_tree=>key_enter ).

* Events registrieren
      SET HANDLER lcl_events=>on_keypress FOR o_tree.
      SET HANDLER lcl_events=>on_selection_changed FOR o_tree.
      SET HANDLER lcl_events=>on_expand_no_children FOR o_tree.

* Root-Node einfügen
      it_nodes = VALUE #( ( node_key  = 'ROOT'           " Node-Bezeichner
                            relatship = cl_gui_simple_tree=>relat_last_child
                            disabled  = abap_true
                            isfolder  = abap_true        " Typ Ordner für Root-Element
                            n_image   = icon_folder      " Icon Ordner
                            exp_image = icon_open_folder " Icon geöffneter Ordner
                            style     = cl_gui_simple_tree=>style_default
                            text      = 'Airlines' ) ).

* Childs an Root-Node anhängen
      LOOP AT it_tree_spfli ASSIGNING FIELD-SYMBOL(<fs_line>).
* bei Änderung der carrid neue carrid als Child anhängen
        AT NEW carrid.
          APPEND VALUE #( node_key  = |NODE{ sy-tabix }| " eindeutiger Node-Bezeichner
                          relatship = cl_gui_simple_tree=>relat_last_child
                          relatkey  = 'ROOT'             " an ROOT-Element anhängen
                          style     = cl_gui_simple_tree=>style_intensified
                          text      = |{ <fs_line>-carrid }| ) TO it_nodes.
        ENDAT.
      ENDLOOP.

* Nodes im Baum einfügen
      o_tree->add_nodes( table_structure_name = 'MTREESNODE' " Typ muss gleich mit Zeilentyp von ty_it_nodes sein
                         node_table           = it_nodes ).

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

* leeres SALV-Grid erzeugen
      cl_salv_table=>factory( EXPORTING
                                r_container    = o_spl_right
                              IMPORTING
                                r_salv_table   = o_salv
                              CHANGING
                                t_table        = it_salv_spfli ).

      o_salv->get_display_settings( )->set_striped_pattern( abap_true ).
      o_salv->get_columns( )->set_optimize( abap_true ).
      o_salv->get_functions( )->set_all( ).
      o_salv->get_selections( )->set_selection_mode( if_salv_c_selection_mode=>row_column ).
      o_salv->display( ).

* Trick: Aus dem Split-Container rechts das Grid-Objekt holen und nach cl_gui_alv_grid casten
      READ TABLE o_spl_right->children INDEX 1 ASSIGNING FIELD-SYMBOL(<child>).
      IF <child> IS ASSIGNED.
        DATA(o_alv_grid) = CAST cl_gui_alv_grid( <child> ).

* Eventhandler registrieren
        SET HANDLER lcl_events=>on_toolbar FOR o_alv_grid.
        SET HANDLER lcl_events=>on_user_command FOR o_alv_grid.
      ENDIF.

    CATCH cx_root INTO DATA(e_text).
      WRITE: / e_text->get_text( ).
  ENDTRY.

* leere Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

* cl_gui_container=>screen0 erzwingen
  WRITE space.

[ABAP] Baumstruktur mit Hilfe des cl_gui_simple_tree anzeigen, Events abfangen

* Demoprogramme
* RSDEMO_DRAG_DROP_EDIT_TREE
* RSDEMO_DRAG_DROP_TREE_MULTI
* SAPSIMPLE_TREE_CONTROL_DEMO

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

DATA: it_nodes TYPE ty_it_nodes.

CLASS lcl_event DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS: on_keypress FOR EVENT node_keypress OF cl_gui_simple_tree
      IMPORTING
          node_key
          key
          sender.
    CLASS-METHODS: on_double_click FOR EVENT node_double_click OF cl_gui_simple_tree
      IMPORTING
          node_key
          sender.
    CLASS-METHODS: on_selection_changed FOR EVENT selection_changed OF cl_gui_simple_tree
      IMPORTING
          node_key
          sender.
    CLASS-METHODS: on_expand_no_children FOR EVENT expand_no_children OF cl_gui_simple_tree
      IMPORTING
          node_key
          sender.
ENDCLASS.

CLASS lcl_event IMPLEMENTATION.
* Tastendruck, die Tasten müssen mit add_key_stroke( ) registriert worden sein
  METHOD on_keypress.
    WRITE: / |Node: { node_key } Taste: { key }|.
  ENDMETHOD.
* Doppelklick auf ein aktives Baumelement
  METHOD on_double_click.
* Text in der Nodes-Tabelle anpassen
    ASSIGN it_nodes[ node_key = node_key ] TO FIELD-SYMBOL(<fs_node>).
    <fs_node>-text = 'Schonmal geklickt.'.

* Text in der Node anpassen
    sender->node_set_text( node_key = node_key text = <fs_node>-text ).

    WRITE: / |Node: { node_key }, Text: { <fs_node>-text }|.
  ENDMETHOD.
* Klick auf ein aktives Baumelement
  METHOD on_selection_changed.
    WRITE: / |Node: { node_key }|.
  ENDMETHOD.
* bei Expandierung eines Baumelements ohne Unterelemente
  METHOD on_expand_no_children.
    WRITE: / |Node: { node_key }|.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

* Container-Objekt erzeugen
  DATA(o_dock) = NEW cl_gui_docking_container( no_autodef_progid_dynnr = abap_true
                                               side = cl_gui_docking_container=>dock_at_left
                                               ratio = 15
                                               caption = 'Datenausgabe' ).

* Tree-Objekt erzeugen
  DATA(o_tree) = NEW cl_gui_simple_tree( parent = o_dock
                                         node_selection_mode = cl_gui_simple_tree=>node_sel_mode_single ).

* Eventtypten müssen gesondert registriert werden
  DATA(it_events) = VALUE ty_it_events( ( eventid = cl_gui_simple_tree=>eventid_node_keypress )
*                                        ( eventid = cl_gui_simple_tree=>eventid_node_double_click )
                                        ( eventid = cl_gui_simple_tree=>eventid_selection_changed )
                                        ( eventid = cl_gui_simple_tree=>eventid_expand_no_children
                                          appl_event = abap_true ) ).

  o_tree->set_registered_events( events = it_events ).

* benötigte Tasten registrieren
*cl_gui_simple_tree=>key_f1: F1
*cl_gui_simple_tree=>key_f4: F4
*cl_gui_simple_tree=>key_insert: Einfügen
*cl_gui_simple_tree=>key_delete: Entfernen
*cl_gui_simple_tree=>key_enter: Enter
*cl_gui_simple_tree=>key_cut: Strg+X
*cl_gui_simple_tree=>key_copy: Strg+C
*cl_gui_simple_tree=>key_paste: Strg+V

  o_tree->add_key_stroke( cl_gui_simple_tree=>key_enter ).
  o_tree->add_key_stroke( cl_gui_simple_tree=>key_f1 ).
  o_tree->add_key_stroke( cl_gui_simple_tree=>key_delete ).

* Events registrieren, on_double_click und on_selection_changed
* dürfen nicht gleichzeitig registriert sein, sonst Exception
  SET HANDLER lcl_event=>on_keypress FOR o_tree.
*  SET HANDLER lcl_event=>on_double_click FOR o_tree.
  SET HANDLER lcl_event=>on_selection_changed FOR o_tree.
  SET HANDLER lcl_event=>on_expand_no_children FOR o_tree.

* Tree-Nodes einfügen -> die Bezeichner müssen eindeutig sein
  it_nodes = VALUE #( ( node_key  = 'FLDR1'
                        relatship = cl_gui_simple_tree=>relat_last_child
                        disabled  = abap_true
                        isfolder  = abap_true
                        n_image   = icon_folder
                        exp_image = icon_open_folder
                        style     = cl_gui_simple_tree=>style_default
                        text      = 'Ordner' )

                      ( node_key  = 'NODE1'
                        relatship = cl_gui_simple_tree=>relat_last_child
                        disabled  = abap_true
                        isfolder  = abap_true
                        relatkey  = 'FLDR1'
                        n_image   = icon_folder
                        exp_image = icon_open_folder
                        style     = cl_gui_simple_tree=>style_intensified
                        text      = 'Datensatz 1' )

                      ( node_key  = 'NODE1_1'
                        relatship = cl_gui_simple_tree=>relat_last_child
                        isfolder  = abap_false
                        relatkey  = 'NODE1'
                        n_image   = icon_led_yellow
                        style     = cl_gui_simple_tree=>style_intensified
                        text      = 'Datensatz 1_1' )

                      ( node_key  = 'NODE2'
                        relatship = cl_gui_simple_tree=>relat_last_child
                        isfolder  = abap_false
                        relatkey  = 'FLDR1'
                        n_image   = icon_led_green
                        style     = cl_gui_simple_tree=>style_default
                        text      = 'Datensatz 2' )

                      ( node_key  = 'NODE3'
                        relatship = cl_gui_simple_tree=>relat_last_child
                        isfolder  = abap_false
                        relatkey  = 'FLDR1'
                        disabled  = abap_true
                        n_image   = icon_led_inactive
                        style     = cl_gui_simple_tree=>style_inactive
                        text      = 'Datensatz 3 (inaktiv)' )

                      ( node_key  = 'NODE4'
                        relatship = cl_gui_simple_tree=>relat_last_child
                        isfolder  = abap_false
                        relatkey  = 'FLDR1'
                        disabled  = abap_false
                        n_image   = icon_led_red
                        style     = cl_gui_simple_tree=>style_intensifd_critical
                        text      = 'Datensatz 4' ) ).

  o_tree->add_nodes( table_structure_name = 'MTREESNODE' " Typ muss gleich mit Zeilentyp von ty_it_nodes sein
                     node_table           = it_nodes ).

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

* leere Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

  WRITE space. " wichtig für Erzwingung der Listenausgabe und Anzeige des Trees

Weiterführende Infos: Link und Link

[ABAP] SALV-Table: Hilfsklasse zur Ermittlung der Referenz auf ALV-Table (cl_gui_alv_grid) einer SALV-Table (cl_salv_table)

bis SAP-Realease 754: Hilfsklasse lcl_salv_helper abgeleitet von cl_salv_model_base

* bis SAP-Realease 754
* https://zevolving.com/2015/06/salv-table-20-editable-yes-as-per-this-standard-sap-application/

CLASS lcl_salv_helper DEFINITION INHERITING FROM cl_salv_model_base.
  PUBLIC SECTION.

    CLASS-METHODS:
      get_alv_from_salv
        IMPORTING
          io_model       TYPE REF TO cl_salv_model
        RETURNING
          VALUE(ro_grid) TYPE REF TO cl_gui_alv_grid.
ENDCLASS.

CLASS lcl_salv_helper IMPLEMENTATION.
*---------------------------------------------------------------------*
* Wandelt eine Referenz auf cl_salv_table in ein cl_gui_alv_grid um.
* Funktioniert nur, wenn SALV-Table schon mit display( ) angezeigt
* wurde, d.h. schon ein Container dafür erzeugt wurde. Andernfalls ist
* r_adapter INITIAL.
*---------------------------------------------------------------------*
* -> io_model - Referenz auf cl_salv_table (cl_salv_model)
* <- ro_grid  - Referenz auf cl_gui_alv_grid, bei Fehler INITIAL
*---------------------------------------------------------------------*
  METHOD get_alv_from_salv.
  
* wenn Typ 'Table'
    IF io_model->model = if_salv_c_model=>table.
      TRY.
          IF abap_true = cl_wdy_wb_reflection_helper=>is_instance_of( object = io_model->r_controller->r_adapter
                                                                      type_name = 'CL_SALV_GRID_ADAPTER' ).
                                                                      
            DATA(o_grid_adap) = CAST cl_salv_grid_adapter( io_model->r_controller->r_adapter ).

            IF o_grid_adap IS BOUND.
              ro_grid = o_grid_adap->get_grid( ).
            ENDIF.
          ELSEIF abap_true = cl_wdy_wb_reflection_helper=>is_instance_of( object = io_model->r_controller->r_adapter
                                                                          type_name = 'CL_SALV_FULLSCREEN_ADAPTER' ).

            DATA(o_fs_adap) = CAST cl_salv_fullscreen_adapter( io_model->r_controller->r_adapter ).

            IF o_fs_adap IS BOUND.
              ro_grid = o_fs_adap->get_grid( ).
            ENDIF.
          ENDIF.
        CATCH cx_root.
      ENDTRY.
    ENDIF.
  ENDMETHOD.

ENDCLASS.

ab SAP-Release 755: Hilfsklasse lcl_salv_helper mit Nutzung des Interfaces if_salv_table_display_adapter

* ab SAP-Release 755
* SALV-Table: Hilfsklasse zur Ermittlung der Referenz auf ALV-Table (cl_gui_alv_grid) einer SALV-Table (cl_salv_table)
* ab SAP-Release 755 hat die Klasse CL_SALV_FULLSCREEN_ADAPTER keine Funktion get_grid( ) mehr
* somit muss das Coding ab SAP-Release 755 geändert werden
* Quellen:
* https://blogs.sap.com/2022/08/01/editable-cl_salv_table-after-release-756/
* https://tricktresor.de/blog/alv-grid-aus-salv-ermitteln-ab-release-7-55/

CLASS lcl_salv_helper DEFINITION INHERITING FROM cl_salv_model_base FINAL.
  PUBLIC SECTION.

    CLASS-METHODS:
      get_alv_from_salv
        IMPORTING
          io_salv_grid   TYPE REF TO cl_salv_table
        RETURNING
          VALUE(ro_grid) TYPE REF TO cl_gui_alv_grid.
ENDCLASS.

CLASS lcl_salv_helper IMPLEMENTATION.
*---------------------------------------------------------------------*
* Wandelt eine Referenz auf cl_salv_table in ein cl_gui_alv_grid um.
*---------------------------------------------------------------------*
* -> io_model - Referenz auf cl_salv_table (cl_salv_table)
* <- ro_grid  - Referenz auf cl_gui_alv_grid, bei Fehler INITIAL
*---------------------------------------------------------------------*
  METHOD get_alv_from_salv.

    IF io_salv_grid IS BOUND.

      TRY.
          DATA(o_model) = CAST cl_salv_model_base( io_salv_grid->extended_grid_api( ) ).

* Funktioniert nur, wenn SALV-Table schon mit display( ) angezeigt und
* somit schon ein Container dafür erzeugt wurde. Andernfalls ist r_adapter INITIAL.
          IF o_model->r_controller IS BOUND AND o_model->r_controller->r_adapter IS BOUND.

            IF o_model->r_controller->r_adapter IS INSTANCE OF if_salv_table_display_adapter.
              ro_grid = CAST if_salv_table_display_adapter( o_model->r_controller->r_adapter )->get_grid( ).
            ENDIF.

          ENDIF.

        CATCH cx_root.
      ENDTRY.

    ENDIF.

  ENDMETHOD.

ENDCLASS.

Anwendungsbeispiel

* Anwendungs-Beispiel
CLASS lcl_event DEFINITION.
  PUBLIC SECTION.
    CONSTANTS: co_btn_click TYPE string VALUE 'BTN_KLICK'.

    CLASS-METHODS: on_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
      IMPORTING
        e_object
        sender.
    CLASS-METHODS: on_user_command FOR EVENT user_command OF cl_gui_alv_grid
      IMPORTING
        e_ucomm
        sender.
ENDCLASS.

CLASS lcl_event IMPLEMENTATION.
* Toolbar-Buttons hinzufügen
  METHOD on_toolbar.
* Separator hinzufügen
    APPEND VALUE #( butn_type = cntb_btype_sep ) TO e_object->mt_toolbar.
* Edit-Button hinzufügen
    APPEND VALUE #( butn_type = cntb_btype_button
                    text = 'Klick!'
                    icon = icon_change_text
                    function = co_btn_click
                    quickinfo = 'Etwas ausgeben'
                    disabled = abap_false ) TO e_object->mt_toolbar.
  ENDMETHOD.

* User-Command
  METHOD on_user_command.
    CASE e_ucomm.
      WHEN co_btn_click.
        MESSAGE |Klick: { sender->m_guid }| TYPE 'I'.
    ENDCASE.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  TRY.
      DATA: o_salv TYPE REF TO cl_salv_table.

* Daten holen
      SELECT FROM t000
        FIELDS *
        INTO TABLE @DATA(it_t000).

      cl_salv_table=>factory( EXPORTING r_container  = cl_gui_container=>default_screen
                              IMPORTING r_salv_table = o_salv
                              CHANGING  t_table      = it_t000 ).

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

      o_salv->display( ).

* Referenz auf ALV-Grid holen
      DATA(o_alv_grid) = lcl_salv_helper=>get_alv_from_salv( o_salv ).

      IF o_alv_grid IS BOUND.
* Eventhandler des ALV-Grids registrieren
        SET HANDLER lcl_event=>on_toolbar FOR o_alv_grid.
        SET HANDLER lcl_event=>on_user_command FOR o_alv_grid.

* Toolbar-Buttons refreshen
        o_alv_grid->refresh_table_display( ).
      ENDIF.
    CATCH cx_root INTO DATA(e_text).
      WRITE: / e_text->get_text( ).
  ENDTRY.

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

* Ausgabe von cl_gui_container=>default_screen erzwingen
  WRITE space.

Links

[ABAP] SALV-Table: Anzeige in einem DockingContainer, Einfügen von Buttons und Eventhandling

Variante 1 (cl_gui_docking_container)

CLASS lcl_event DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS: handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
      IMPORTING e_object
                sender.
    CLASS-METHODS:
      handle_user_command FOR EVENT user_command OF cl_gui_alv_grid
        IMPORTING e_ucomm  " Benutzerkommando
                  sender.  " Sender
ENDCLASS.

CLASS lcl_event IMPLEMENTATION.
  METHOD handle_toolbar.
* Separator hinzufügen
    APPEND VALUE #( butn_type = 3 ) TO e_object->mt_toolbar.
* Print-Button hinzufügen
    APPEND VALUE #( butn_type = 5 text = 'Klick!' icon = icon_change_text function = 'PRINT_DATA' quickinfo = 'Etwas ausgeben' disabled = ' ' ) TO e_object->mt_toolbar.
  ENDMETHOD.

  METHOD handle_user_command.
* TypeCast auf Sender
    DATA: o_grid TYPE REF TO cl_gui_alv_grid.
    o_grid ?= sender.

    CASE e_ucomm.
* Daten speichern
      WHEN 'PRINT_DATA'.
        WRITE: / 'Klick: ', o_grid->m_guid.
    ENDCASE.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  DATA: it_data TYPE STANDARD TABLE OF t000.
  DATA: o_salv TYPE REF TO cl_salv_table.

* Daten holen
  SELECT *
    INTO TABLE it_data
    FROM t000.

  DATA(o_dock) = NEW cl_gui_docking_container( no_autodef_progid_dynnr = abap_true
                                               side = cl_gui_docking_container=>dock_at_top
*                                               style = cl_gui_container=>ws_visible + cl_gui_container=>ws_thickframe + cl_gui_container=>ws_child
                                               ratio = 90
                                               caption = 'Datenausgabe'
                                               name = 'CNT1' ).

* Datenanzeige
  TRY.
* Bei Angabe des Containers o_dock bleibt die Abarbeitung nach o_salv->display( ) nicht
* stehen, sondern läuft weiter und die Referenz auf das ALV-Grid kann geholt werden.
* Eine Anzeige des SALV-Grids erfolgt so aber nur, wenn eine Listenausgabe erfolgt, daher das WRITE space.
      cl_salv_table=>factory( EXPORTING
                                r_container    = o_dock
                              IMPORTING
                                r_salv_table   = o_salv
                              CHANGING
                                t_table        = it_data ).

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

* Trick: Aus dem Container das Grid-Objekt holen und nach cl_gui_alv_grid casten
      READ TABLE o_dock->children INDEX 1 ASSIGNING FIELD-SYMBOL(<child>).
      DATA(o_alv_grid) = CAST cl_gui_alv_grid( <child> ).

* Eventhandler registrieren
      SET HANDLER lcl_event=>handle_toolbar FOR o_alv_grid.
      SET HANDLER lcl_event=>handle_user_command FOR o_alv_grid.

* Anzeige neu aufbauen
      o_alv_grid->refresh_table_display( ).

    CATCH cx_root INTO DATA(e_text).
      WRITE: / e_text->get_text( ).
  ENDTRY.

* leere Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

  WRITE space. " wichtig für Erzwingung der Listenausgabe

Variante 2 (cl_gui_splitter_container)

CLASS lcl_event DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
        IMPORTING e_object
                    sender.
    CLASS-METHODS:
      handle_user_command FOR EVENT user_command OF cl_gui_alv_grid
        IMPORTING e_ucomm  " Benutzerkommando
                    sender.  " Sender
ENDCLASS.

CLASS lcl_event IMPLEMENTATION.
  METHOD handle_toolbar.
* Separator hinzufügen
    APPEND VALUE #( butn_type = 3 ) TO e_object->mt_toolbar.
* Edit-Button hinzufügen
    APPEND VALUE #( butn_type = 5 text = 'Klick!' icon = icon_change_text function = 'PRINT_DATA' quickinfo = 'Etwas ausgeben' disabled = ' ' ) TO e_object->mt_toolbar.
  ENDMETHOD.

  METHOD handle_user_command.
* TypeCast auf Sender
    DATA: o_grid TYPE REF TO cl_gui_alv_grid.
    o_grid ?= sender.

    CASE e_ucomm.
* Daten speichern
      WHEN 'PRINT_DATA'.
        WRITE: / 'Klick: ', o_grid->m_guid.
    ENDCASE.
  ENDMETHOD.

ENDCLASS.

START-OF-SELECTION.

  DATA: it_data TYPE STANDARD TABLE OF t000.
  DATA: o_salv TYPE REF TO cl_salv_table.

* Daten holen
  SELECT *
    INTO TABLE it_data
    FROM t000.

  DATA(o_split) = NEW cl_gui_splitter_container( parent = cl_gui_container=>default_screen
                                                 no_autodef_progid_dynnr = abap_true
                                                 rows = 1
                                                 columns = 2 ). " wenn columns = 1, dann FullScreen

* Referenz auf linken Container holen
  DATA(o_spl_left) = o_split->get_container( row = 1 column = 1 ).

* Datenanzeige
  TRY.
* Bei Angabe des Containers o_spl_left bleibt die Abarbeitung nach o_salv->display( ) nicht
* stehen, sondern läuft weiter und die Referenz auf das ALV-Grid kann geholt werden.
* Eine Anzeige des SALV-Grids erfolgt so aber nur, wenn eine Listenausgabe erfolgt, daher das WRITE space.
      cl_salv_table=>factory( EXPORTING
                                r_container    = o_spl_left
                              IMPORTING
                                r_salv_table   = o_salv
                              CHANGING
                                t_table        = it_data ).

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

* Trick: Aus dem Container das Grid-Objekt holen und nach cl_gui_alv_grid casten
      READ TABLE o_spl_left->children INDEX 1 ASSIGNING FIELD-SYMBOL(<child>).
      IF <child> IS ASSIGNED.
        DATA(o_alv_grid) = CAST cl_gui_alv_grid( <child> ).

* Eventhandler registrieren
        SET HANDLER lcl_event=>handle_toolbar FOR o_alv_grid.
        SET HANDLER lcl_event=>handle_user_command FOR o_alv_grid.

* Anzeige neu aufbauen
        o_alv_grid->refresh_table_display( ).
      ENDIF.
    CATCH cx_root INTO DATA(e_text).
      WRITE: / e_text->get_text( ).
  ENDTRY.

* leere Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

  WRITE space. " wichtig für Erzwingung der Listenausgabe 

Variante 3 (cl_gui_container=>screen0)

CLASS lcl_event DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS: handle_toolbar FOR EVENT toolbar OF cl_gui_alv_grid
      IMPORTING e_object
                sender.
    CLASS-METHODS:
      handle_user_command FOR EVENT user_command OF cl_gui_alv_grid
        IMPORTING e_ucomm  " Benutzerkommando
                  sender.  " Sender
ENDCLASS.

CLASS lcl_event IMPLEMENTATION.
  METHOD handle_toolbar.
* Separator hinzufügen
    APPEND VALUE #( butn_type = 3 ) TO e_object->mt_toolbar.
* Print-Button hinzufügen
    APPEND VALUE #( butn_type = 5 text = 'Klick!' icon = icon_change_text function = 'PRINT_DATA' quickinfo = 'Etwas ausgeben' disabled = ' ' ) TO e_object->mt_toolbar.
  ENDMETHOD.

  METHOD handle_user_command.
* TypeCast auf Sender
    DATA: o_grid TYPE REF TO cl_gui_alv_grid.
    o_grid ?= sender.

    CASE e_ucomm.
* Daten speichern
      WHEN 'PRINT_DATA'.
        WRITE: / 'Klick: ', o_grid->m_guid.
    ENDCASE.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  DATA: it_data TYPE STANDARD TABLE OF t000.
  DATA: o_salv TYPE REF TO cl_salv_table.

* Daten holen
  SELECT *
    INTO TABLE it_data
    FROM t000.

* Datenanzeige
  TRY.
* Bei Angabe des Containers cl_gui_container=>screen0 bleibt die Abarbeitung nach o_salv->display( ) nicht
* stehen, sondern läuft weiter und die Referenz auf das ALV-Grid kann geholt werden.
* Eine Anzeige des SALV-Grids erfolgt so aber nur, wenn eine Listenausgabe erfolgt, daher das WRITE space.
      cl_salv_table=>factory( EXPORTING
                                r_container    = cl_gui_container=>screen0
                              IMPORTING
                                r_salv_table   = o_salv
                              CHANGING
                                t_table        = it_data ).

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

* Trick: Aus dem Container das Grid-Objekt holen und nach cl_gui_alv_grid casten
      READ TABLE cl_gui_container=>screen0->children INDEX 1 ASSIGNING FIELD-SYMBOL(<child>).
      DATA(o_alv_grid) = CAST cl_gui_alv_grid( <child> ).

* Eventhandler registrieren
      SET HANDLER lcl_event=>handle_toolbar FOR o_alv_grid.
      SET HANDLER lcl_event=>handle_user_command FOR o_alv_grid.

* Anzeige neu aufbauen
      o_alv_grid->refresh_table_display( ).

    CATCH cx_root INTO DATA(e_text).
      WRITE: / e_text->get_text( ).
  ENDTRY.

* leere Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

  WRITE space. " wichtig für Erzwingung der Listenausgabe

[ABAP] ALV-Grid ohne Dynpro – Daten anzeigen, editieren und als CSV-Datei speichern

DATA: it_mara TYPE STANDARD TABLE OF mara.

CLASS lcl_events DEFINITION.

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

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

    CLASS-METHODS: on_user_command FOR EVENT user_command OF cl_gui_alv_grid
      IMPORTING
        e_ucomm
        sender.
ENDCLASS.

CLASS lcl_events IMPLEMENTATION.
* Toolbar-Buttons hinzufügen:
* butn_type   Bezeichung
* 0           Button (normal)
* 1           Menü + Defaultbutton
* 2           Menü
* 3           Separator
* 4           Radiobutton
* 5           Auswahlknopf (Checkbox)
* 6           Menüeintrag
  METHOD on_toolbar.
* Separator hinzufügen
    APPEND VALUE #( butn_type = 3 ) TO e_object->mt_toolbar.
* Edit-Button hinzufügen
    APPEND VALUE #( butn_type = 5 text = 'Edit' icon = icon_change_text function = 'EDIT_DATA' quickinfo = 'Editieren' disabled = ' ' ) TO e_object->mt_toolbar.
* Speichern-Button hinzufügen
    APPEND VALUE #( butn_type = 5 text = 'Speichern' icon = icon_system_save function = 'SAVE_DATA' quickinfo = 'Speichern' disabled = ' ' ) TO e_object->mt_toolbar.
  ENDMETHOD.

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

        IF <f> IS ASSIGNED.
* Änderungswert in die Zelle der iTab (it_mara) rückschreiben
          <f> = <c>-value.
        ENDIF.
      ENDIF.
    ENDLOOP.

  ENDMETHOD.
* Benutzerkommandos behandeln
  METHOD on_user_command.
    CASE e_ucomm.
* Daten speichern
      WHEN 'SAVE_DATA'.
        DATA: lv_action TYPE i.
        DATA: lv_filename TYPE string.
        DATA: lv_fullpath TYPE string.
        DATA: lv_path TYPE string.
* FileSave-Dialog aufrufen
        TRY.
            cl_gui_frontend_services=>file_save_dialog( EXPORTING
                                                          default_extension   = 'txt'
                                                          file_filter         = |TXT (*.txt)\|*.txt\|{ cl_gui_frontend_services=>filetype_all }|
                                                          prompt_on_overwrite = abap_true
                                                        CHANGING
                                                          filename            = lv_filename     " Dateiname
                                                          path                = lv_path         " Pfad
                                                          fullpath            = lv_fullpath     " Pfad + Dateiname
                                                          user_action         = lv_action ).    " Benutzeraktion

            IF lv_action EQ cl_gui_frontend_services=>action_ok.
* iTab nach CSV konvertieren und speichern
              cl_icf_csv=>request_for_write_into_csv( it_data            = it_mara
                                                      iv_hdr_struct_name = 'MARA'
                                                      iv_init_dir        = lv_path
                                                      iv_file_name       = lv_filename ).

              MESSAGE 'Daten erfolgreich gespeichert.' TYPE 'I'.
            ENDIF.

          CATCH cx_root INTO DATA(e_text).          " Oberklasse für Exceptions abfangen und Kurztext übergeben
            MESSAGE e_text->get_text( ) TYPE 'I'.   " Exception Kurztext ausgeben
        ENDTRY.

* Editmodus umschalten
      WHEN 'EDIT_DATA'.
        DATA: it_fcat TYPE lvc_t_fcat.
        DATA: lv_edit TYPE abap_bool VALUE abap_false.

* Feldkatalog holen
        sender->get_frontend_fieldcatalog( IMPORTING
                                             et_fieldcatalog = it_fcat ).

        IF lines( it_fcat ) > 0.
          lv_edit = it_fcat[ 1 ]-edit.
        ENDIF.

        CASE lv_edit.
          WHEN abap_true.
            lv_edit = abap_false.
          WHEN OTHERS.
            lv_edit = abap_true.
        ENDCASE.

* im Feldkatalog alle Zellen des ALV-Grids auf editierbar stellen
        LOOP AT it_fcat ASSIGNING FIELD-SYMBOL(<fcat>).
          <fcat>-edit = lv_edit.
        ENDLOOP.

* Feldkatalog zurückgeben
        sender->set_table_for_first_display( CHANGING
                                              it_fieldcatalog = it_fcat
                                              it_outtab = it_mara ).
    ENDCASE.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.

  SELECT * FROM mara INTO TABLE it_mara UP TO 100 ROWS.

  DATA(o_alv) = NEW cl_gui_alv_grid( 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.
  SET HANDLER lcl_events=>on_user_command FOR o_alv.

  o_alv->register_edit_event( i_event_id = cl_gui_alv_grid=>mc_evt_enter ).

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

  DATA(lv_layout) = VALUE lvc_s_layo( zebra = abap_true
                                      cwidth_opt = 'A'
                                      grid_title = 'Editierbares ALV-Gitter ohne extra Dynpro' ).

  o_alv->set_table_for_first_display( EXPORTING
                                        i_bypassing_buffer = abap_true
                                        i_save             = 'A'
                                        is_layout          = lv_layout
                                        i_structure_name   = 'MARA'
                                      CHANGING
                                        it_outtab        = it_mara ).

  cl_gui_alv_grid=>set_focus( control = o_alv ).

  cl_gui_cfw=>flush( ).

* leere Toolbar ausblenden
  cl_abap_list_layout=>suppress_toolbar( ).

* Listenausgabe für cl_gui_container=>default_screen erzwingen
  WRITE: space.

[ABAP] Nutzung der Google-Chart-API zur Anzeige von Charts

* Beispiel adaptiert von:
* http://www.tricktresor.de/blog/sap-und-bunte-bilder-cl_gui_html_viewer/

DATA: lv_s032 TYPE s032.
SELECT-OPTIONS: so_werks FOR lv_s032-werks.

START-OF-SELECTION.

* Alle Bestände je Werk aus der S032 summieren
  SELECT werks,                    " Werk
         SUM( wbwbest ) AS wbwbest " Summe Wert Bewerteter Bestand
    INTO TABLE @DATA(it_data)
    FROM s032
      WHERE werks IN @so_werks
        AND vrsio = '000'
      GROUP BY werks.

* HTML-Code erzeugen
  DATA(it_html) = VALUE html_table(
                                    ( |<html>| )
                                    ( |  <head>| )
                                    ( |    <script type="text/javascript" src="https://www.google.com/jsapi"></script>| )
                                    ( |    <script type="text/javascript">| )
                                    ( |      google.load("visualization", "1", \{packages:["corechart"]\});| )
                                    ( |      google.setOnLoadCallback(drawChart);| )
                                    ( |      function drawChart() \{| )
                                    ( |        var data = google.visualization.arrayToDataTable([ ['Werk', 'Bestand'],| )
                                  ).

* Daten aus der iTab in den Code einfügen
  DATA(lv_html) = ||.

  LOOP AT it_data ASSIGNING FIELD-SYMBOL(<d>).
    IF lv_html IS INITIAL.
      lv_html = |        ['{ <d>-werks }', { <d>-wbwbest }]|.
    ELSE.
      lv_html = |        ,['{ <d>-werks }', { <d>-wbwbest }]|.
    ENDIF.

    APPEND lv_html TO it_html.
  ENDLOOP.

* Code abschließen
  it_html = VALUE html_table( BASE it_html
                              ( |        ]);| )
                              ( |        var options = \{title: 'Summe bewertete Bestände pro Werk'\};| )
                              ( |        var chart = new google.visualization.PieChart(document.getElementById('piechart'));| )
                              ( |        chart.draw(data, options);| )
                              ( |      \};| )
                              ( |    </script>| )
                              ( |  </head>| )
                              ( |  <body>| )
                              ( |    <div id="piechart" style="width: 900px; height: 500px;"></div>| )
                              ( |  </body>| )
                              ( |</html>| )
                            ).

* HTML-Viewer
  DATA(o_html) = NEW cl_gui_html_viewer( parent = cl_gui_container=>default_screen ).

* URL zu HTML holen
  DATA: lv_url TYPE swk_url.

  o_html->load_data( IMPORTING
                       assigned_url = lv_url
                     CHANGING
                       data_table   = it_html ).

* HTML anzeigen
  o_html->show_url( url = lv_url ).

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

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

[ABAP] Anzeige der Toolbar unterdrücken / ausschalten

Variante 1 (cl_abap_list_layout)

PARAMETERS: p_matnr TYPE matnr.

AT SELECTION-SCREEN OUTPUT.
* Unterdrückt die Applikationszeile auf dem Listdynpro
  cl_abap_list_layout=>suppress_toolbar( ).

START-OF-SELECTION.
  WRITE: / p_matnr.

Variante 2 (RPY_DYNPRO_READ, RPY_DYNPRO_INSERT)

PARAMETERS: p_matnr TYPE matnr.

AT SELECTION-SCREEN OUTPUT.

  DATA: lv_header               TYPE rpy_dyhead.
  DATA: it_containers           TYPE dycatt_tab.
  DATA: it_fields_to_containers TYPE dyfatc_tab.
  DATA: it_flow_logic           TYPE swydyflow.

* Lesen eines Dynpros
  CALL FUNCTION 'RPY_DYNPRO_READ'
    EXPORTING
      progname             = sy-cprog
      dynnr                = sy-dynnr
    IMPORTING
      header               = lv_header
    TABLES
      containers           = it_containers
      fields_to_containers = it_fields_to_containers
      flow_logic           = it_flow_logic
    EXCEPTIONS
      cancelled            = 1
      not_found            = 2
      permission_error     = 3
      OTHERS               = 4.

  IF sy-subrc = 0.
* Anzeige der Toolbar prüfen
    IF lv_header-no_toolbar = abap_false.
      lv_header-no_toolbar = abap_true.

* Einfügen eines Dynpros
      CALL FUNCTION 'RPY_DYNPRO_INSERT'
        EXPORTING
          header                 = lv_header
          suppress_exist_checks  = abap_true
        TABLES
          containers             = it_containers
          fields_to_containers   = it_fields_to_containers
          flow_logic             = it_flow_logic
        EXCEPTIONS
          cancelled              = 1
          already_exists         = 2
          program_not_exists     = 3
          not_executed           = 4
          missing_required_field = 5
          illegal_field_value    = 6
          field_not_allowed      = 7
          not_generated          = 8
          illegal_field_position = 9
          OTHERS                 = 10.
    ENDIF.
  ENDIF.

START-OF-SELECTION.
  WRITE: / p_matnr.