Um eigene Toolbar-Funktionen erweiterte ALV-Grid
Transcrição
Um eigene Toolbar-Funktionen erweiterte ALV-Grid
ajanzen.com Um eigene Toolbar-Funktionen erweiterte ALV-Grid-Anzeige ajanzen.com 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. 1 ajanzen.com 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. 2 ajanzen.com 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 ALVGrid-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 Toolbar 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 3 ajanzen.com 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 ImportparameterTabelle IT_SFLIGHT in das globale Klassenattribut kopiert. Dadurch existieren die Informationen (Tabellen) doppelt (siehe Abbildung 3). Globales Attribut GT_SFLIGHT_CLASS Importparameter IT_SFLIGHT Mandant 001 001 001 001 001 … Carrier AA AA AZ AZ AZ … Flug-Nr. 17 64 555 555 788 … Flugdatum 15.10.2014 12.12.2014 15.10.2014 04.02.2015 23.06.2015 … Flugpreis 422,94 422,94 185,00 185,00 1.030,00 … … … … … … … … Mandant 001 001 001 001 001 … Carrier AA AA AZ AZ AZ … Flug-Nr. 17 64 555 555 788 … Flugdatum 15.10.2014 12.12.2014 15.10.2014 04.02.2015 23.06.2015 … Flugpreis 422,94 422,94 185,00 185,00 1.030,00 … … … … … … … … 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). 4 ajanzen.com Importparameter IT_SFLIGHT Mandant 001 001 001 001 001 … Carrier AA AA AZ AZ AZ … Flug-Nr. 17 64 555 555 788 … Flugdatum 15.10.2014 12.12.2014 15.10.2014 04.02.2015 23.06.2015 … Flugpreis 422,94 422,94 185,00 185,00 1.030,00 … … … … … … … … Globales Attribut GT_SFLIGHT_CLASS Abbildung 4: Zeiger auf Ursprungsdaten bei der Zuweisung 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. 5 ajanzen.com 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. 6 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 von 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 ein * 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 setzen SET HANDLER gr_event_handler->add_toolbar_function FOR gr_alv_grid. * Ereignisbehandler zum behandeln der eigenen Funktion 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