Um eigene Toolbar-Funktionen erweiterte...
Transcript of Um eigene Toolbar-Funktionen erweiterte...
ajanzen.com
Um eigene Toolbar-Funktionen erweiterte
ALV-Grid-Anzeige
ajanzen.com
1
1 Einleitung
Der Fokus des vorliegenden Dokumentes liegt auf dem Vorgehen zum Einbinden einer
eigenen Toolbarfunktion bei ALV-Erzeugung unter Verwendung von Klasse
CL_GUI_ALV_GRID. Im Rahmen dessen wird auch auf die Behandlung des
Ereignisses auslösen der eigenen Toolbarfunktion eingegangen. Zur besseren
Strukturierung des Codes ist die Ereignisbehandlung in ein eigenständiges INCLUDE
ausgelagert.
Die im vorliegenden Beispiel ausgeprägte Funktion ist relativ einfach und visualisiert
ausschließlich die ausgewählten Zeilen in einem Pop-Up.
Das komplette Beispielcoding ist in Kapitel 3 enthalten. Nähere Informationen zum
Ablauf können Kapitel 2 entnommen werden.
ajanzen.com
2
2 Informationen zur Programmlogik
Im vorliegenden Beispiel werden vorbereitend die Informationen aus Tabelle SFLIGHT
in eine interne Tabelle selektiert und in Form eines ALVs visualisiert. Anschließend
wird gezeigt, wie die Toolbar der ALV-Anzeige um eigene Funktionen erweitert werden
kann. Das Ergebnis ist in Abbildung 2 visualisiert.
Aus Gründen der Übersichtlichkeit sind Hauptprogramm und das INCLUDE zur
Ereignisbehandlung in eigenständigen Kapiteln enthalten.
2.1 Hauptprogramm
Im ersten Schritt des ALV-Aufrufes wird ein Objekt der Klasse CL_GUI_ALV_GRID
erzeugt. Bei der Objekterzeugung wird als Parent (Parameter I_PARANT) ein
Standard-Container mitgegeben. Dieser dockt sich automatisch auf einem
Trägerdynpro an.
Im nächsten Schritt erfolgt das Ermitteln des Feldkataloges über Funktionsbaustein
LVC_ FIELDCATALOG_MERGE.
Hinweis : Das Ermitteln des Feldkataloges ist in diesem Beispiel nicht zwingend
erforderlich. Die Bezeichnung der Struktur (in unserem Beispiel ist es SFLIGHT) kann
über Parameter I_STRUCTURE_NAME direkt der ALV-Grid-Methode SET_TABLE_
FOR_FIRST_DISPLAY mitgegeben werden. Ich habe es mir jedoch angewöhnt, den
Feldkatalog in einem separaten Schritt immer zu ermitteln, da dieser in vielen Fällen
anzupassen ist (z.B. Spaltenüberschriften)
Nach Aufruf von FuBa LVC_FIELDCATALOG_MERGE werden die
ereignisbehandelnde Klasse instanziiert und die Ereignisbehandler gesetzt. Beim
Instanziieren der Behandler-Klasse werden dieser die Instanz des AVL-Grids und die
Tabelle mit den anzuzeigenden Daten übergeben. Nähere Informationen zur
Behandler-Klasse können Kapitel 2.2 entnommen werden.
Beim Setzen der Ereignisbehandler ist zu beachten, dass die Toolbar bei Verwendung
von Klasse CL_GUI_ALV_GRID nur über das Ereignis TOOLBAR angepasst werden
kann (zumindest ist mir kein anderer Weg bekannt). Beim Auslösen der eigenen
Tollbar-Funktion durch Klicken wird Ereignis USER_COMMAND durchlauen. In
Abbildung 1 sind beide Ereignisse durch einen roten Rahmen hervorgehoben.
ajanzen.com
3
Abbildung 1: Relevante Ereignisse der Klasse CL_GUI _ALV_GRID
Nach Anpassen der Anzeigeeigenschaften und Schaffung der Möglichkeit Varianten
zu speichern, wird über Methode SET_TABLE_ FOR_FIRST_DISPLAY( ) der ALV-
Grid-Klasse die eigentliche Anzeige angestoßen. Der Aufruf des Träger-Dynpro erfolgt
über die Anweisung WRITE.
Das Ergebnis der Anzeige kann Abbildung 2 entnommen werden.
Abbildung 2: Um eigene Funktionen erweiterte Toolba r
2.2 INCLUDE zur Ereignisbehandlung
Wie bereits im Vorfeld beschrieben, ist für die Behandlung der im vorhergehenden
Kapitel benannten Ereignisse eine Behandler-Klasse notwendig. In dem vorliegenden
ajanzen.com
4
Beispiel wurde die Klasse in ein eigenständiges INCLUDE ausgelagert. Die
ausgeprägte Logik ist in Kapitel 2.2 beschrieben.
Die Behandler-Klasse besteht neben der Constructor-Methode und den Methoden zur
Behandlung der Ereignisse TOOLBAR und USER_COMMAND aus zwei
Hilfsmethoden.
Im Folgenden wird näher auf die einzelnen Methoden der Behandler-Klasse
eingegangen.
Beim Instanziieren der Behandler-Klasse werden der Constructor-Methode eine
Instanz der ALV-Grid-Klasse und die Tabelle mit den Daten übergeben. Der Inhalt
beider Parameter wird in klassenglobalen Attributen abgelegt und damit für die
Weiterverarbeitung vorgehalten. Bei Ablage der Datentabelle ist zu beachten, dass
diese nicht über ein „=“ sondern über die Anweisung GET REFERENCE OF erfolgt.
Siehe nachfolgende Erklärung:
Bei Verwenden des „=“ für die Datenzuweisung wird der Inhalt der Importparameter-
Tabelle IT_SFLIGHT in das globale Klassenattribut kopiert. Dadurch existieren die
Informationen (Tabellen) doppelt (siehe Abbildung 3).
Abbildung 3: Doppeln der Daten bei Zuweisung über „ =“
Bei Verwendung der Anweisung GET REFERENCE OF wird ein Zeiger auf die
übergebenen Daten erzeugt. Dadurch sind die Informationen nur einmal vorhanden
und alle Änderungen (z.B. sortieren der Tabelle im ALV) sind ohne weiteren Aufwand
ersichtlich (siehe Abbildung 4).
Mandant Carrier Flug-Nr. Flugdatum Flugpreis …
001 AA 17 15.10.2014 422,94 …
001 AA 64 12.12.2014 422,94 …
001 AZ 555 15.10.2014 185,00 …
001 AZ 555 04.02.2015 185,00 …
001 AZ 788 23.06.2015 1.030,00 …
… … … … … …
Importparameter
IT_SFLIGHT
Mandant Carrier Flug-Nr. Flugdatum Flugpreis …
001 AA 17 15.10.2014 422,94 …
001 AA 64 12.12.2014 422,94 …
001 AZ 555 15.10.2014 185,00 …
001 AZ 555 04.02.2015 185,00 …
001 AZ 788 23.06.2015 1.030,00 …
… … … … … …
Globales Attribut
GT_SFLIGHT_CLASS
ajanzen.com
5
Abbildung 4: Zeiger auf Ursprungsdaten bei der Zuwe isung GET REFERENCE OF
Hinweis : In der Klasse ALV-Grid werden die Informationen der Datentabelle ähnlich
abgelegt.
Methode ADD_TOOLBAR_FUNCTION() behandelt das TOOLBAR-Ereignis und dient
somit dem Anpassen der Toolbar. Dabei werden neue Funktionen in das
Tabellenattribut MT_TOOLBAR des Ereignisparameters E_OBJECT übernommen.
Hinweis : Besteht der Wunsch gewisse Funktionen nicht zur Verfügung zu stellen,
können diese aus dem Tabellentattribut gelöscht werden.
Zur optischen Abgrenzung der neuen Funktion von den SAP-Standardfunktionen wird
vor der neuen Funktion zusätzlich ein Separator (|) eingefügt.
Die Behandlung des Button-Klicks erfolgt über Methode HANDLE_USER_
COMMAND(). Die ausgeführte Funktion ist in Ereignisparameter E_UCOMM
enthalten. In dem vorliegenden Beispiel werden die ausschließlich die markierten
Zeilen in einem Pop-Up visualisiert.
Das Ermitteln der markierten Zeilen erfolgt in Methode GET_SEL_ROWS() der
Ereignisbehandler-Klasse. Dabei ist das vorliegende Beispiel so ausgeprägt, dass
schon das Klicken in eine Zeile als „Markieren“ der Zeile ausreicht (siehe Abbildung
5). Zum Bestimmen angeklickten Zeile kommt Methode GET_SELECTED_CELLS()
der klassenglobal vorliegenden ALV-Grid-Instanz zum Einsatz.
Abbildung 5: Markieren einer Zeile durch anklicken
Im Gegensatz zum Anklicken steht das tatsächliche Markieren von Zeilen. Siehe
hierzu Abbildung 6. Das Bestimmen der markierten Zeilen findet über Methode
GET_SELECTED_ROWS() der klassenglobal vorliegenden ALV-Grid-Instanz statt.
Mandant Carrier Flug-Nr. Flugdatum Flugpreis …
001 AA 17 15.10.2014 422,94 …
001 AA 64 12.12.2014 422,94 …
001 AZ 555 15.10.2014 185,00 …
001 AZ 555 04.02.2015 185,00 …
001 AZ 788 23.06.2015 1.030,00 …
… … … … … …
Importparameter
IT_SFLIGHT
Globales Attribut
GT_SFLIGHT_CLASS
ajanzen.com
6
Abbildung 6: Tatsächliches Markieren der Zeilen
Die letzte Methode der Ereignisbehandler-Klasse hat die Bezeichnung
DISPLAY_POPUP ( ) und dient dem Visualisieren der ausgewählten Informationen.
Für das eigentliche Anzeigen des Pop-Ups kommt aus Gründen der Einfachheit Klasse
CL_SALV_TABLE zum Einsatz.
3 Coding
Wie aus der Überschrift ersichtlich ist, enthält Kapitel 3 das komplette Beispielcoding.
Genau wie beim Aufbau von Kapitel 2 sind Hauptprogramm und das INCLUDE zur
Ereignisbehandlung in eigenständigen Unterkapiteln enthalten.
3.1 Hauptprogramm
*-------------------------------------------------- ------------------*
* Das vorliegende Programm dient der Demonstration einer um eigene
* Funktionen erweiterten Toolbar unter Verwendung v on Klasse
* CL_GUI_ALV_GRID
*
* Date: 24.04.2015
*-------------------------------------------------- ------------------*
* Änderungen
*-------------------------------------------------- ------------------*
REPORT zaj_alv_grid_toolbar_funct .
INCLUDE zaj_alv_grid_toolbar_funct_cl .
CONSTANTS: gc_sel_mode TYPE char1 VALUE 'A' .
DATA: gt_sflight TYPE flighttab .
DATA: gr_alv_grid TYPE REF TO cl_gui_alv_grid .
DATA: gt_fieldcat TYPE lvc_t_fcat .
DATA: gr_event_handler TYPE REF TO gcl_event_handler .
DATA: gs_layout TYPE lvc_s_layo .
DATA: gs_alv_variant TYPE disvariant .
START-OF-SELECTION.
*************************************************** ************************
* Selektion der anzuzeigenden Daten
*************************************************** ************************
SELECT *
FROM sflight
INTO CORRESPONDING FIELDS OF TABLE gt_sflight .
IF sy - subrc NE 0.
* In diesem Fall wird eine leere Tabelle angezeigt
ENDIF.
*************************************************** ***********
* ALV-Objekt instanziieren ... als Container wird e in
* Default-Container angegeben
*************************************************** ***********
CREATE OBJECT gr_alv_grid
EXPORTING
i_parent = cl_gui_custom_container =>default_screen
EXCEPTIONS
error_cntl_create = 1
error_cntl_init = 2
error_cntl_link = 3
error_dp_create = 4
OTHERS = 5.
IF sy - subrc <> 0.
MESSAGE ID sy - msgid TYPE sy - msgty NUMBER sy - msgno
WITH sy - msgv1 sy - msgv2 sy - msgv3 sy - msgv4.
ENDIF.
*************************************************** ***********
* Feldkatalog ermitteln
*************************************************** ***********
CALL FUNCTION 'LVC_FIELDCATALOG_MERGE'
EXPORTING
i_structure_name = 'SFLIGHT'
CHANGING
ct_fieldcat = gt_fieldcat
EXCEPTIONS
inconsistent_interface = 1
program_error = 2
OTHERS = 3.
IF sy - subrc <> 0.
MESSAGE ID sy - msgid TYPE sy - msgty NUMBER sy - msgno
WITH sy - msgv1 sy - msgv2 sy - msgv3 sy - msgv4.
ENDIF.
*************************************************** ***********
* Ereignisbehandler setzen
*************************************************** ***********
* Behandler-Objekt instanziieren
CREATE OBJECT gr_event_handler
EXPORTING
ir_alv_grid = gr_alv_grid
it_sflight = gt_sflight .
* Ereignisbehandler zum verändern der Toolbar setze n
SET HANDLER gr_event_handler -> add_toolbar_function FOR gr_alv_grid .
* Ereignisbehandler zum behandeln der eigenen Funkt ion setzen
SET HANDLER gr_event_handler -> handle_user_command FOR gr_alv_grid .
*************************************************** ***********
* ALV-Anzeige anstoßen
*************************************************** ***********
* Anzeigeeigenschaften setzen
MOVE gc_sel_mode TO gs_layout - sel_mode .
MOVE abap_true TO gs_layout - cwidth_opt .
MOVE abap_true TO gs_layout - zebra .
* Speichern von Varianten ermöglichen
MOVE sy - repid TO gs_alv_variant - report .
* anzeigen
gr_alv_grid -> set_table_for_first_display (
EXPORTING
is_variant = gs_alv_variant
is_layout = gs_layout
CHANGING
it_outtab = gt_sflight
it_fieldcatalog = gt_fieldcat
EXCEPTIONS
invalid_parameter_combination = 1
program_error = 2
too_many_lines = 3
OTHERS = 4
).
IF sy - subrc <> 0.
MESSAGE ID sy - msgid TYPE sy - msgty NUMBER sy - msgno
WITH sy - msgv1 sy - msgv2 sy - msgv3 sy - msgv4.
ENDIF.
*************************************************** ***********
* Träger-Dynpro per WRITE zur Anzeige bringen
*************************************************** ***********
WRITE space .
3.2 INCLUDE zur Ereignisbehandlung
*&------------------------------------------------- --------------------*
*& Include ZAJ_ALV_GRID_TOOLBAR_FUNCT_CL
*&------------------------------------------------- --------------------*
CLASS gcl_event_handler DEFINITION .
* Methoden und Attribute der Sichtbarkeit PUBIC
PUBLIC SECTION.
METHODS: constructor
IMPORTING ir_alv_grid TYPE REF TO cl_gui_alv_grid
it_sflight TYPE flighttab ,
add_toolbar_function FOR EVENT toolbar OF cl_gui_alv_grid
IMPORTING e_object
e_interactive ,
handle_user_command FOR EVENT user_command OF cl_gui_alv_grid
IMPORTING e_ucomm.
* Methoden und Attribute der Sichtbarkeit PROTECTED
PROTECTED SECTION.
CONSTANTS: gc_new_function TYPE ui_func VALUE 'NEW' .
DATA: gr_cl_alv_grid TYPE REF TO cl_gui_alv_grid .
DATA: gr_cl_sflight TYPE REF TO flighttab .
METHODS: get_sel_rows
RETURNING value ( rt_sflight_lines ) TYPE flighttab ,
display_popup
CHANGING ct_sflight_display TYPE flighttab .
ENDCLASS. "gcl_event_handler DEFINITION
*-------------------------------------------------- --------------------*
* CLASS gcl_event_handler IMPLEMENTATION
*-------------------------------------------------- --------------------*
*
*-------------------------------------------------- --------------------*
CLASS gcl_event_handler IMPLEMENTATION.
METHOD constructor .
* Importingparameter klassenglobal ablegen
gr_cl_alv_grid = ir_alv_grid .
GET REFERENCE OF it_sflight INTO gr_cl_sflight .
ENDMETHOD. "gcl_event_handler
METHOD add_toolbar_function .
DATA: ls_toolbar_button TYPE stb_button .
* separator einfügen
MOVE 3 TO ls_toolbar_button - butn_type .
APPEND ls_toolbar_button TO e_object -> mt_toolbar .
CLEAR: ls_toolbar_button .
* Toolbar um eigene Funktion erweitern
MOVE gc_new_function TO ls_toolbar_button - function .
MOVE '@9P@' TO ls_toolbar_button - icon . "Siehe Tabelle ICON
MOVE 'Neue Funktion' TO ls_toolbar_button - quickinfo .
MOVE 'Neue Funktion' TO ls_toolbar_button - text .
* Funktion übernehmen
APPEND ls_toolbar_button TO e_object -> mt_toolbar .
ENDMETHOD. "add_toolbar_function
METHOD handle_user_command .
DATA: lt_sflight_lilnes TYPE flighttab .
CASE e_ucomm.
WHEN gc_new_function .
*************************************************** ******
* Behandeln der neu hinzugefügten Funktion
*************************************************** ******
* Zu Beginn die selektierten Zeilen bestimmen
lt_sflight_lilnes = get_sel_rows ( ).
* Und hier ist die eigentliche Anzeige
display_popup (
CHANGING
ct_sflight_display = lt_sflight_lilnes ).
WHEN OTHERS.
* Nichts tun
ENDCASE.
ENDMETHOD. "handle_user_command
METHOD get_sel_rows .
DATA: lt_cells TYPE lvc_t_cell .
DATA: ls_rows TYPE lvc_s_row .
DATA: ls_cell TYPE lvc_s_cell .
DATA: lt_rows TYPE lvc_t_row .
DATA: ls_sflight TYPE sflight .
* Zeilen wurden markiert
gr_cl_alv_grid -> get_selected_rows (
IMPORTING
et_index_rows = lt_rows
).
* in eine Zeile wurde geklickt
IF lt_rows[] IS INITIAL .
gr_cl_alv_grid -> get_selected_cells (
IMPORTING
et_cell = lt_cells
).
LOOP AT lt_cells INTO ls_cell .
MOVE ls_cell - row_id TO ls_rows - index .
APPEND ls_rows TO lt_rows .
ENDLOOP.
CLEAR ls_rows .
ENDIF.
* Und jetzt die eigentlichen Zeilen ermitteln
LOOP AT lt_rows INTO ls_rows .
READ TABLE gr_cl_sflight -> * INTO ls_sflight
INDEX ls_rows - index .
APPEND ls_sflight TO rt_sflight_lines .
ENDLOOP.
ENDMETHOD. "get_sel_rows
METHOD display_popup .
DATA: lr_salv_popup TYPE REF TO cl_salv_table .
DATA: lr_err_salv TYPE REF TO cx_salv_msg .
DATA: lv_string TYPE string .
TRY.
* ALV-instanz erzeugen
CALL METHOD cl_salv_table =>factory
EXPORTING
list_display = if_salv_c_bool_sap =>false
IMPORTING
r_salv_table = lr_salv_popup
CHANGING
t_table = ct_sflight_display .
CATCH cx_salv_msg INTO lr_err_salv .
* Fehler anzeigen
lv_string = lr_err_salv -> get_text ( ).
MESSAGE lv_string TYPE 'E' .
ENDTRY.
* Größe des Fensters setzen
lr_salv_popup -> set_screen_popup (
start_column = 5
end_column = 160
start_line = 5
end_line = 15 ).
* Anzeige anstoßen
lr_salv_popup -> display ( ).
ENDMETHOD. "display_popup
ENDCLASS. "gcl_event_handler IMPLEMENTATION