• Anfragen per Mail

    info(at)nehoco.at

Dieses Tutorial versucht in einer Schritt-für-Schritt-Anleitung die Implementierung eines ALV-Gridcontrols darzustellen. Es stellt sozusagen ein Kochrezept zur Verfügung, um einerseits das Verständnis der Funktionsweise dieses Steuerelements zu verstehen und andererseits um eigenständige Entwicklungen zu fördern.

 Haftungsausschluss / Disclaimer

This document may discuss sample coding or other information that does not include SAP official interfaces and therefore is not supported by SAP. Changes made based on this information are not supported and can be overwritten during an upgrade. SAP will not be held liable for any damages caused by using or misusing the information, code or methods suggested in this document, and anyone using these methods does so at his/her own risk.
SAP offers no guarantees and assumes no responsibility or liability of any type with respect to the content of this technical article or code sample, including any liability resulting from incompatibility between the content within this document and the materials and services offered by SAP. You agree that you will not hold, or seek to hold, SAP responsible or liable with respect to the content of this document.

Inhaltsverzeichnis

Kapitel Überschrift  
1 Übersicht
2 Erste Schritte
3 Erste Implementierung
4 Toolbars und der Event Handler
5 Zeileninhalte auslesen - Details ausgeben
6 Ampeln und andere Farbspielereien
7 Änderung der Flugdaten
8 Noch ein paar Worte zum Schluss
Anhang A Autor
Anhang B Voraussetzungen

 

Übersicht

Das folgende Tutorial dient dazu, das Verständnis einer ALV Grid Control Implementierung zu fördern. Es sind dazu keine Detailkenntnisse der objektorientierten ABAP-Programmierung notwendig noch ist es wichtig, Erfahrungen in der Dialogprogrammierung zu besitzen. Sollten diese Kenntnisse allerdings vorhanden sein, schaden sie natürlich nicht.
Inhalt dieser Anleitung ist die Erstellung eines ausführbaren Reports, die Anlage von 2 einfachen Dynpros, die Erstellung eines GUI-Titels und eines GUI-Status. Des weiteren werden wir den Event-Handler kennenlernen und wie Klassen und Instanzen zu verwenden sind. Die Anleitung ist so aufgebaut, das auch einzelne Kapitel das Verständnis des ALV Grid Control fördern, allerdings wird das implementierte Beispiel von Kapitel zu Kapitel erweitert.
Ergebnis dieser Anleitung ist die Erstellung eines ALV Grid Controls, der Daten der Tabellen SFLIGHT und SBOOK darstellt, wobei dem Benutzer die Möglichkeit gegeben werden soll zu einzelnen Flüge die Buchungsdaten anzuzeigen bzw. einzelne Flüge zu ändern.

Zum Inhaltsverzeichnis

Erste Schritte

Zu Beginn möchte ich mal abstecken, ob dieses Tutorial überhaupt für euch von Nutzen ist. Mir ist es schon des Öfteren so ergangen, das ich nach 10 Seiten Durcharbeitung plötzlich stecken blieb, da ich von völlig falschen Voraussetzungen ausgegangen bin. Deshalb schauen wir uns einmal an (wie bei einem guten Kochrezept), welche Zutaten benötigt werden:

  • Grundkenntnisse der ABAP Programmierung, d.h. wie erstelle ich einen ABAP-Report, was ist ein GUI-Status, was ist ein OK-Code etc. reichen aus
  • Einen ausführbaren Report
  • Ein Dynpro, um das ALV-Grid anzuzeigen
  • Einen Custom-Container im Dynpro, der den ALV-Grid darstellt
  • Einen GUI-Status, damit das Dynpro ohne Debugging verlassen werden kann (EXIT-Buttons)

Soweit klar? OK, dann kann es ja losgehen.

Erstellung ausführbarer Report und Dynpro

  • Erstellung eines ausführbaren Reports
    Die Bezeichnung des Reports ist grundsätzlich egal. Es sollte auf jeden Fall ein ausführbares Programm erzeugt werden ohne TOP-Include
  • Erstellung des Dynpro 0100
    Anschließend ein Dynpro anlegen mit der Nummer 0100. Als Typ des Dynpro „Normal“ auswählen. Ansonsten alles so belassen, wie es vorgegeben ist.
  • Erstellung eines Custom Containers im Dynpro 0100
    Nach Erstellung des Dynpro muss ein Controlelement angelegt werden, der sog. Custom Container. Dazu das Dynpro aufrufen und mittels Layout-Button den grafischen Screen Painter aufrufen. Anschließend in den Änderungsmodus wechseln und auf den Button für den Custom Control klicken.

Custom Control Button

 

Anschließend öffnet sich ein Viereck und dieses im Dynpro platzieren. Je nach Wunsch ist es größenmäßig anzupassen. Schließlich noch den Namen ALV_CONTAINER vergeben. Speichern, Aktivieren und das Ganze sollte dann ungefähr folgendermaßen aussehen:

ALV Container

Zum Schluss den Screen Painter verlassen, denn er wird in diesem Kapitel nicht mehr gebraucht.

  • Erstellung eines GUI-Status für Dynpro 0100
    Damit das angezeigte Dynpro 0100 auch „normal“ verlassen werden kann, sollte noch ein GUI-Status eingebaut werden, der bei Anzeige des Dynpro vorhanden ist. Dazu legen wir den GUI-Status STATUS_0100 an. Bezeichnung kann frei vergeben werden. In der Menüleiste übernehmen wir zunächst die Standardleisten und belegen im Menü Bearbeiten und Springen den Code EXIT.
    Bei den Funktionstasten belegen wir ebenfalls nur die Abbrechen, Zurück und Beenden Buttons mit dem Code EXIT. Das ganze sollte dann folgendermaßen aussehen

GUI Status

