Um eigene Toolbar-Funktionen erweiterte ALV
Transcription
Um eigene Toolbar-Funktionen erweiterte ALV
ajanzen.com Um eigene Toolbar-Funktionen erweiterte ALV-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_SALV_TABLE. 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 kann Abbildung 1 entnommen werden. Aus Gründen der Übersichtlichkeit sind Hauptprogramm und das INCLUDE zur Ereignisbehandlung in eigenständigen Kapiteln enthalten. 2.1 Hauptprogramm In Kapitel 2.1 wird zwischen dem umgesetzten Vorgehen (siehe Unterkapitel 2.1.1) und einer anderen möglichen Vorgehensweise (siehe Unterkapitel 2.1.2) unterschieden. 2.1.1 Umgesetztes Vorgehen Im ersten Schritt des ALV-Aufrufes wird über die FACTORY-Methode der Klasse CL_SALV_TABLE eine Instanz derselben Klasse erzeugt. Dabei wird der FactoryMethode die Tabelle mit den anzuzeigenden Informationen direkt mitgegeben. Eine zusätzliche Angabe eines Feldkataloges ist nicht notwendig, da sich die CL_SALV_TABLE-Klasse die Dictionary-Informationen anhand der Tabellenfelder ermittelt. Zu beachten ist, dass beim Aufruf der FACTORY-Methode der optionale Parameter R_CONTAINER mit einem Default-Container belegt wird. Die Begründung für den Container-Einsatz ist in Kapitel 2.1.2 enthalten. Über eine Instanz von Klasse CL_SALV_COLUMNS_TABLE wird die Spaltenbreite an den Inhalt angepasst (optimiert). Zum besseren Auswählen der einzelnen Zeilen, erfolgt das Aktivieren des Selektionsmodus. Für diese Aktivität wird zum ALV eine Instanz der Klasse CL_SALV_SELECTIONS erzeugt und der Selektionsmodus durch Aufruf von Methode SET_SELECTION_MODE( ) gesetzt. Für das Erweitern der Toolbar um die gewünschte Funktion, ist eine Instanz der Klasse CL_SALV_FUNCTIONS_LIST zum ALV notwendig. Vor dem Einfügen der eigenen Funktion werden über Methode SET_ALL( ) der soeben erzeugten Instanz alle SAPStandard ALV-Funktionen aktiviert. In Abbildung 1 sind diese Funktionen links vom roten Rahmen aufgeführt. 2 ajanzen.com Das Hinzufügen der eigenen Funktion erfolgt über Methode ADD_FUNCTION( ) der Klasse CL_SALV_FUNCTIONS_LIST. In dem vorliegenden Beispiel sind alle Schnittstellenparameter der Methode belegt und die neue Funktion rechts neben den Standard-Funktionen positioniert. Das Ergebnis des bisher beschriebenen Vorgehens ist in Abbildung 1 visualisiert. Der rote Rahmen hebt die eigene Funktion hervor. Abbildung 1: Um eine eigene Funktion erweiterte Toolbar Wie bereits einleitend erwähnt, wird beim Klick auf die neu eingefügte Funktion ein Ereignis ausgelöst. Die Ereignisbehandlung findet über eine eigenständige lokale Klasse statt. Nähere Informationen zu der Klasse können Kapitel 2.2 entnommen werden. Damit das ALV weiß, wo das Klick-Ereignis behandelt wird, ist eine Verbindung zwischen Ereignis und Ereignis-Behandler herzustellen, also das Ereignis zu registrieren. Zum Registrieren wird eine Instanz der Klasse CL_SALV_EVENTS_ TABLE benötigt. Das Objekt der Klasse verwaltet die SALV-Ereignisse. Da zur Ereignisbehandlung eine eigenständige Klasse zum Einsatz kommt, muss diese ebenfalls instanziiert werden. Nach Instanziieren der lokalen Behandler-Klasse wird diese über die Anweisung SET HANDLER der Instanz von CL_SALV_EVENTS_ TABLE zugeordnet und damit die Verbindung zwischen Ereignis und Ereignisbehandlung hergestellt. Hinweis: Bei dem ausgelösten Ereignis handelt es sich um ADDED_FUNCTION. Dieses kann der Registerkarte Ereignisse der Klasse CL_SALV_EVENTS_TABLE entnommen werden (siehe Abbildung 2). In der Behandler-Klasse kommt für die Ereignisbehandlung Methode HANDLE_TOOLBAR_CLICK zum Einsatz. 3 ajanzen.com Abbildung 2: Ereignis ADDED_FUNCTION der Klasse CL_SALV_EVENTS_TABLE Das eigentliche Visualisieren erfolgt durch Methode DISPLAY( ) der ALV-Klasse. Da der Factory-Methode ein Container mitgegeben wurde, ist auch eine Art „TrägerDynpro“ notwendig. Dieses ist erforderlich, damit sich der Container irgendwo „andocken“ kann. In diesem Beispiel wird das Dynpro über die Anweisung WRITE erzeugt. 2.1.2 Exkurs Mir sind zwei Vorgehen bekannt, die beim Einsatz der CL_SALV_TABLE-Klasse das Einbinden eigener Funktionen in die Toolbar ermöglichen. In Kapitel 2.1.1 ist eines der Vorgehen beschrieben. Das zugehörige Coding kann Kapitel 3 entnommen werden. Die zweite Möglichkeit basiert auf dem Einsatz des PF-STATUS. Der PF-Status mit allen ALV-Standardfunktionen kann aus dem Demo-Report SALV_DEMO_TABLE_ FUNCTIONS kopiert werden und hat hier die Bezeichnung SALV_STANDARD. Nach dem Kopieren lässt sich der PF-Status durch eigene Funktionen erweitern (sieh Abbildung 3). Abbildung 3: Um eigene Funktion erweiterter PF-Status Das Bekanntmachen des PF-Status der SALV-Instanz erfolgt über folgende Anweisung: 4 ajanzen.com gr_salv->set_screen_status( pfstatus = 'SALV_STANDARD' report = sy-repid set_functions = gr_salv->c_functions_all ). Auch eine über den PF-Status eingefügte Funktion erscheint in der Toolbar und das Ausführen dieser Funktion erzeugt ein Ereignis. Die Ereignisbehandlung unterscheidet sich nicht von der Ereignisbehandlung beim ersten Vorgehen und kann dem vorliegenden Dokument entnommen werden. Welches der beiden Vorgehen zum Erweitern der Toolbar eingesetzt werden kann, hängt davon ab, ob der FACTORY-Methode der Klasse CL_SALV_TABLE ein Container mitgegeben wird oder nicht. Wird auf das Mitgeben eines Containers verzichtet, erfolgt im Rahmen der Ausführung der DISPLAY( ) Methode ein Dynproaufruf. Bei diesem Vorgehen können eigene Funktionen nur über den PFStatus mitgeteilt werden. Bei Angabe eines Containers, ist das Erweitern der Toolbar nur über die Methode ADD_FUNCTION( ) möglich. Da in diesem Fall kein Dynpro-Aufruf in Methode DISPLAY( ) erfolgt, ist der zusätzliche Aufruf eines „Träger-Dynpros“ im Programm notwendig. In diesem Beispiel habe ich mich für die Variante mit Container entschieden. Das hat m.E. den Vorteil, dass der Beispielcode direkt kopiert und getestet werden kann. Statt der WRITE-Anweisung für das Träger-Dynpro kann zum Aufruf eines Dynpros auch die Anweisung CALL-Screen verwendet werden. Auch bei der Verwendung der Container hat der Entwickler freie Hand. So kommen hier beispielsweise folgende Container in Frage: • CL_GUI_DOCKING_CONTAINER • CL_GUI_DIALOGBOX_CONTAINER • CL_GUI_CUSTOM_CONTAINER 2.2 INCLUDE zur Ereignisbehandlung Wie bereits im Vorfeld beschrieben, ist für die Behandlung des Ereignisses ButtonClick eine Behandler-Klasse notwendig. In dem vorliegenden Beispiel wurde die Klasse in ein eigenständiges INCLUDE ausgelagert. Die ausgeprägte Logik ist in Kapitel 2.2 beschrieben. 5 ajanzen.com Die Behandler-Klasse besteht neben der Constructor-Methode ausschließlich aus Methode HANDLE_TOOLBAR_CLICK. Letztere wurde als Event-handler für das Ereignis ADDED_FUNCTION der CL_SALV_EVENTS_TABLE definiert. Beim Instanziieren der Behandler-Klasse werden der Constructor-Methode eine Instanz der SALV-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 4). 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 4: 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 5). 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 5: Zeiger auf Ursprungsdaten bei der Zuweisung GET REFERENCE OF Hinweis: In der FACTORY( )-Methode der SALV-Klasse wird ebenfalls nur eine Referenz auf die übergebenen Daten erzeugt. 6 ajanzen.com Zu Beginn der Verarbeitung von Methode HANDLE_TOOLBAR_CLICK wird abgefragt, um was für eine Funktion es sich handelt. Diese Information ist im EreignisParameter E_SALV_FUNCTION enthalten. Handelt es sich um die im Vorfeld erstellte Toolbar-Funktion, werden die ausgewählten Zeilen ermittelt. Das erfolgt über eine Instanz der Selektionsklasse CL_SALV_SELECTIONS zur, in der ConstructorMethode klassenglobal abgelegten, SALV-Instanz. Das eigentliche Bestimmen der ausgewählten Zeilen findet über Methode GET_SELECTED_ROWS( ) der Selektionsklasse statt. Unter Verwendung der Indizes werden die selektierten Zeilen aus der klassenglobal vorliegende Tabellenreferenz auf die Daten bestimmt und in einem Pop-Up angezeigt. 7 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 eines SALV im * Selection-mode erweitert um eine eigene Toolbar-Funktion * * Date: 28.03.2015 *--------------------------------------------------------------------* * Änderungen *--------------------------------------------------------------------* REPORT zaj_sel_mode_own_funct_salv. *************************************************************************** **** * Include zur Ereignisbehandlung *************************************************************************** **** INCLUDE zaj_sel_mode_own_funct_salv_cl. DATA: gr_salv TYPE REF TO cl_salv_table. DATA: gr_columns TYPE REF TO cl_salv_columns_table. DATA: gr_functions TYPE REF TO cl_salv_functions_list. DATA: gr_selections TYPE REF TO cl_salv_selections. DATA: gt_sflight TYPE flighttab. DATA: gr_err_salv TYPE REF TO cx_salv_msg. DATA: gr_err_salv_exist TYPE REF TO cx_salv_existing. DATA: gr_err_wrong_call TYPE REF TO cx_salv_wrong_call. DATA: gv_string TYPE string. DATA: gr_events TYPE REF TO cl_salv_events_table. DATA: gr_event_handler TYPE REF TO gcl_event_handler. 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. *************************************************************************** **** * Daten anzeigen *************************************************************************** **** TRY. * ALV-Instanz erzeugen CALL METHOD cl_salv_table=>factory EXPORTING list_display = if_salv_c_bool_sap=>false r_container = cl_gui_custom_container=>default_screen IMPORTING r_salv_table = gr_salv CHANGING t_table = gt_sflight. CATCH cx_salv_msg INTO gr_err_salv. * Fehler anzeigen gv_string = gr_err_salv->get_text( ). MESSAGE gv_string TYPE 'E'. ENDTRY. * Instanz für Spalten holen gr_columns = gr_salv->get_columns( ). * Spaltenbreite optimieren gr_columns->set_optimize( abap_true ). " nur ein 'X' *************************************************************************** **** * Selection-Mode aktivieren *************************************************************************** **** * Instanz des Selection-Objektes holen gr_selections = gr_salv->get_selections( ). * Selektionsmodus setzen gr_selections->set_selection_mode( if_salv_c_selection_mode=>row_column ). *************************************************************************** **** * Alle Standard-Funktionen auf aktiv setzen *************************************************************************** **** * Instanz für Funktionen holen gr_functions = gr_salv->get_functions( ). * Alle Standardfunktionen aktivieren gr_functions->set_all( abap_true ). " nur ein 'X' *************************************************************************** **** * Toolbar um eigene Funktionen erweitern *************************************************************************** **** TRY. * Neue Funktion für das ALV vorsehen gr_functions->add_function( name = 'NFUNC' icon = '@L1@' text = 'Neue Funktion' tooltip = 'Hinzugefügte Funktion' position = if_salv_c_function_position=>right_of_salv_functions " Irgendein ICON aus Tabelle ICON ). CATCH cx_salv_existing INTO gr_err_salv_exist. * Fehler anzeigen gv_string = gr_err_salv_exist->get_text( ). MESSAGE gv_string TYPE 'E'. CATCH cx_salv_wrong_call INTO gr_err_wrong_call. * Fehler anzeigen gv_string = gr_err_wrong_call->get_text( ). MESSAGE gv_string TYPE 'E'. ENDTRY. *************************************************************************** **** * Ereignis zum Behandeln des Button-Click registrieren *************************************************************************** **** * Das Objekt für die möglichen ALV-Ereignisse holen gr_events = gr_salv->get_event( ). * Objekt für die Ereignisbehandlung erzeugen ... CREATE OBJECT gr_event_handler EXPORTING cr_salv = gr_salv it_sflight = gt_sflight. * ... und bei den ALV-Ereignissen registrieren SET HANDLER gr_event_handler->handle_toolbar_click FOR gr_events. *************************************************************************** **** * * ALV-Anzeige anstoßen *************************************************************************** **** * ALV-Anzeige anstoßen gr_salv->display( ). * "Trägerbildschirm" für Container rufen WRITE space. 3.2 INCLUDE zur Ereignisbehandlung *************************************************************************** **** * Definition der Klasse *************************************************************************** **** CLASS gcl_event_handler DEFINITION. PUBLIC SECTION. METHODS: constructor IMPORTING cr_salv TYPE REF TO cl_salv_table it_sflight TYPE flighttab. METHODS: handle_toolbar_click FOR EVENT added_function OF cl_salv_events_table IMPORTING e_salv_function. PROTECTED SECTION. DATA: gr_salv_class TYPE REF TO cl_salv_table. DATA: gt_sflight_class TYPE REF TO flighttab. METHODS: display_popup CHANGING ct_sflight_display TYPE flighttab. ENDCLASS. "gcl_event_handler DEFINITION *************************************************************************** **** * Implementierung der Klasse *************************************************************************** **** CLASS gcl_event_handler IMPLEMENTATION. METHOD constructor. * Importparameter in globale Klassenattribute übernehmen gr_salv_class = cr_salv. GET REFERENCE OF it_sflight INTO gt_sflight_class. ENDMETHOD. "constructor METHOD handle_toolbar_click. DATA: lr_selections TYPE REF TO cl_salv_selections. DATA: lt_sel_rows TYPE salv_t_row. DATA: lv_sel_row TYPE int4. DATA: ls_sflight TYPE sflight. DATA: lt_sflight_display TYPE flighttab. CASE e_salv_function. WHEN 'NFUNC'. *************************************************************************** **** * Hier behandeln wir unsere Funktion *************************************************************************** **** * Instanz des Selection-Objektes holen lr_selections = gr_salv_class->get_selections( ). * Indes der markierten Zeilen bestimmen lt_sel_rows = lr_selections->get_selected_rows( ). * Die selektierten Datensätze ermitteln LOOP AT lt_sel_rows INTO lv_sel_row. * selektierte Zeilen auslesen READ TABLE gt_sflight_class->* INTO ls_sflight INDEX lv_sel_row. * Datensatz für die Anzeige übernehmen APPEND ls_sflight TO lt_sflight_display. ENDLOOP. * Daten in einem separaten Pop-Up visualisieren display_popup( CHANGING ct_sflight_display = lt_sflight_display ). WHEN OTHERS. *************************************************************************** **** * Wenn sonst irgendwas passiert, soll keine Reaktion erfolgen *************************************************************************** **** ENDCASE. ENDMETHOD. "handle_toolbar_click 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. ENDCLASS. "display_popup "gcl_event_handler IMPLEMENTATION