Exporting ALV to Memory2
Wir greifen den Trick – nach SUBMIT an die ALV-Daten im Office-Format zu gelangen – noch einmal auf und zeigen, wie man aus dem XML-String eine Tabelle erhält.
In diesem Beispiel rufen wir das Beispielprogramm BCALV_FULLSCREEN_DEMO auf, um mittels ALV-Grid Daten zu erzeugen.
Die Flugdatenbank muss natürlich gefüllt sein!!
Die grundlegenden Bestandteile sind bereits im vorherigen Artikel erläutert worden. In diesem Programm zeigen wir, wie man die im XML-Format vorliegenden Daten in eine interne Tabelle umwandelt.
Das XML-Ergebnis wird dabei Ereignisgesteuert bearbeitet. Das bedeutet: Die XML-Tags werden Stück für Stück durchlaufen und im Programm wird entsprechend darauf reagiert.
XML
Die zurückgelieferte XML-Struktur, die die Tabelle beschreibt ist recht komplex. Hier ist die Beispiel-XML-Datei zu sehen: http://pastebin.com/XkgctkJA
Uns interessieren jedoch nur die folgenden Tags:
Anzahl der Spalten
<Table><Column/><Column/></Table>
Zellen und Zelleninhalte
<Cell><Data>Inhalt</data></cell>
Coding
REPORT zz_export_alv_to_memory_demo01. *----------------------------------------------------------------------* * CLASS lcl_xml DEFINITION *----------------------------------------------------------------------* CLASS lcl_xml DEFINITION. PUBLIC SECTION. CLASS-METHODS call_report IMPORTING iv_repid TYPE syrepid iv_list TYPE char1. CLASS-METHODS create_table IMPORTING iv_fields TYPE i EXPORTING ed_table TYPE REF TO data. CLASS-METHODS display_data IMPORTING it_table TYPE STANDARD TABLE PREFERRED PARAMETER it_table. ENDCLASS. "lcl_xml DEFINITION *----------------------------------------------------------------------* * CLASS lcl_xml IMPLEMENTATION *----------------------------------------------------------------------* CLASS lcl_xml IMPLEMENTATION. METHOD call_report. *== Data DATA lv_guid TYPE guid_32. DATA ls_params TYPE rsparams. DATA lt_params TYPE TABLE OF rsparams. *== Create and export GUIID for ALV lv_guid = cl_salv_export_db_storage=>create_guid( ). EXPORT l_mode = 'M' TO MEMORY ID 'ALV_EXTRACT_MODE'. EXPORT l_guid = lv_guid TO MEMORY ID 'ALV_EXTRACT_GUID'. *== Call Report SUBMIT (iv_repid) WITH SELECTION-TABLE lt_params AND RETURN. "#EC CI_SUBMIT DATA lv_xstring TYPE xstring. DATA lr_stream_factory TYPE REF TO if_ixml_stream_factory. DATA lr_ixml TYPE REF TO if_ixml. DATA lr_istream TYPE REF TO if_ixml_istream. DATA lr_doc TYPE REF TO if_ixml_document. DATA lr_parser TYPE REF TO if_ixml_parser. DATA lv_events TYPE i. DATA lv_number_of_fields TYPE i. DATA lr_event TYPE REF TO if_ixml_event. DATA lv_type TYPE i. DATA lv_current_node TYPE string. DATA lv_current_value TYPE string. DATA lv_cell_index TYPE i. *== Import XML-data from AVL and convert to stream lv_xstring = cl_salv_export_db_storage=>import_xmlstring ( guid = lv_guid ). lr_ixml = cl_ixml=>create( ). lr_stream_factory = lr_ixml->create_stream_factory( ). lr_istream = lr_stream_factory->create_istream_xstring ( string = lv_xstring ). lr_doc = lr_ixml->create_document( ). *== Create parser for document lr_parser = lr_ixml->create_parser( document = lr_doc istream = lr_istream stream_factory = lr_stream_factory ). *== deactivate DOM generation lr_parser->set_dom_generating( space ). *== data for dynamically generated internal table DATA ld_table TYPE REF TO data. FIELD-SYMBOLS <table> TYPE STANDARD TABLE. FIELD-SYMBOLS <row> TYPE ANY. "line of <table>. FIELD-SYMBOLS <cell> TYPE string. *== define Parser events lv_events = if_ixml_event=>co_event_element_pre2 + if_ixml_event=>co_event_element_post + if_ixml_event=>co_event_text_post. *== Register XML-Events lr_parser->set_event_subscription( lv_events ). DO. *== get next event (XML-tag) lr_event = lr_parser->parse_event( ). IF lr_event IS INITIAL. EXIT. ENDIF. *== get type of event lv_type = lr_event->get_type( ). *== New element CASE lv_type. WHEN if_ixml_event=>co_event_element_pre2. *===> Event "PRE2" lv_current_node = lr_event->get_name( ). IF iv_list <> space. WRITE: / lv_current_node. ENDIF. CASE lv_current_node. WHEN 'Column'. *=====> New Column: Add column counter ADD 1 TO lv_number_of_fields. WHEN 'Row'. *=====> New Row IF <table> IS NOT ASSIGNED. *=====> Create table if not done yet create_table( EXPORTING iv_fields = lv_number_of_fields IMPORTING ed_table = ld_table ). ASSIGN ld_table->* TO <table>. ENDIF. *=====> Insert new table line APPEND INITIAL LINE TO <table> ASSIGNING <row>. CLEAR lv_cell_index. WHEN 'Cell'. *======> new cell data: ADD 1 TO lv_cell_index. ASSIGN COMPONENT lv_cell_index OF STRUCTURE <row> TO <cell>. ENDCASE. WHEN if_ixml_event=>co_event_text_post. *===> Event "TEXT" CASE lv_current_node. WHEN 'Data'. *=====> get cell value and assign to table cell <cell> = lr_event->get_value( ). ENDCASE. IF iv_list <> space. lv_current_value = lr_event->get_value( ).. WRITE lv_current_value COLOR COL_TOTAL. ENDIF. WHEN if_ixml_event=>co_event_element_post. *===> Event "POST" IF iv_list <> space. lv_current_node = lr_event->get_name( ). WRITE: lv_current_node COLOR COL_GROUP. ENDIF. ENDCASE. ENDDO. *== Display table IF <table> IS ASSIGNED. display_data( <table> ). ENDIF. ENDMETHOD. "call_report METHOD create_table. *== field catalog DATA lt_fcat TYPE lvc_t_fcat. FIELD-SYMBOLS <fcat> TYPE lvc_s_fcat. *== create field catalog for internal table DO iv_fields TIMES. *== cell APPEND INITIAL LINE TO lt_fcat ASSIGNING <fcat>. <fcat>-fieldname = sy-index. CONDENSE <fcat>-fieldname. <fcat>-tabname = 'GT_TABLE'. <fcat>-inttype = 'g'. "String ENDDO. *== generate internal table from given field catalog CALL METHOD cl_alv_table_create=>create_dynamic_table EXPORTING it_fieldcatalog = lt_fcat IMPORTING ep_table = ed_table EXCEPTIONS generate_subpool_dir_full = 1 OTHERS = 2. ENDMETHOD. "create_table METHOD display_data. *== Data DATA lv_col TYPE i. FIELD-SYMBOLS <row> TYPE ANY. FIELD-SYMBOLS <cell> TYPE string. *== Display all table lines LOOP AT it_table ASSIGNING <row>. NEW-LINE. DO. *== Display each table cell ASSIGN COMPONENT sy-index OF STRUCTURE <row> TO <cell>. IF sy-subrc = 0. lv_col = ( sy-index - 1 ) * 21. WRITE AT lv_col(19) <cell> COLOR COL_POSITIVE. ELSE. EXIT. "from do ENDIF. ENDDO. ENDLOOP. ENDMETHOD. "display_data ENDCLASS. "lcl_xml IMPLEMENTATION ***___________________________________________________________________ *** *** SELECTION SCREEN ***___________________________________________________________________ *** SELECTION-SCREEN BEGIN OF BLOCK reps WITH FRAME TITLE text-var. PARAMETERS p_repid TYPE syrepid DEFAULT 'BCALV_FULLSCREEN_DEMO'. PARAMETERS p_data RADIOBUTTON GROUP x DEFAULT 'X'. PARAMETERS p_list RADIOBUTTON GROUP x. SELECTION-SCREEN END OF BLOCK reps. START-OF-SELECTION. *== Start report lcl_xml=>call_report( EXPORTING iv_repid = p_repid iv_list = p_list ).
- Interview mit Björn Schulz (Software-Heroes.com) - 3. September 2024
- Daten aus ALV ermitteln - 3. September 2024
- So lange es den SAPGUI noch gibt… - 27. Juni 2024
Eine schöne Lösung – aber:
Die Ergebnistabelle ist sehr ‘neutral’: Alle Spalten sind vom Typ String.
Insbesondere ist eine Datumsspalte im Format yyyy-mm-tt, was eine Weiterverarbeitung
zumindest erschwert.
Schöner wäre eine Tabelle, die technisch genau so aufgebaut ist wie im
Layout der ALV-Ausgabe des Reports.
Ich habe mal versucht mit dem FB LT_DBDATA_READ_FROM_LTDX dem ALV-Report sein Layout zu entlocken.
Dadurch bekommt man leider auch nur die Feldnamen mit diversen Parametern und eben nicht die Datenelemente.
Gibt es für EXPORT l_mode = ‘M’ TO MEMORY ID ‘ALV_EXTRACT_MODE’ vielleicht noch andere Ausprägungen,
die dafür sorgen, dass mehr technische Information in die XML-Daten gelangt?
Statt ‘M’ habe ich im System auch ‘B’, ‘E’ und ‘F’ gesehen.
Viele Grüße
Werner Maurer
Hui. Das ist aber schon lange her… 😉
Evtl. kommst du mit der Methode CL_SALV_EXPORT_DB_STORAGE=>IMPORT_ALV_VARIANT nach Aufruf des Reports weiter.
Für FB LT_VARIANT_LOAD braucht man aber ausser dem Reportnamen und des Layouts (DISVARIANT) auch einen Tabellennamen, wenn ich das richtig sehe. Genau der fehlt aber.
Zudem ist ja auch nicht sicher, dass der ALV überhaupt ein gespeichertes Layout benutzt hat.
Ob es noch weitere Parameter gibt, weiß ich nicht.
Vielen Dank für die prompte Reaktion.
Die Methode CL_SALV_EXPORT_DB_STORAGE=>IMPORT_ALV_VARIANT hilft mir schon ein bisschen weiter – mit ihr kann ich prüfen, ob ein gespeichertes Layout benutzt wurde.
Dann kann ich mit dem FB LT_DBDATA_READ_FROM_LTDX die Details zum Layout ermitteln. Leider eben nur die Feldnamen etc. Mit den Feldnamen und der Struktur, die dem ALV zugrunde liegt, kann ich dann weiterkämpfen.
Evtl. mal einen Breakpoint bei “EXPORT TO MEMORY” setzen und gucken, was da vom ALV noch exportiert wird.
Ich hatte gedacht, dass mit der GUIID noch was passiert aber nichts gefunden.