Speichern, Aktivieren und Schluss. Noch nicht ganz. Damit das Programm die Funktionscodes auch verarbeiten kann, müssen wir noch im Dynpro ein Feld einbauen, damit diese Codes auch aufgenommen werden können.
Also Dynpro 0100 durch Doppelklick aufrufen, den Tabreiter Elementliste anklicken und in den Änderungsmodus gehen. Wie unschwer zu erkennen ist, existieren 2 Elemente, allerdings hat das Feld OK noch keinen Namen. Hier den Namen OK_CODE eingeben, speichern und aktivieren.

Zusammenfassung

Nachdem nun die grundsätzlichen Anforderungen geklärt sind, haben wir einmal die grundlegende Basis für die Implementierung des ALV Grid Control gelegt. Wir haben einen Report erzeugt, der später Daten ausliest und im ALV darstellt. Danach haben wir ein Dynpro inklusive eines Custom Controls erzeugt, der für die Darstellung und Verarbeitung der Daten zuständig ist. Schließlich haben wir noch einen GUI-Status hinzugefügt, damit das Dynpro auch von „Nicht-Debuggern“ verlassen werden kann.
Die Basis des Programms ist gelegt, nun geht es daran das Custom Control mit Daten zu befüllen, das Dynpro anzuzeigen und auch wieder verlassen zu können. Dies alles passiert im nächsten Kapitel und wir können auch schon einen ersten Probelauf des Programms durchführen. Also: Weiter geht’s!

Erste Implementierung

Nachdem nun in Kapitel 1 die Grundlagen für die Erstellung des ALV Grid Control gelegt wurden, geht es nun daran dieses mit Daten zu befüllen, im Dynpro anzuzeigen bzw. das Layout insofern anzupassen, indem der User Varianten anlegen und abspeichern kann, um sie bei einem zukünftigen Aufruf abzurufen bzw. als voreingestellte Variante bei Ausführung des Programmes zu sehen.

Definition der Datenfelder

Damit auch nur irgendwas im Report passiert ist es notwendig, die notwendigen Datenfelder zu definieren. Dies erreichen wir durch folgenden Codingteil, der am Anfang des Reports eingefügt wird:

Coding

Datenfeldname Typ Beschreibung
gt_sflight Interne Tabelle Diese Tabelle enthält die Daten aus der Tabelle sflight, die im ALV Grid Control angezeigt werden
ok_code Variable OK-Codefeld, welche die Funktionscodes verarbeitet
g_wa_sflight Struktur 1-zeilige Datenstruktur der Tabelle sflight (für später…)
go_grid Klasseninstanz Instanz der Klasse CL_GUI_ALV_GRID (ALV List Viewer)
go_custom_container Klasseninstanz Instanz der Klasse CL_GUI_CUSTOM_CONTAINER (Container für Custom Controls im Dynproumfeld)

Diese Datendeklarationen sind notwendig, um grundlegend Daten im Dynpro via ALV List Viewer anzuzeigen bzw. die Navigation via GUI-Status zu ermöglichen.

Aufruf des Dynpro

Das ist zwar alles schön und gut, allerdings wird uns kein Dynpro angezeigt werden. Daher sagen wir dem Report nach der Datendeklaration welchen Bildschirm ergo Dynamisches Programm (Dynpro) es anzeigen und verarbeiten soll. Dies erfolgt durch folgenden Befehl:

Coding

Diesen Befehl fügen wir unmittelbar nach der Datendeklaration ein. Es wird nun nach der Datendeklaration das Dynpro 0100 aufgerufen und somit wird sofort der PBO-Prozess dieses Dynpros gestartet. Also bauen wir im PBO Bereich folgendes Modul ein:

PBO

Durch Doppelklick auf status_0100 erzeugen wir ein neues Modul im Report, das wir folgendermassen ausgestalten:

Coding

Als erstes setzen wir hier den angelegten GUI-Status (Funktionscode EXIT) und überprüfen ob eine Instanz für den Custom Container existiert. Falls dies der Fall ist, also bei Erstausführung, legen wir eine Instanz, die einen Bezug zum Custom Container im Dynpro 0100 mit dem Namen 'ALV_CONTAINER' hat. Anschließend erstellen wir eine Instanz für das ALV Grid Control, welches wiederum im Custom Container 'ALV_CONTAINER' enthalten ist (daher Export-Parameter Parent). Als letzten Teil laden wir noch die Daten in das ALV Grid Control mittels eines Unterprogrammes. Dieses brauchen wir aber noch nicht anzulegen (daher noch keinen Check durchführen). Das erfolgt dann später.

Da allerdings das Dynpro-Prozessieren nicht nur aus PBO, sondern auch aus PAI Modulen besteht, schließen wir diese gleich ab. Diese brauchen wir, um auf die Eingaben des Benutzers (Richtig: diese Funktionscodes EXIT) zu reagieren. Wir statten also den Process After Input-Prozess folgendermaßen aus:

PAI

Durch Doppelklick auf user_command_0100 legen wir ein neues Modul im Report an, das folgendes Coding enthält:

Coding

Ich denke, diese Minicoding ist wohl selbsterklärend und braucht nicht näher dokumentiert zu werden.

Laden der Daten in den ALV-Grid

Es sind nun alle Vorbereitungen getroffen, um das Dynpro mit ALV Grid Control anzuzeigen und auch wieder aus dem Dynpro auszusteigen. Allerdings fehlt noch ein wesentlicher, für den Benutzer wahrscheinlich DER wesentlichste Teil, nämlich die Anzeige der Daten im ALV Grid Control. Das tun wir indem wir die Zeile

Coding

Doppelt anklicken und ein neues Unterprogramm erzeugen, welches wie folgt erweitert wird:

Coding

