erste Mal würde ich gern loswerden, dass das hier echt ein klasse Forum ist! ein Dank and die Webmaster, macht echt Spaß, sich hier zu tummeln. Meiner Meinung nach, ist das hier im deutschsprachigen Raum das Beste.
Aus dem Grund hab ich mich entschlossen, hier nen kleinen Aufsatz über ALV zu schreiben. (nicht nur, außer mir etwas davon hat... ich hoffe, daß ihr mir Feedback gebt. Und ich meine Programme dadurch optimieren kann )
Vorwort:
Vor einiger Zeit habe ich den Auftrag bekommen einen Report zu schreiben, der eine Auswertung macht. Wie die Auswertung am Schluss dargestellt werden sollte wurde mir überlassen. Ich habe mich für den ALV Grid entschieden. Jedoch musste ich schnell feststellen, dass dieser so seine Tücken hat. und auch die Informationen dazu etwas spärlich sind... Aber genug gequakt, lasst uns mal eine kleine Applikation bauen:
Ich wollte in meinem Report keine Dynpros zeichnen und habe in dem Forum folgenden Beitrag gefunden: http://www.abapforum.com/forum/viewtopic.php?t=834.
1. Einfachstaufruf des FuBas 'REUSE_ALV_GRID_DISPLAY'
Der Baustein REUSE_ALV_GRID_DISPLAY baut selbständig einen ALV auf. Der Einfachstaufruf sieht wie folgt aus:
- Code: [Select all] [Expand/Collapse] [Download] (Untitled.txt)
- * call ALV
- CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
- EXPORTING
- I_STRUCTURE_NAME = 'SFLIGHT'
- t_outtab = lt_sflight
- EXCEPTIONS
- program_error = 1
- OTHERS = 2.
- GeSHi ©
Der an I_STUCTURE_NAME übergebene Parameter ist der Name der Struktur aus dem die Tabelle lt_sflight besteht. Diese Struktur verwendet der ALV um sich die Tabellennamen und Tabelldefinitionen zu ziehen (z.B. ob es sich bei Spalte X ein Datumsfeld handelt, um die dann nach Userzeitzone aufzubereiten)
Das Ergebnis ist ein ALV mit der alt bekannten Buttonleiste. Als Spalten sehen wir die Felder aus der die Tabelle besteht.
2. Ausgabe der Felder anpassen -> REUSE_ALV_FIELDCATALOG_MERGE'
Damit nicht alle Felder angezeigt werden muss man dem ALV einen Fieldcatalog mitgeben. Das ist eine Definition von Feldern die in einer Tabelle übergeben werden. Um die Tabelle nicht mühsam händisch aufbauen zu müssen, verwende ich den Baustein 'REUSE_ALV_FIELDCATALOG_MERGE'.
Der Aufruf sieht wie folgt aus:
- Code: [Select all] [Expand/Collapse] [Download] (Untitled.txt)
- CALL FUNCTION 'REUSE_ALV_FIELDCATALOG_MERGE'
- EXPORTING
- i_structure_name = 'SFLIGHT'
- CHANGING
- ct_fieldcat = lt_fieldcat
- EXCEPTIONS
- inconsistent_interface = 1
- program_error = 2
- OTHERS = 3.
- * MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
- * WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
- GeSHi ©
Der FuBa liefert uns also eine komplette Definition aller Felder der Struktur SFLIGHT. Um eine Tabelle von dem geforderten Typ anzulegen muß man folgende Type-Pool includieren slis. Dies geschieht über die anweisung (meist ganz am anfang des reports):
- Code: [Select all] [Expand/Collapse] [Download] (Untitled.txt)
- TYPE-POOLS slis.
- GeSHi ©
Nun erst mal die unnötigen Felder rausschmeißen:
- Code: [Select all] [Expand/Collapse] [Download] (Untitled.txt)
- OR fieldname = 'CONNID'
- OR fieldname = 'FLDATE'
- OR fieldname = 'PLANETYPE').
- GeSHi ©
und das ganze an unseren ALV übergeben:
- Code: [Select all] [Expand/Collapse] [Download] (Untitled.txt)
- * call ALV
- CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
- EXPORTING
- it_fieldcat = lt_fieldcat
- t_outtab = lt_poarch
- EXCEPTIONS
- program_error = 1
- OTHERS = 2.
- GeSHi ©
Diesmal haben wir einen etwas schmaleren ALV, der nur die Spalten Carrid, connid, fldate und planetype enthält.
3. Keine ddic Struktur für i_structure_name? Kein Problem für den 'REUSE_ALV_FIELDCATALOG_MERGE'
Doch was machen wir, wenn wir keine DDIC Struktur haben auf die wir uns beziehen können?
Was definitiv nicht geht ist folgendes (hab?s ausprobiert ): Lokal einen Type zu definieren und diesen dann an den Parameter I_STRUCTURE_NAME zu übergeben.
Und was nun folgt, ist echt eine klasse Funktion, die in den ?REUSE_ALV_FIELDCATALOG_MERGE' eingebaut wurde. das müsst ihr mal debugged haben - ein traumcoding
Hier erstmal der Aufruf:
- Code: [Select all] [Expand/Collapse] [Download] (Untitled.txt)
- CALL FUNCTION 'REUSE_ALV_FIELDCATALOG_MERGE'
- EXPORTING
- i_program_name = sy-repid
- i_internal_tabname = 'SRESULT'
- * i_structure_name
- * i_client_never_display
- i_inclname = 'ZMADDOGTOP'
- CHANGING
- ct_fieldcat = lt_fieldcat
- EXCEPTIONS
- inconsistent_interface = 1
- program_error = 2
- OTHERS = 3.
- * MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
- * WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
- GeSHi ©
Gibt man dem 'REUSE_ALV_FIELDCATALOG_MERGE' den Programmnamen (Parameter i_program_name) und einen Includenamen (Parameter i_inclname) sowie den Namen des lokalen Datentypen mit (Parameter i_internal_tabname), so parst dieser den Quelltext, sucht dann den definierten Typ und baut anhand dessen einen fieldcatalog zusammen. der Aufruf des FuBas REUSE_ALV_GRID_DISPLAY ist dann wie bei punkt 2.
Der Vorteil den wir hier haben ist, dass wir bei dem select auf die Datenbank gleich ein 'into corresponding fields of table' mitgeben können. Somit werden nicht alle Felder durch die Gegend geschoben (vielleicht kann Frank Dietrich etwas dazu sagen... die Performance lesson habe ich mir leider noch nicht gegeben).
4. Überschrift direkt oberhalb des ALVs - ein kleines Beispiel für Eventing ('REUSE_ALV_EVENTS_GET' - 'REUSE_ALV_COMMENTARY_WRITE')
Um den Benutzern meines Report etwas mehr Informationen über die Daten zu geben die der ALV Ihnen da anzeigt, habe ich mich entschlossen deine Überschriftenspalte einzubauen. Oder wie es in Abap heißt: HTML_TOP_OF_PAGE. Den eigentlichen Inhalt liefert der Baustein 'REUSE_ALV_COMMENTARY_WRITE'. Setzt man den FuBa Aufruf einfach vor den 'REUSE_ALV_GRID_DISPLAY' so erscheint erst unser hübscher ALV. Erst nachdem man auf Back oder F3 geklickt hat, sieht man die gewünschten Kommentare. Und genau hier kommt das Eventing vom ALV GRID ins Spiel. Um bestimmte den ALV flexibel zu halten haben die Entwickler bestimmte Punkte definiert, bei denen man eingreifen kann (Quasi wie BADIS). Die ganze liste aller verfügbaren events liefert der Baustein 'REUSE_ALV_EVENTS_GET'. Dieser hat einen Inputparameter I_LIST_TYPE (für den typ der liste. Nicht alle Listen haben die gleichen events). Dann muss man einfach einem event einen Perform zuordnen den man in seinem Report definiert hat. Diese Eventinformationen übergibt man dann in einer Tabelle an den REUSE_ALV_GRID_DISPLAY. Der Baustein ruft dann automatisch den Perform des eigenen Programms auf.
Und nun zur Praxis:
Zuerst baue ich mir den Header auf:
- Code: [Select all] [Expand/Collapse] [Download] (Untitled.txt)
- *&--------------------------------------------------------------------*
- *& Form DO_TOP_OF_PAGE
- *&--------------------------------------------------------------------*
- * text
- *---------------------------------------------------------------------*
- FORM do_top_of_page.
- lt_top_of_page TYPE TABLE OF slis_listheader.
- * Listenüberschrift: Typ H
- CLEAR ls_line.
- ls_line-typ = 'H'.
- * LS_LINE-KEY: not used for this type
- ls_line-info = 'Na'.
- * Kopfinfo: Typ S
- CLEAR ls_line.
- ls_line-typ = 'S'.
- ls_line-key = 'wie'.
- ls_line-info = 'gehts'.
- * Aktionsinfo: Typ A
- CLEAR ls_line.
- ls_line-typ = 'A'.
- * LS_LINE-KEY: not used for this type
- ls_line-info = 'so?'.
- CALL FUNCTION 'REUSE_ALV_COMMENTARY_WRITE'
- EXPORTING
- it_list_commentary = lt_top_of_page.
- GeSHi ©
Danach bestimme ich, bei welchem event diese form aufgerufen werden soll:
- Code: [Select all] [Expand/Collapse] [Download] (Untitled.txt)
- *&--------------------------------------------------------------------*
- *& Form set_event_for_alv
- *&--------------------------------------------------------------------*
- * text
- *---------------------------------------------------------------------*
- * -->LT_EVENTS text
- *---------------------------------------------------------------------*
- CALL FUNCTION 'REUSE_ALV_EVENTS_GET'
- EXPORTING
- i_list_type = 0
- IMPORTING
- et_events = lt_events.
- * prüfen, ob das event für den listentyp 0 gibt.
- READ TABLE lt_events WITH KEY name = slis_ev_top_of_page
- INTO ls_event.
- * wenn ja dann unseren Perform setzten.
- GeSHi ©
Für Kopf ist es der event TOP_OF_PAGE. Den setzten wir nun auf unseren Perform 'DO_TOP_OF_PAGE'. Damit dieser zum entsprechenden Zeitpunkt vom ALV gerufen
wird.
Und nun brauchen wir nur noch unseren altbekannten Baustein 'REUSE_ALV_GRID_DISPLAY' aufzurufen:
- Code: [Select all] [Expand/Collapse] [Download] (Untitled.txt)
- * call ALV
- CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
- EXPORTING
- i_callback_program = sy-repid
- it_fieldcat = lt_fieldcat
- it_events = lt_events
- t_outtab = lt_poarch
- EXCEPTIONS
- program_error = 1
- OTHERS = 2.
- GeSHi ©
Worauf zu achten ist, dass man hier noch den Parameter i_callback_program mit dem aktuellen Programm befüllt. Das ist wichtig, damit der FuBa unseren in der Tabelle lt_events angegeben Perform findet.
Und das war?s auch schon. Nun haben wir einen ALV der nur die Daten aus unserem Fieldcatalog hat und eine entsprechende Listenüberschrift.
Über Feedback oder Ergänzungen würde ich mich freuen.
Gruß Azreal
ps. als anhang findet ihr das im Punkt 4 beschriebene Programm