ALV-Grid Tabelle direkt ändern

Bei einem ALV-Grid wird die anzuzeigende Datentabelle der Methode SET_TABLE_FOR_FIRST_DISPLAY mitgegeben. Eine Änderung kann eigentlich nur aus der aufrufenden Klasse oder im Ereignis DATA_CHANGED erfolgen. Wird die Datentabelle im Programm geändert, so muss die Methode REFRESH_TABLE_DISPLAY aufgerufen werden, damit die Änderungen auch im Frontend angezeigt werden.

In einigen Fällen kann es jedoch erforderlich sein, die Daten von außen zu ändern. Dies ist jedoch nicht möglich, da das Attribut MT_OUTTAB, das die Datenreferenz zur Datentabelle hält, geschützt (protected) ist. Zudem werden die folgenden beiden öffentlichen Methoden, die es ermöglichen könnten, die Daten zu ändern, nicht unterstützt:

  • SET_DATA_CELLS
  • CHANGE_DATA_FROM_INSIDE

Wenn ich diese verwende, erhalte ich den Shortdump ASSERTION_FAILED in Klasse CL_DATAPTABLECACHE.

Glücklicherweise gibt es das If you wanna be my lover – Das FRIENDS-Konzept. Das können wir uns zunutze machen, indem wir die ALV-Grid-Instanz an eine Klasse übergeben, die mit CL_GUI_ALV_GRID befreundet ist und uns die Datenreferenz von MT_OUTTAB zurückgeben lassen.

Friends-Klasse

CLASS alv_data DEFINITION.
  PUBLIC SECTION.
    INTERFACES if_alv_rm_grid_friend .
    CLASS-METHODS get_outtab
      IMPORTING
        ir_grid          TYPE REF TO cl_gui_alv_grid
      RETURNING
        VALUE(ro_outtab) TYPE REF TO data.

ENDCLASS.

CLASS alv_data IMPLEMENTATION.
  METHOD get_outtab.
    ro_outtab = ir_grid->mt_outtab.
  ENDMETHOD.
ENDCLASS.

Nutzung

Wenn wir also die Instanz eines ALV-Grids haben, dann können wir dieses an die Klasse ALV_DATA=>GET_OUTTAB übergeben und erhalten eine nutzbare Datenreferenz. Diese Datenreferenz können wir zu einem Feldsymbol zuweisen:

DATA(my_outtab) = alv_data=>get_outtab( my_grid ).
FIELD-SYMBOLS <outtab> TYPE TABLE.
ASSIGN my_outtab->* TO <outtab>.

Anwendungsbeispiel “Navigationsprofil”

Wenn du dich bisher gefragt hast, wo zum Geier man sowas machen wollen würde, dann schau dir dieses Beispiel an. Es gibt die Funktionalität Navigationsprofil. Mit dieser Funktionalität kannst du ein ALV-Grid erweitern und modifikationsfrei Funktionalitäten hinzufügen. Das kann zum Beispiel durch eine Klasse erfolgen, die das Interface IF_NAVIGATION_PROFILE implementiert. In der Methode USER_COMMAND werden eine Referenz auf die Daten und die Instanz des ALV-Grid übergeben. mit GET_SELECTED_ROWS ist es dann möglich, ausgewählte Zeilen zu ermitteln und aufgrund dieser eine andere Funktionalität aufzurufen.

Allerdings ist es nicht möglich, die Daten selbst zu ändern. Es sei denn, du verwendest den oben genannten Trick.

Wie das Beispiel im Detail funktioniert, kannst du mit dem Demoprogramm NAVP_DEMO_TABLE nachvollziehen. Hierzu musst du das Navigationsprofil ändern und einen Button hinzufügen. Wie genau das geht, kannst du hier erfahren.

Zuerst benötigst du jedoch eine Klasse, die die Datenänderungen vornimmt.

CLASS zcl_navigation_profile_enno DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    INTERFACES if_navigation_profile .
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.



CLASS ZCL_NAVIGATION_PROFILE_ENNO IMPLEMENTATION.


* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method ZCL_NAVIGATION_PROFILE_ENNO->IF_NAVIGATION_PROFILE~USER_COMMAND
* +-------------------------------------------------------------------------------------------------+
* | [--->] IO_ALV                         TYPE REF TO OBJECT
* | [--->] ID_TABLE                       TYPE REF TO DATA
* | [--->] IS_PROFILE_KEY                 TYPE        NAVP_S_PROFILE_KEY
* | [--->] IV_PARAMETER                   TYPE        NAVP_FUNCTION_PARAMETER
* +--------------------------------------------------------------------------------------</SIGNATURE>
  METHOD if_navigation_profile~user_command.
    DATA outtab TYPE REF TO data.
    FIELD-SYMBOLS <table> TYPE table.

    DATA(alv) = CAST cl_gui_alv_grid( io_alv ).
    outtab = lcl_data=>get_outtab( alv ).
    ASSIGN outtab->* TO <table>.

    DATA lt_delta TYPE lvc_t_modi.

    alv->get_selected_rows( IMPORTING et_row_no = DATA(lt_row_no) ).

    LOOP AT lt_row_no INTO DATA(ls_row).
      ASSIGN <table>[ ls_row-row_id ] TO FIELD-SYMBOL(<line>).
      ASSIGN COMPONENT 'FLDATE' OF STRUCTURE <line> TO FIELD-SYMBOL(<fldate>).
      <fldate> = sy-datum.
    ENDLOOP.

    FIELD-SYMBOLS <outtab> TYPE table.

    alv->refresh_table_display(
      i_soft_refresh = abap_true
      is_stable      = VALUE #( row = abap_true col = abap_true ) ).

    alv->set_selected_rows( it_row_no = lt_row_no ).

  ENDMETHOD.
ENDCLASS.

Danach kannst du die neue Drucktaste anlegen:

Drucktaste “Set Date”

Die Drucktaste wird nun – modifikationsfrei – in der Toolbar angezeigt:

Wenn du Einträge markierst und die Drucktaste drückst, dann wird das Flugdatum der markierten Einträge auf das Tagesdatum gesetzt.

Enno Wulff