Ich denke, auch hier ist das Coding selbsterklärend. Wir selektieren alle Daten aus den Tabelle sflight und übergeben sie der internen Tabelle gt_sflight. Anschließend rufen wir die Methode set_table_for_first_display der Instanz go_grid auf (Klasse CL_GUI_ALV_GRID) und lassen die interne Tabelle anzeigen, welche die Struktur SFLIGHT aufweist.

Jetzt den ganzen Report checken, speichern und aktivieren und schon sollte folgendes Ergebnis sichtbar sein:

Ergebnis Selektion

Layoutvarianten ändern, sichern und aufrufen

Sieht doch mal nicht so schlecht aus. Allerdings hat das Ganze noch einen Schönheitsfehler: Es können weder Varianten aufgerufen noch gespeichert werden. Dieses kleine Manko beheben wir indem wir das vorherige Coding des Unterprogramms ändern:

Coding

Wir fügen also den Datentyp l_layout ein, der uns die Variante einblendet. Als Default-Variante übernehmen wir die Report-ID und übergeben diese in der Methode. Schließlich sagen wir der Methode mittels Exportparameter i_save, welche Varianten gespeichert bzw. aufgerufen werden dürfen:

  • U - Nur Benutzerspezifische Varianten
  • X - Nur Globale Varianten
  • A - Sowohl Globale als auch Benutzerspezifische Varianten dürfen gesichert werden
  • Leer -> Es dürfen keine Varianten gesichert werden

Einfach ausprobieren und ihr werdet sehen, wie einfach das funktioniert.

Zusammenfassung

Nachdem nun die Datenfelddeklaration durchgeführt wurde, haben wir uns zuerst einmal darum gekümmert, dass der richtige Dynpro angezeigt wird und das OK_CODE-Feld richtig verarbeitet wird. Im Zuge der Anzeige des Dynpros haben wir Instanzen der Klassen CL_GUI_ALV_GRID und CL_GUI_CUSTOM_CONTAINER erzeugt, damit das Custom Control-Feld im Dynpro auch angezeigt wird. Anschließend haben wir noch die Daten ausgelesen und das ALV Grid damit befüllt. Zum guten Schluss haben wir dem Benutzer noch die Möglichkeit gegeben, Varianten zu ändern, zu speichern und wieder aufzurufen.

Damit kann der Benutzer schon was anfangen. Report ausführen, Varianten anlegen und aufrufen. Was will ein einfacher Benutzer mehr? Falls euch das nicht reicht (wovon ich mal ausgehe) der sollte sich auch die nächsten Kapitel zu Gemüte führen.

Toolbars und der Event Handler

In den ersten beiden Kapiteln haben wir also einen ALV Grid erzeugt, der Daten in ein Dynpro ausgibt und indem der User eigene Varianten verwenden kann. Schön. Wie wäre es aber, könnten wir noch die vordefinierte Toolbar mit einer zusätzlichen Funktion via Button versehen und auf diese bei Anklicken auch reagieren? Nun das machen wir nun in diesem Kapitel.

Die Definition des Event Handler

Wie so oft bei ABAP müssen wir dem Programm mal die Definitionen übermitteln. Als erstes stellen wir dem Programm alle Icon’s (oder auf hochdeutsch: Ikonen) zur Verfügung, damit wir den Button mit einer solchen belegen können. Dazu schreiben wir am Beginn des Programmes folgenden Eintrag:

Coding

Anschließend definieren wir einen Event Handler, damit wir einerseits die Standard-Toolbar anpassen können und andererseits auf das Ereignis reagieren können, sobald ein Benutzer diese Toolbar aktiviert bzw. im Besonderen unseren hinzugefügten Button betätigt. Zuerst müssen wir dem Report sagen, dass die Definition des Event Handlers vor der Definition des lcl_event_receiver erfolgt. Dies tun wir, indem wir zu Beginn des Reports (unter Type-Pools) folgende Anweisung eingeben:

Coding

Danach erfolgt die Definition des Event Handlers. Wegen der besseren Übersichtlichkeit habe ich diese nach den globalen Daten durchgeführt, es kann aber beliebig eingefügt werden - nehme ich mal an ;-)

Coding

Voila, damit haben wir einmal unseren Event Handler definiert. Aber jeder der auch nur ansatzweise des ABAP-OO mächtig ist weiß doch, dass noch die Definition und die Implementation des Event Handlers fehlt. Und hier kommt sie auch schon (zumindest mal die Definition):

Coding

Was haben wir denn jetzt schon wieder definiert? Also, das Ziel ist es, die Standard-Toolbar, um ein bzw. mehrere Felder zu erweitern und auch darauf zu reagieren. Dazu stellt uns die Klasse CL_GUI_ALV_GRID 2 Events zur Verfügung: 1. mal das Ereignis (oder EVENT) toolbar, indem wir die Toolbar verändern können, wie wir wollen (das folgt in der Implementierung) und 2. Verwenden wir das Ereignis user_command um eine entsprechende Reaktion auf die Aktion des Benutzers durchzuführen, wenn ein Button angeklickt wird. Alles klar soweit? Na dann geht es weiter zur Implementierung, die wir direkt unterhalb der Definition einbauen:

Coding

Zur Methode handle_toolbar: die Struktur ls_toolbar wird mit jenen Informationen versehen damit die Standard-Toolbar um einen Button erweitert wird. Diese Struktur wird anschließend mittels APPEND-Befehles an e_object übergeben und damit wird gleichzeitig die Toolbar erweitert.

Dieser zusätzliche Button wurde mit dem Funktionscode CHANGE ausgestattet. Genau auf diesen Funktionscode reagiert die nächste Methode. D.h. wird dieser Button betätigt und der Funktionscode CHANGE ausgelöst, so wird das Programm verlassen.

Den Event Handler erzeugen und auslösen

