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

1. Hilfsklasse lcl_salv_helper abgeleitet von cl_salv_model_base

* Klasse
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 und
*& somit 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.

2. Anwendungsbeispiel

CLASS lcl_event DEFINITION.
  PUBLIC SECTION.
    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.
  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 = 'Klick!' icon = icon_change_text function = 'PRINT_DATA' quickinfo = 'Etwas ausgeben' disabled = ' ' ) TO e_object->mt_toolbar.
  ENDMETHOD.

  METHOD on_user_command.
    CASE e_ucomm.
* Daten speichern
      WHEN 'PRINT_DATA'.
        WRITE: / 'Klick: ', sender->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.
* cl_gui_container=>screen0 wird aber nur erzeugt, 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( ).

* 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.
      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 und damit Generierung von cl_gui_container=>screen0

Weiterführende Infos: Link