Kontextmenü im ALV-basierten Kontenstand
,
Im klassischen, textbasierten FS-CD Kontenstand gibt es ein praktisches Kontextmenü mit den wichtigsten Befehlen. Leider gibt es im ALV-basierten Kontenstand dieses Kontextmenü nicht. In diesem Blogpost zeige ich, wie dieses Kontextmenü einfach nachgerüstet werden kann.
Der FS-CD Kontenstand wurde von SAP in der Funktionsgruppe FKL9 implementiert. Weil die Datenobjekte, auf die wir Zugriff benötigen, als globale Variablen im TOP-Include dieser Funktionsgruppe definiert wurden, können wir mittels externer Assigns auf sie zugreifen.
Die Lösung besteht aus einem Funktionsbaustein, der zum Zeitpunkt 1205 von FS-CD aufgerufen werden soll, und einer lokalen Klasse, die in der gleichen Funktionsgruppe abgelegt werden sollte (alternativ geht natürlich auch eine globale Klasse).
Definition der lokalen Klasse
Diese Klasse registriert sich für die Ereignisse CONTEXT_MENU_REQUEST
und USER_COMMAND
das ALV-basierten Kontenstand der Transaktion FPL9 und reagiert auf diese Ereignisse, wenn sie ausgelöst werden. Das Ereignis CONTEXT_MENU_REQUEST
wird ausgelöst, wenn der Anwender die rechte Maustaste betätigt. In diesem Ereignis besteht die Möglichkeit, die Kontextmenü-Einträge zu erstellen. Wenn der Anwender einen Befehl aus dem Kontextmenü auswählt, können wir die passende Funktionalität im Ereignishandler für USER_COMMAND
auslösen.
CLASS lcl_event_listener DEFINITION. PUBLIC SECTION. CLASS-METHODS subscribe. PRIVATE SECTION. CLASS-METHODS on_context_menu_request FOR EVENT context_menu_request 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. CLASS-METHODS get_current_item IMPORTING value(io_alv) TYPE REF TO cl_gui_alv_grid RETURNING value(rs_item) TYPE fkkepos. ENDCLASS.
Ereignisse registrieren
Diese Methode wird aus dem Funktionsbaustein für den Zeitpunkt 1205 aufgerufen und registriert sich beim ALV-Grid-Control des Kontenstands für die beiden Ereignisse. Da das ALV-Grid-Control beim ersten Aufruf des Zeitpunkts 1205 noch gar nicht erzeugt wurde, machen wir das an dieser Stelle mittels eines externen Performs.
METHOD subscribe. FIELD-SYMBOLS <o_alv> TYPE REF TO cl_gui_alv_grid. " ALV-Grid bereits jetzt erzeugen PERFORM grid_pbo_311 IN PROGRAM saplfkl9. " Referenz auf ALV-Grid ermitteln ASSIGN ('(SAPLFKL9)GR_ALV_GRID_0311') TO <o_alv>. IF <o_alv> IS NOT ASSIGNED OR <o_alv> IS NOT BOUND. RETURN. ENDIF. " Eventhandler registrieren SET HANDLER on_context_menu_request FOR <o_alv>. SET HANDLER on_user_command FOR <o_alv>. ENDMETHOD.
Kontextmenü aufbauen
In dieser Methode wird das Kontext-abhängige Menü aufgebaut. Mit einer Hilfsmethode wird die aktuelle Zeile des Kontenstands ermittelt. Abhängig von der Herkunft des Belegs und dem Ausgleichsstatus des Postens werden Einträge im Kontextmenü ergänzt. Der Aufbau orientiert sich dabei am gewohnten Kontextmenü des klassischen Kontenstands.
METHOD on_context_menu_request. DATA(ls_item) = get_current_item( sender ). IF ls_item IS INITIAL. RETURN. " kein Kontextmenü für Zeilen mit ALV-Zwischensummen ENDIF. " Herkunftsschlüssel ermitteln SELECT SINGLE herkf FROM dfkkko WHERE opbel = @ls_item-opbel INTO @DATA(lv_source). " Kontextmenü ergänzen (vgl. FuGr FKL9, FORM on_ctmenu_request) e_object->add_separator( ). IF lv_source = '12'. e_object->add_function( fcode = 'INST' text = 'Ratenplan'(001) ). e_object->add_function( fcode = 'RATP' text = 'Ursprungsposten'(002) ). ELSE. e_object->add_function( fcode = 'BELG' text = 'Position anzeigen'(003) ). e_object->add_function( fcode = 'FPE2' text = 'Position ändern'(004) ). e_object->add_function( fcode = 'FP08' text = 'Stornieren'(005) ). IF ls_item-augst IS NOT INITIAL. e_object->add_function( fcode = 'FP07' text = 'Ausgleich zurücknehmen'(006) ). ENDIF. ENDIF. e_object->add_function( fcode = 'BELZ' text = 'Zahlungen/Rückläufer'(007) ). e_object->add_function( fcode = 'DUNH' text = 'Mahnhistorie'(008) ). e_object->add_function( fcode = 'ZHIS' text = 'Zinshistorie'(009) ). e_object->add_separator( ). e_object->add_function( fcode = 'STMM' text = 'Geschäftspartner'(010) ). e_object->add_function( fcode = 'VKON' text = 'Vertragskonto'(011) ). e_object->add_function( fcode = '1201' text = 'Vertrag'(012) ). e_object->add_separator( ). e_object->add_function( fcode = 'FPE2M' text = 'Massenänderung'(013) ). e_object->add_function( fcode = 'FP06' text = 'Kontenpflege'(014) ). e_object->add_separator( ). CASE lv_source. WHEN '05'. e_object->add_function( fcode = 'BAZS' text = 'Zahlstapelposition'(015) ). WHEN '06'. e_object->add_function( fcode = 'BAZL' text = 'Zahllauf'(016) ). WHEN '08'. e_object->add_function( fcode = 'BARL' text = 'Rückläufer Detail'(017) ). ENDCASE. ENDMETHOD.
User-Command behandeln
Diese Methode wird aufgerufen, wenn der Anwender einen Befehl aus dem Kontextmenü ausgewählt hat. Wir lösen die gewünschte Funktion aus, indem wir den OK-Code an die Funktionsgruppe FKL9 per externem Assign weitergeben und einen externen Perform durchführen. Damit wird simuliert, dass der Anwender den Befehl über die Menüleiste aufgerufen hätte.
METHOD on_user_command. FIELD-SYMBOLS <v_ok_code> TYPE c. " User-Command an FPL9 weitergeben ASSIGN ('(SAPLFKL9)OK-CODE') TO <v_ok_code>. IF <v_ok_code> IS ASSIGNED. <v_ok_code> = e_ucomm. ENDIF. PERFORM ucomm_general IN PROGRAM saplfkl9. ENDMETHOD.
Aktuellen Posten ermitteln
In dieser Hilfsmethode wird die aktuelle Zeile aus dem Kontenstand ermittelt. In der Funktionsgruppe gibt es zwei interne Tabellen, eine mit den verdichteten und eine mit den unverdichteten Posten. Die Methode gibt den unverdichteten Posten zurück, wenn möglich, ansonsten den verdichteten Posten.
METHOD get_current_item. TYPES t_postab TYPE TABLE OF fkkepos WITH NON-UNIQUE DEFAULT KEY . FIELD-SYMBOLS <t_postab> TYPE t_postab. FIELD-SYMBOLS <s_item_alv> LIKE LINE OF <t_postab>. FIELD-SYMBOLS <s_item_db> LIKE LINE OF <t_postab>. " Aktuelle Zeile ermitteln io_alv->get_current_cell( IMPORTING es_row_no = DATA(ls_row_info) ). " zunächst Zugriff auf die Tabelle der verdichteten Posten ASSIGN ('(SAPLFKL9)GT_POSTAB[]') TO <t_postab>. IF <t_postab> IS NOT ASSIGNED. RETURN. ENDIF. READ TABLE <t_postab> INDEX ls_row_info-row_id ASSIGNING <s_item_alv>. IF sy-subrc <> 0. RETURN. ENDIF. " danach Zugriff auf die Tabelle der unverdichteten Posten ASSIGN ('(SAPLFKL9)POSTAB[]') TO <t_postab>. IF <t_postab> IS NOT ASSIGNED. RETURN. ENDIF. READ TABLE <t_postab> WITH KEY orisp = <s_item_alv>-oriso ASSIGNING <s_item_db>. IF sy-subrc = 0. rs_item = <s_item_db> " unverdichteten Posten zurückgeben ELSE. rs_item = <s_item_alv>. " verdichteten Posten zurückgeben ENDIF. ENDMETHOD.
Im Zeitpunkt 1205 einbinden
Um das Kontextmenü in den ALV-Kontenstand einzubinden, ist es abschließend noch erforderlich, in den Kunden-Funktionsbaustein im Zeitpunkt 1205 folgende Zeilen hinzuzufügen:
IF i_first_call = abap_true AND i_fkkl1-xgrid = abap_true AND i_fkkeposc-tcode = 'FPL9' AND i_fkkeposc-varnr IS NOT INITIAL. lcl_event_listener=>subscribe( ). ENDIF.