Wir haben nun den Event Handler definiert und implementiert. Aber dieses gute Ding steht jetzt im Coding herum und tut eigentlich nichts. Oder? Auch die erweitere Toolbar wird nicht angezeigt. Alles umsonst gewesen? Natürlich nicht. Also es geht nun darum, dem Dynpro zu sagen: Erzeuge ein Objekt des Event Handlers und pass genau auf diese 2 Ereignisse ergo Events auf.

Wir machen dies nun im Process before Output und zwar am Besten, nachdem das ALV Grid Objekt erzeugt wurde:

Coding

Anschließend lösen wir den Event toolbar aus, um die modifizierte Toolbar anzuzeigen. Diese Auslösung erfolgt direkt nach der Abarbeitung der Methode set_table_for_first_display:

Coding

Und um das Ganze noch abzurunden, setzen wir gleich danach folgende Codingzeile:

Coding

Diese Anweisung, wie der Methode unschwer zu entnehmen ist, setzt den Focus auf den ALV Grid.

Und noch ein bißchen am Layout herumfeilen ...

Nachdem wir nun schon die Toolbar so schön angepasst haben, wollen wir der ganzen Liste auch noch ein schöneres Erscheinungsbild geben und der Liste eine Überschrift geben.

Dazu verwenden wir die Datenstruktur lvc_s_layo, also ein durchaus sprechender Name ;-). Diese Struktur können wir einfach verwenden und anschließend in den Methodenaufruf set_table_for_first_display einbauen. Und schon geht’s los:

Wie üblich müssen wir diese Struktur mal definieren (Global Data Bereich bietet sich an):

Coding

Danach setzen benennen wir den Titel der Liste mit dem Namen Fluege oder Flights oder Flüge. Das überlasse ich euch:

Coding

Wo das eingebaut werden soll? Vor dem Methodenaufruf würde es sich anbieten, denn da müsst ihr auch die Struktur einbauen:

Coding

Und? Hat es funktioniert? Na bitte. Falls nicht, dann bitte einfach Bescheid geben;-)

Die Struktur kann aber natürlich weit mehr, als nur den Titel einzublenden. Es lassen sich mit dieser Struktur auch die Toolbar ausblenden, wie die Zeilen markiert werden können, Exceptions anzeigen (kommt nochmal später) usw.

Einfach mal ausprobieren…

Zusammenfassung

In diesem Kapitel haben wir nun den berühmten Event Handler eingebaut und ihn dazu verwendet auf bestimmte Ereignisse (Toolbar angepasst und auf die Reaktion des Benutzers reagieren) zu reagieren. Im Detail haben wir die Standard-Toolbar um einen Button erweitert und bei Anklicken dieses Buttons verlassen wir das Programm. Zusätzlich haben wir die Struktur lvc_s_layo eingebaut, mit der wir den ALV Grid anpassen können. D.h. einen sprechenden Titel vergeben bzw. kann diese Struktur auch für viele andere Layoutfunktionen verwendet werden.

Zeileninhalte auslesen - Details ausgeben

Da wir nun mit dem ALV Grid schon so vertraut sind, wollen wir in diesem Kapitel daran gehen und nicht nur die Tabelleninhalte anzeigen, sondern dem Benutzer auch die Möglichkeit geben, auf Basis seiner Selektion von Zeilen Detaildaten dazu anzuzeigen. In unserem Beispiel tun wir dies indem wir dem Benutzer die Möglichkeit geben eine Zeile auszuwählen (also einen Flug) und mittels anklicken eines Buttons (das haben wir ja im vorherigen Beispiel erfolgreich exerziert) die dazugehörigen Buchungen anzuzeigen. Klingt einfach und ist es (hoffentlich) auch.

Vorbereitungen

 

Also was brauchen wir nun um das zu bewerkstelligen:

  1. Eine Funktion, damit nur eine Zeile selektiert wird, denn wir wollen den Benutzer ja nicht überfordern…
  2. Einen neuen Button, der das Dynpro aufruft und die Daten übergibt
  3. Ein neues Dynpro (Dynpro 0101 – Analog zum Dynpro 0100)
  4. Eine Funktion, welche die selektierte Zeile ausliest und diese Info weitergibt damit die Buchungen ausgelesen werden können
  5. Eine Funktion, damit die Buchungen ausgelesen werden und an den ALV Grid übergeben werden

Da wir nun die genauen Anforderungen kennen, kann es auch gleich losgehen.

Wir sorgen einmal dafür, dass der Benutzer nur eine einzelne Zeile selektieren kann, und erstellen einen Button, damit das Dynpro aufgerufen werden kann. Beide Funktionen haben wir im vorigen Kapitel kennengelernt und brauchen wir nur ganz einfach anzuwenden:

Selektion einer Zeile im ALV-Grid

Im Augenblick haben wir folgende Selektionsmöglichkeit gegeben:

Coding

Damit hat der Benutzer die Möglichkeit mehrere Zeilen (multiple rows) auszuwählen. Wir ändern diese Einstellung von A auf B und schon kann der Benutzer nur mehr eine einzelne Zeile auswählen.

Neuer Button zum Aufruf des Dynpro für Buchungen

Im vorigen Kapitel hatten wir den Button Change hinzugefügt, den wir ein späteres Kapitel benötigen. Nun wollen wir noch einen zusätzlichen Button hinzufügen, der die Funktion BOOKINGS auslöst. Dazu implementieren wir im Event Handler in der Methode handle_toolbar den zusätzlichen Button Buchungen und in der Methode handle_user_command reagieren wir auf diese neue Funktion:

Zuerst der neue Button:

Coding

Dieses Coding fügen wir direkt unter dem Button CHANGE ein. Anschließend fügen wir in der Methode handle_user_command folgendes Coding ein:

Coding

Neues Dynpro für Anzeige der Buchungen

So weit so gut. Nun müssen wir dafür sorgen, dass ein neues Dynpro existiert, dass diese Daten auch anzeigen kann. Dazu legen wir das Dynpro 0101 an, das einfach vom Dynpro 0100 kopieren. Also Dynpro 0100 markieren, rechte Maustaste -> kopieren und als Dynpro 0101 einfügen. Erledigt. Nun nicht ganz. Wir müssen noch den Custom Container umbenennen: von ALV_CONTAINER auf ALV_BOOKINGS, aber das war es im Prinzip auch schon wieder.

Neue Funktion, um die selektierte Zeile auszulesen

Wir haben nun den Button und reagieren auch darauf. Wir haben das neue Dynpro, das allerdings noch nutzlos Speicherplatz verbraucht. Also sorgen wir nun dafür, dass dieses Dynpro auch mit Leben erfüllt wird. Wie in jedem Kapitel definieren wir zuerst die notwendigen Strukturen, Tabellen etc.:

Wir sagen dem Programm, das auch die Tabelle SBOOK benötigt wird:

Coding

Und eine interne Tabelle für die spätere Selektion der Buchungen brauchen wir auch noch:

Coding

Wir teilen dem Programm mit, das ein neuer Custom Container und ein neues ALV Grid auftreten werden:

Coding

Als nächstes müssen wir nun in der Methode handle_user_command dafür sorgen, das die selektierte Zeile ausgelesen wird und zur weiteren Prozessierung übergeben wird. Dazu definieren wir zu Beginn der Methode folgende interne Tabelle:

Coding

Diese Tabelle wird dann die selektierten Daten enthalten. Nun erweitern wir den Funktionscode BOOKINGS in der Methode:

Coding

Damit selektieren wir die markierte Zeile im ALV Grid und (falls kein Fehler auftritt) rufen wir das Unterprogramm show_booking_table auf, damit die Buchungen auf Basis der internen Tabelle lt_rows selektiert werden können. Aber halt, wird der geübte Programmierer aufschreien, was ist wenn keine Zeile markiert worden ist? Guter Einwand, also erweitern wir unser Coding. Zuerst Datendeklaration für die Anzahl der selektierten Zeilen:

Coding

Danach den ELSE-Zweig erweitern, um bei Nicht-Selektion aus dem Programm abzuspringen und den User zu beschimpfen ähm Verzeihung zu informieren:

Coding

Die Vorkehrungen sind getroffen, also müssen wir jetzt dafür sorgen, dass die Buchungen ausgelesen werden und das Dynpro angezeigt wird. Weiter geht’s.

Buchungen auslesen und im neuen Dynpro anzeigen

Doppelklick auf show_booking_table und ein neues Unterprogramm anlegen.

Als erstes müssen wir folgenden Codingteil bearbeiten:

Coding

Wir ersetzen den Teil mit der Struktur lvc_s_row und implementieren den folgenden Code innerhalb des Unterprogramms:

Coding

Wir erhalten also in diesem Unterprogramm die ausgelesene Zeile aus dem ALV Grid und verarbeiten diese in einer Schleife. Diese Schleife übergibt nun aus der Tabelle gt_sflight jene Zeile, die selektiert wurde und übergibt diese an eine Struktur, welche dieser Zeile entspricht. Anschließend selektieren wir aus der Tabelle sbook jene Buchungen, die dieser Selektion ergo diesem Flug entsprechen und übergeben Sie in die Tabelle gt_sbook.

Man könnte dies natürlich auch mir mehreren Zeilen machen, aber dies ist eine andere Geschichte. Am Ende rufen wir noch das neue Dynpro auf, um die Ergebnisse anzuzeigen. Und voila wir bekommen einen wunderschönen Bildschirm, der außer Grau nichts anzeigt. Was haben wir vergessen? Natürlich, das PBO-Modul entsprechend auszuformulieren, indem wir das ALV Grid des Dynpros einer Instanz zuweisen und die Ergebnisse in dieses ALV Grid befüllen. Also dann mal los. Wir öffnen das Dynpro 0101 und ändern in der Ablauflogik von MODUL status_0100 auf status_0101 (obwohl wir keinen Status setzen). Doppelklick auf das neue Modul und im Programm ein neues PBO-Modul erzeugen.

Im Prinzip machen wir jetzt dasselbe, was wir schon im vorigen Kapitel getan haben, um den ALV Grid anzuzeigen bzw. die Daten zu übergeben. Wir prüfen im ersten Schritt, ob eine Instanz des Custom Container existiert. Wenn nicht, dann erzeugen wir eine neue Custom Container Instanz und auch eine neue Instanz des ALV Grid in diesem Custom Container. Danach definieren wir einen Titel für den ALV Grid und rufen das Grid mit den bereits selektierten SBOOK-Daten auf. Das Coding sieht dann wie folgt aus:

Coding

Der Benutzer wird aber wahrscheinlich nicht nur einmal die Flugbuchungen für einen Flug aufrufen, sondern dies mehrmals tun. Allerdings ist dann die Instanz schon vorhanden und das Dynpro würde dann ins Leere laufen. Also müssen wir auch den ELSE-Zweig Leben einhauchen. Um also eine neuerliche Anzeige der Buchungen (möglicherweise mit anderen Buchungsdaten) zu gewährleisten rufen wir einfach die Methode refresh_table_display auf und somit ist auch dieses Dilemma beseitigt:

Coding

Zu guter Letzt geben wir dem ALV Grid im Dynpro 0101 noch den Focus und damit ist alles wieder Paletti:

Coding

Zusammenfassung

Nachdem nun eine Tabelle im ALV Grid angezeigt wurde, sind wir einen Schritt weitergegangen und geben dem Benutzer nun auch die Möglichkeit, auf Basis eines selektierten Eintrages in der Tabelle sich die Detaildaten auf Basis dieser Tabelle anzeigen zu lassen. Dazu haben wir zunächst die Toolbar erweitert und den Event Handler eine neue Funktion implementiert, welche auf Basis der selektierten Zeile die Detaildaten ausliest und anschließend ein neues Dynpro aufruft. Dieses neue Dynpro ist ähnlich dem Grunddynpro und stellt nun die Detaildaten dar. Im Gegensatz zum Originaldynpro haben wir auch eine neue Methode kennengelernt, welches bei bereits bestehender Instanz die Daten des ALV Grid auffrischt.

Ampeln und andere Farbspielereien

Bis jetzt wurden prinzipiell die Einträge aus den Tabellen sflight bzw. sbook ausgelesen und mittels ALV Grid Control dargestellt. So weit so gut. In diesem Kapitel gehen wir einen Schritt weiter und wollen dem Benutzer einen raschen Überblick der dargestellten Daten ermöglichen, indem wir ihm mittels Farbinformationen über Dateninhalte informieren. Dies können wir einerseits über eine Ampelfarbe (Rot, Gelb, Grün) in einer Spalte darstellen – auch genannt Exception – oder aber indem wir eine ganze Zeile mittels einer Farbe hinterlegen, die bestimmte Kriterien erfüllt. Das gibt dem Benutzer sofort einen raschen Überblick, ob beispielsweise kritische Werte in der Liste enthalten sind.

Wir bauen eine Ampel ein

Die Ampelfunktion ist grundsätzlich ein Teil der Layoutstruktur lvc_s_layo die wir in den vorangegangen Kapiteln schon für Titel bzw. Auswahlstil (sel_mode) verwendet haben. Um diese im ALV Grid nun anzuzeigen müssen wir allerdings eine neue Spalte in die Tabelle sflight einbauen, damit das Layout weis, welche Spalte die Information enthält, ob nun eine grüne, gelbe oder rote Ampel darzustellen ist. Also erweitern wir zuerst einmal die Tabelle sflight um ein Feld, welches diese Information aufnehmen kann.

Dazu bauen wir uns einen neuen Tabellentyp, der dieses zusätzliche Feld aufnehmen kann, auf Basis der bestehenden Tabelle sflight:

Coding

D.h. wir haben die Tabelle sflight verwendet und fügen das Feld traffic_light an, welches 3 Werte aufnehmen kann:

  • 1 – Rote Ampel
  • 2 – Gelbe Ampel
  • 3 – Grüne Ampel

Schließlich müssen wir noch unsere bisherige interne Tabelle gt_sflight diesem neu definierten Tabellentyp anpassen:

Coding

Zusätzlich muss noch die Struktur für die Modifikation pro Zeile dem neuen Tabellentyp angepasst werden:

Coding

Alle diese Deklarationen werden in der globalen Definition durchgeführt. Nun geht es daran, dieses zunächst leere Feld auch zu befüllen. Dazu sehen wir uns einfach mal das aktuelle Coding im Unterprogramm load_data_into_grid an. Nachdem das Select von der Tabelle sflight in die interne Tabelle gt_sflight durchgeführt worden ist, müssen wir diese interne Tabelle modifizieren, damit die Ampelinfo eingetragen ist.

Es stellt sich nun die Frage, auf Basis welcher Kriterien soll der Benutzer informiert werden, ob es sich um einen kritischen Eintrag handelt oder nicht. Die Buchungseinnahmen eines Fluges sind beispielsweise ein solches Kriterium. Ein Manager könnte beispielsweise festlegen, dass alle Flüge welche unter 100.000 Währungseinheiten ein Verlust sind, zwischen 100.000 und 1.000.000 kritisch und über 1.000.000 Währungseinheiten ein Gewinn sind. Dementsprechend belegen wir unsere Ampel. Wir fügen daher folgendes Coding ein:

Coding

Schließlich muss noch eine Zuordnung zwischen dem Exceptionsfeld des Layouts und der Tabelle hergestellt werden und der Ampel steht nichts mehr im Wege:

Coding

Noch ein Hinweis: Es ist im Prinzip egal ob ihr die Zuordnung vor dem Select bzw. vor der Modifikation der Tabelle durchführt (ich habe es gleich am Beginn des Unterprogramms zusammen mit den anderen Layout-Eigenschaften getan). Wichtig ist nur (keine Ahnung wieso), das die Bezeichnung 'TRAFFIC_LIGHT' großgeschrieben wird, sonst funktioniert das Ganze Ding nicht. Komisch, ist aber so.

Und jetzt wird noch die Zeile eingefärbt

Im Prinzip genau dasselbe Spiel wie beim Exception Feld. Auch hier ist die Struktur anzupassen und anschließend die Tabellenzeilen zu modifizieren. Wir erweitern also nochmals die Tabellenstruktur:

Coding

Anschließend legen wir wieder ein Kriterium fest, wann eine Zeile in welcher Farbe eingefärbt werden soll. Der Farbencode (wie auch aus der Definition erkennbar) besteht aus 4 Kennzeichen:

  • Char 1 – C (als Farbkennzeichnung also COLOR)
  • Char 2 – Farbcode zwischen 1 und 7
  • Char 3 – Intensiv An/Aus – 1 = an / 0 = aus
  • Char 4 – Inverse Darstellung An/Aus – 1 = an / 0 = aus

Wir wählen einmal die Farbe 5 aus, mit Intensivdarstellung und Invers, also C511. Wie wollen alle Flüge einfärben, wieder hat ein Manager so eine Phobie, das alle Flüge, deren Buchungseinnahme 50.000 Währungseinheiten unterschreitet mittels dieser Farbe dargestellt werden sollen. Also tun wir das:

Coding

Ich habe dieses Coding direkt unter der Exception eingebaut. Ja klar, die erfahrenen Programmierer – oder die Klugscheisser unter euch ;-) kleiner Scherz – werden sagen: Das könnte man doch gleich im ersten Loop auch einbauen. Vollkommen richtig, aber das ist ein Tutorial und deshalb muss ja nicht alles voll optimiert sein.

Zu guter letzt müssen wir wiederum das Feld in der Tabelle dem Feld im Layout zuordnen, das diesmal heißt: Falsch, das heißt nämlich:

Coding

Achtung: wieder auf die Großschreibung achten.

Zusammenfassung

Ein relativ kurzes, aber wie ich meine farbenprächtigen Kapitel. In diesem Kapitel haben wir das Layout des ALV Grid so angepasst, das auf Basis von bestimmten Kriterien, einerseits eine Ampelfarbe angezeigt wird. Wir können hier standardmäßig zwischen Rot, Gelb und Grün (also die Ampelfarben) wählen und wir können zusätzlich noch einzelne Zeilen oder alle Zeilen – was aber die Sinnhaftigkeit dieser Aktion in Frage stellt – mit einer Zeilenfarbe unterlegen. Hier ist die Bandbreite der Farbgebung schon wesentlich freizügiger.

Änderung der Flugdaten

Nun ist es auch schon wieder soweit. Wer das ganze Tutorial bis hierher durchgearbeitet hat, der hat erstens wirklich Durchhaltevermögen bewiesen und zweitens auch hoffentlich von diesem profitiert. Falls nicht, dann tut es mir leid um die verschwendete Zeit. Aber zum Schluss kommt noch, um in der Kochsprache bzw. Cooking language zu bleiben, der Zuckerguss. Wir, die Entwickler oder Programmierer dieses Spitzenprogramms, gewähren dem Benutzer noch die Gnade, das er via des ALV Grid Einträge verändern darf. Und das ohne 3 mal gefragt zu werden: Wollen Sie den Eintrag wirklich ändern. Also auf zum letzten Akt.

Vorbereitungen für die Flugänderung

Und um gleich in der Kochsprache zu bleiben, bereiten wir unsere Zutaten mal vor:

  • 1 neues Dynpro (0200), indem wir die Werte eintragen und ändern können
  • 1 neue Struktur, das als Verbindung zwischen den Daten im ALV Grid und dem neuen Dynpro dient
  • 1 Unterprogramm, das die selektierte Zeile im ALV Grid ausliest und an das neue Dynpro zur Änderung übergibt
  • 1 Funktion für den Event Handler, um das neue Dynpro aufzurufen
  • 1 Unterprogramm, das die geänderten Daten auf die Tabelle schreibt und den ALV Grid auffrischt, um die geänderten Daten anzuzeigen

Ich denke, damit sollte es möglich sein, unseren Zuckerguss für den ALV Grid umzusetzen. Somit frisch ans Werk.

Bevor wir das Dynpro anlegen, erstellen wir eine Struktur, welche die Verbindung zwischen Dynpro und ALV Grid ist. Wir legen diese Struktur wieder global an:

Coding

Das Änderungsdynpro 0200

Als nächstes legen wir ein Dynpro an, dass wir mit der Nummer 0200 versehen. Wir übernehmen alle Einstellungen wie vorgeschlagen und sichern das neue Dynpro – eventuell mit einer sprechenden Kurzbeschreibung. Danach gehen wir wieder einmal in den grafischen Screenpainter mittels Button Layout und sehen einmal eine (wahrscheinlich) gähnend graue Screen.

Nun übernehmen wir die neue Struktur (die wir soeben angelegt, gesichert und aktiviert haben) in dieses Dynpro auf folgende Weise. Wir öffnen das sog. Dict/Programmfelder-Fenster.

Dictionary Felder

Nun geben wir in das Feld Tabellen-/Feldname den Namen der neuen Struktur ein und klicken auf Holen aus Programm. Es sollte nun folgendes Fenster erscheinen:

Übernahme Felder ins Dynpro

Nun übernehmen wir alle Felder, indem wir alle Zeilen markieren und klicken auf OK. Anschließend platzieren wir die Felder auf der noch bis vor kurzen leeren Dynpro-Oberfläche. Danach vergeben wir links neben den Datenfeldern noch schöne Beschreibungen und schon sollte das Dynpro in etwa so aussehen:

Änderungsdynpro

Damit der Benutzer nun Änderungen durchführen bzw. abbrechen kann, müssen noch 2 Button eingebaut werden:1 Button zum Speichern und 1 zum Abbrechen:

Buttons für Dynpro

Nicht vergessen, den Buttons auch entsprechende Funktionscodes zuzuweisen. Beispielsweise SAVE für Speichern und CANCEL für Abbrechen. Zum Schluss müssen wir in der Elementliste noch das OK-Feld den Namen OK_CODE zuweisen.

Aufruf der Änderungsdynpro

Auch das hatten wir schon mal: 1 Dynpro das noch nichts tut, außer Speicherplatz zu verbrauchen. Aber dem Werden wir gleich Abhilfe schaffen. Der Button, der das Änderungsdynpro aufrufen soll existiert in der Toolbar und wir müssen nun über den Event Handler dem Programm sagen, das die markierte Zeile auszulesen ist und an das Dynpro zu übergeben ist und anzuzeigen ist. Also machen wir das ganz einfach.

Bisher hatten wir einen Platzhalter, indem bei Drücken des Change-Button das Programm verlassen wird. Wir ersetzen nun in der Methode handle_user_command diesen Befehl durch folgendes Coding:

Coding

Wie beim vorherigen Kapitel wird hier zuerst die Methode get_selected_rows ausgeführt um die ausgewählte Zeile zu erhalten. Anschließend überprüfen wir, ob der Benutzer auch wirklich eine Zeile selektiert hat und falsch ja, führen wir das Unterprogramm change_data aus, dem wir die selektierte Zeile mitgeben.

Nun ein Doppelklick auf change_data und das neue Unterprogramm erstellen. Auch hier ist zuerst die Struktur lvc_s_row für den Platzhalter einzutragen (das kennen wir doch schon von irgendwoher, oder?) und folgendes Coding zu implementieren:

Coding

Wiederum ähnlich zum Flugbuchungen-Kapitel wird hier nun aus der internen Tabelle gt_sflight die entsprechende Zeile ausgelesen und an die Struktur übergeben, die anschließend an die Verbindungsstruktur transferiert wird. Abschließend wird das Dynpro aufgerufen, das ja nun die Information der Datenstruktur enthält.

Aber Vorsicht: das Programm noch nicht ausführen, da noch kein PAI-Prozess definiert ist, um das Dynpro zu verlassen. Also in das Dynpro springen, den Kommentar-Stern vor MODULE USER_COMMAND_0200 entfernen und Doppelklick. Das neue Modul anlegen und mit folgenden Coding versehen:

Coding

Sofern Ihr ebenfalls den Funtionscode CANCEL für den Abbrechen-Button vergeben habt dann 1:1 übernehmen, ansonsten den von euch definierten Code eintragen. Zum Unterprogramm save_changes kommen wir sofort.

Erfasste Änderungen Speichern und den ALV Grid auffrischen

Im Augenblick öffnen wir den Änderungsschirm, Verzeihung Änderungsdynpro und zeigen die Daten an. Alle Änderungen die der Benutzer durchführt werden noch nicht auf die Datenbanktabelle geschrieben und daher auch nicht aktiv. Nun implementieren wir das Unterprogramm save_changes, das die DB-Tabelle aktualisiert, den Änderungsschirm schließt und das ALV Grid aktualisiert.

Doppelklick auf save_changes und folgendes Coding anfügen:

Coding

Sieht ziemlich unspektakulär aus, ist es aber nicht. Wir übertragen im ersten Schritt die Daten aus dem Dynpro (also in der Struktur g_screen200) auf unsere gewohnte sflight-Struktur. Danach wird die DB-Tabelle sflight aktualisiert. Abhängig davon ob nun die Aktualisierung erfolgreich durchgeführt werden konnte oder nicht wird die Änderung auch tatsächlich auf der Datenbank durchgeführt oder nicht. Bei erfolgreicher Änderung wird ALV Grid mittels Unterprogramm load_data_into_grid neu geladen, die Ampeln aktualisiert, die Zeilenfärbung durchgeführt und die Daten neu angezeigt. Abschließend wird der Bildschirm verlassen und der Originaldynpro wieder angezeigt. Sollte keine Änderung durchgeführt werden können, wird eine Warnung ausgegeben, das keine Änderung durchgeführt wurde und der Benutzer kann seine Änderung nochmals versuchen oder mittels Abbrechen den Änderungsschirm verlassen.

Zusammenfassung

Ende gut, Alles gut? Im letzten Kapitel haben wir also noch ein Änderungsdynpro eingebaut, bei dem der Benutzer Änderungen der Flüge durchführen kann, die nach der Aktualisierung auf der Datenbank im ALV Grid sofort wieder angezeigt werden bzw. bei Nichtdurchführung der Aktualisierung wird eine Meldung ausgegeben.

Noch ein paar Worte zum Schluss

Mir ist natürlich klar, das einige Dinge wesentlich performanter bzw. schöner programmiert werden können, aber mir ging es bei dieser Anleitung bzw. Empfehlungen um das Verständnis und ich denke der Aufbau und Ablauf ist recht schön gelungen (ohne mich natürlich selbst loben zu wollen ;-)).

Ich möchte mich nochmals im speziellen bei Henrik Frank bedanken, dem ich einen großen Teil dieses Beispiels verdanke und mich auch zum größten Teil an seine Vorlage gehalten habe. Sein Beispiel ist auf der Internetseite http://www.erpgenie.com/sap/abap/controls/alvgrid.htm zu finden. Leider funktioniert dieser Link (Stand 19. Oktober 2021) aktuell nicht (mehr). Zusätzlich gibt es wirklich gute Beispiele im Paket SLIS und hier wiederum die Programme BCALV_GRID_01 - BCALV_GRID_11. Ich habe bewusst das gesamte Coding NICHT in diesem Dokument integriert, da ich die Versuchung kenne, mal einfach ein Programm zu erstellen und das Coding reinzuwerfen, um mal zu sehen was passiert. Falls ihr aber doch einmal das Bedürfnis habt, das gesamte Coding als Datei zu bekommen, dann gerne melden.

Sollte es von eurer Seite Anregungen, Probleme oder sogar Beschwerden geben, dann behaltet sie bitte für euch. Nein, Scherz beiseite, dann einfach bei mir melden oder im SDN unter http://sdn.sap.com im Forum nachsehen.

Autor

Dieses Dokument wurde im Februar 2009 von Dipl.-Ing. (FH) Robert Lang erstellt.

Voraussetzungen

Diese Anleitung wurde auf einem SAP-System mit Releasestand ECC6.0 ( Support Package SAPKB70016) umgesetzt. Der ALV Grid Control ist allerdings ab Releasestand 4.6C einsetzbar und daher sollten die Ausführungen auch ab diesem Releasestand umsetzbar sein. Dieses wurde allerdings nicht getestet.

We use cookies
Diese Webseite verwendet Cookies. Einige dieser Cookies sind unbedingt notwendig für den Betrieb, während andere zur Verbesserung der Benutzung bzw. zur Aufzeichnung von Userverhalten (sogenannte Tracking Cookies) dienen. Sie haben die Möglichkeit, den Einsatz dieser Cookies zu untersagen. Leider kann dann die Webseite nicht benutzt werden und Sie werden auf eine Informationsseite für Cookies weitergeleitet.