Upload
others
View
4
Download
0
Embed Size (px)
Citation preview
Bonn � Boston
Enno Wulff, Maic Haubitz, Dennis Goerke, Sascha Seegebarth, Udo Tönges
Das ABAP®-Kochbuch
Erfolgsrezepte für Entwickler
5
Auf einen Blick
1 Grundlagen der Anwendungsprogrammierung ...... 25
2 Mit Tabellenpflegedialogen arbeiten ..................... 39
3 Viewcluster verwenden .......................................... 85
4 Dialog erstellen ....................................................... 109
5 Komponenten wiederverwenden ............................ 191
6 Mit dem TextEdit Control arbeiten ........................ 221
7 Mit dem Applikationslog arbeiten ......................... 247
8 Änderungsbelege verwenden ................................. 279
9 Mit Tree Controls arbeiten ..................................... 295
10 Dynamische Dokumente verwenden ...................... 337
11 Controls in Dialog einbauen ................................... 349
12 Frameworks verwenden .......................................... 357
13 ALV Grid erstellen ................................................... 379
14 Drag & Drop implementieren ................................. 433
15 Formulare erstellen ................................................. 465
16 Generische Objektdienste verwenden .................... 485
17 E-Mails versenden .................................................. 497
18 Dynamisch programmieren ..................................... 525
19 Personalisierung verwenden ................................... 579
20 Mit Webservices auf das SAP-System zugreifen ... 599
7
Inhalt
Vorwort .................................................................................... 15Einleitung .................................................................................. 18
1 Grundlagen der Anwendungsprogrammierung ...... 25
1.1 Entwurfsmuster ....................................................... 251.2 Entwicklungsumgebung .......................................... 261.3 Anforderungen an SAP-Programme ......................... 291.4 Vorhandenes clever nutzen ..................................... 321.5 Kosten-Nutzen-Verhältnis ....................................... 331.6 Planung einer Anwendung ...................................... 341.7 Dokumentation ...................................................... 341.8 Teamarbeit ............................................................. 35
2 Mit Tabellenpflegedialogen arbeiten ...................... 39
2.1 Datenmodell erarbeiten .......................................... 402.2 Tabellenpflegegenerator ......................................... 46
2.2.1 Berechtigungsgruppen ............................... 462.2.2 Funktionsgruppe ....................................... 462.2.3 Pflegebilder ............................................... 472.2.4 Generierung des Pflegedialogs ................... 482.2.5 Texttabellen anlegen ................................. 482.2.6 Pflegetransaktion anlegen .......................... 522.2.7 Kategorientabelle erstellen ........................ 54
2.3 Adressdatenpflege integrieren ................................. 552.4 Zeitpunkte .............................................................. 57
2.4.1 Anlegen eines Pflege-Views ....................... 582.4.2 Zeitpunkt 05: Hinzufügen eines
neuen Eintrags ........................................... 622.4.3 Zeitpunkt 21: Versorgen von
verborgenen Feldern ................................. 642.4.4 Zeitpunkt 23: vor dem Aufruf des
Adresspflegebildes ..................................... 642.4.5 Zeitpunkt 19: nach Initialisieren
globaler Variablen ..................................... 652.5 Stolperfallen und Hilfestellungen ............................ 69
Inhalt
8
2.6 Einzelne Datensätze gezielt pflegen ......................... 722.6.1 Funktionsbaustein
VIEW_MAINTENANCE_CALL ..................... 722.6.2 Funktionsbaustein
VIEW_MAINTENANCE_SINGLE_ENTRY ..... 732.7 Zeitabhängige Pflege-Views ..................................... 742.8 Berechtigungen ....................................................... 782.9 Änderungen am Pflegedialog vornehmen ................ 78
2.9.1 Felder hinzufügen oder entfernen .............. 792.9.2 Änderung der Speicherart .......................... 802.9.3 Dynpros nachbearbeiten ............................ 812.9.4 Table Control vergrößern ........................... 82
3 Viewcluster verwenden ........................................... 85
3.1 Viewcluster definieren ............................................. 863.2 Abhängige Einträge definieren ................................. 933.3 Viewcluster per Programm aufrufen ......................... 993.4 Zeitpunkte ............................................................... 100
4 Dialog erstellen ....................................................... 109
4.1 Datenbanktabelle erstellen ...................................... 1104.2 Suchhilfe anlegen .................................................... 113
4.2.1 Eingabehilfe einrichten ............................... 1164.2.2 Elementare Suchhilfe einrichten ................. 1204.2.3 Suchhilfe erweitern .................................... 1234.2.4 Eigenen Suchhilfe-Exit anlegen ................... 1284.2.5 Datensätze aus der Ergebnismenge löschen 1344.2.6 Sammelsuchhilfe verwenden ...................... 135
4.3 Modulpool anlegen ................................................. 1394.4 Dictionary-Struktur für die Dynpros erstellen ........... 1414.5 Optionen zur Einbindung von Datenstrukturen ........ 143
4.5.1 TYPE-Referenzierung .................................. 1454.5.2 INCLUDE-Befehl ........................................ 1484.5.3 Inkludierung unter Verwendung eines
Gruppennamens ......................................... 1484.5.4 Umbenannte Includes ................................ 1504.5.5 Umbenannte Includes unter Verwendung
eines Gruppennamens ................................ 1534.6 Dynpros anlegen ..................................................... 155
Inhalt
9
4.7 Abhängige Listboxen .............................................. 1624.8 Transaktion anlegen ................................................ 1644.9 Felder ein- und ausblenden .................................... 165
4.9.1 Feldeigenschaften ändern .......................... 1654.9.2 Laufzeitkomprimierung .............................. 171
4.10 Änderungen erkennen ............................................ 1744.11 Daten sichern ......................................................... 1774.12 TextEdit Control für die Texteingabe implementieren 185
5 Komponenten wiederverwenden ............................ 191
5.1 Wiederverwendbares Wissen sammeln ................... 1935.2 Ableiten oder parametrisieren? ............................... 1955.3 Enjoy Control kapseln ............................................. 196
5.3.1 Eigenen Button erstellen ............................ 1965.3.2 Basisklasse erstellen ................................... 1995.3.3 Komponente einbinden ............................. 2045.3.4 Enjoy-Komponenten spezialisieren ............ 206
5.4 Subscreen kapseln .................................................. 2095.4.1 Standortanzeige kapseln ............................ 2095.4.2 Subscreen anlegen ..................................... 2145.4.3 Funktionsbaustein testen ........................... 2155.4.4 Subscreen in Programm einbauen .............. 216
5.5 Enjoy Control »andocken« ....................................... 2185.6 Verwaltung von Reuse-Funktionen ......................... 219
6 Mit dem TextEdit Control arbeiten ........................ 221
6.1 Datenhaltung und Model ........................................ 2226.1.1 Dictionary-Objekte anlegen ....................... 2226.1.2 Model-Klasse anlegen ............................... 223
6.2 Controller anlegen .................................................. 2326.2.1 Anlegen der Controller-Klasse ................... 2326.2.2 Weitere Attribute anlegen ......................... 2336.2.3 Weitere Methoden des Controllers ............ 240
6.3 Testprogramm entwickeln ....................................... 240
7 Mit dem Applikationslog arbeiten .......................... 247
7.1 Schnittstelle ............................................................ 2477.2 Begriffsklärung ........................................................ 248
Inhalt
10
7.3 Transiente Protokolle .............................................. 2497.4 Persistente Protokolle .............................................. 251
7.4.1 Objekt und Unterobjekt anlegen ................ 2527.4.2 Zugriffsklassen anlegen ............................... 254
7.5 Protokolle mit Callbacks .......................................... 2677.6 Nachrichten mit Kontext ......................................... 2727.7 Protokollausgabe anpassen ...................................... 2737.8 Erweiterte Möglichkeiten des Applikationslogs ........ 277
8 Änderungsbelege verwenden .................................. 279
8.1 Datenelemente als änderungsrelevant markieren ..... 2808.2 Änderungsbelegobjekt anlegen ................................ 2818.3 Generierung des Verbuchers .................................... 2838.4 Analyse der generierten Objekte ............................. 2858.5 Testprogramm ......................................................... 2888.6 Tipps zur Arbeit mit Änderungsbelegen ................... 291
8.6.1 Komplexe Änderungsbelegobjekte ............. 2918.6.2 Aufbereitung, Anzeige und Archivierung .... 292
9 Mit Tree Controls arbeiten ...................................... 295
9.1 Tree-Typen .............................................................. 2959.1.1 Historische Entwicklung der
Baumdarstellung ........................................ 2959.1.2 Hilfestellung bei der Wahl und der
Implementierung der Tree-Typen ............... 3029.2 Einheitliches Interface anlegen ................................ 3039.3 Baumdarstellung erzeugen ....................................... 312
9.3.1 Anforderungen ........................................... 3129.3.2 Passendes Tree Control für die
Ticketanwendung wählen ........................... 3139.3.3 Klasse für den Teambaum erstellen ............ 316
9.4 Tree Control testen .................................................. 332
10 Dynamische Dokumente verwenden ...................... 337
10.1 Statusanzeige aufbauen ........................................... 34010.2 Klasse für die Ereignisbehandlung erstellen .............. 34410.3 Programmlokale Klassen importieren ....................... 346
Inhalt
11
11 Controls in Dialog einbauen .................................... 349
11.1 HTML-Buttons einbauen ......................................... 34911.2 Standorte-Subscreen einbauen ................................ 354
12 Frameworks verwenden .......................................... 357
12.1 Klasse zur Ereignisbehandlung ................................ 35812.2 Schubladen verwenden ........................................... 36012.3 Eigenes Framework entwickeln ............................... 36612.4 Framework verwenden ........................................... 375
13 ALV Grid erstellen ................................................... 379
13.1 Funktionen des SAP List Viewers ............................ 37913.1.1 Darstellungsarten ...................................... 380
13.2 Grundlagen und Vorarbeiten zur Erstellung eines ALV Grid Controls .......................................... 38213.2.1 Layoutstruktur ........................................... 38313.2.2 Layoutvarianten ......................................... 38413.2.3 Feldkatalog ................................................ 38513.2.4 Styles ........................................................ 38713.2.5 Pufferkonzept ............................................ 38813.2.6 Änderbarkeit des ALV Grids ....................... 38913.2.7 Globale Tabellen ....................................... 39013.2.8 Verwendung von Ereignissen ..................... 390
13.3 Tabellarische Übersicht erstellen ............................. 39213.3.1 Selektionsparameter an Klasse
übergeben ................................................. 39313.3.2 Erstellen eines Reports für die
Ticketübersicht .......................................... 39813.3.3 Erstellen eines Interfaces für die
Ereignisbehandlung ................................... 40813.3.4 Eigene Klasse als Verschalung des
Controls erstellen ...................................... 40913.3.5 Dictionary-Struktur für die ALV-Anzeige
anlegen ..................................................... 41113.3.6 Methoden anlegen und implementieren .... 41213.3.7 Implementieren der Ereignisbehandler ...... 422
13.4 Ergebnis der implementierten Funktionen ............... 428
Inhalt
12
14 Drag & Drop implementieren .................................. 433
14.1 Grundlagen ............................................................. 43314.1.1 Begriffe ...................................................... 43514.1.2 Drag-&-Drop-fähige Objekte ...................... 43714.1.3 Ereignisse für Drag & Drop ......................... 439
14.2 Funktionsweise und Ablauf ...................................... 44014.2.1 Ablauf des Drag & Drop ............................. 44014.2.2 Datenübertragung ...................................... 441
14.3 Beispielanwendung: Drag & Drop in Teambaum und Ticketübersicht ................................................. 44214.3.1 Integrieren des Teambaums in die
Ticketübersicht ........................................... 44314.3.2 Vorbereiten der Datenübertragung ............ 44514.3.3 Anpassung des Teambaums ........................ 45214.3.4 Anpassung der Ticketübersicht ................... 457
15 Formulare erstellen ................................................. 465
15.1 Möglichkeiten der Formularerstellung ..................... 46515.2 Formularerstellung mit SAP Smart Forms ................. 46815.3 Umsetzung des Formularentwurfs ............................ 469
15.3.1 Vorbereitung der Übergabestruktur ............ 46915.3.2 Elemente des SAP Form Builders ................ 47015.3.3 Formular anlegen ....................................... 47115.3.4 Logo dynamisch einbinden ......................... 47215.3.5 Druck des Dokuments ................................ 482
16 Generische Objektdienste verwenden .................... 485
16.1 Umgang mit generischen Objektdiensten ................ 48516.2 Generische Objektdienste in eigene Programme
einbinden ................................................................ 48816.2.1 Business-Object-Repository-Objekt
anlegen ...................................................... 48816.2.2 Generische Objektdienste für ein Objekt
aufrufen ..................................................... 49116.3 Ablage der GOS-Anlagen ......................................... 496
Inhalt
13
17 E-Mails versenden ................................................... 497
17.1 Einfacher E-Mail-Versand ....................................... 49817.2 Versand einer E-Mail innerhalb der
Ticketbearbeitung ................................................... 50217.2.1 Auslesen der E-Mail als Text ...................... 50317.2.2 Implementierung der Methode
CREATE_MAIL_DIALOG ............................ 50717.3 E-Mail-Versand als Hintergrundverarbeitung ........... 509
17.3.1 SAP-Link erzeugen .................................... 50917.3.2 Erzeugen einer E-Mail mit Anhang im
Hintergrund ............................................... 51117.3.3 Anschreiben einbinden/Nutzung von
Templates .................................................. 51517.4 E-Mails als Smart-Forms-Dokument versenden ....... 51817.5 E-Mail mit Anhängen versenden ............................. 523
18 Dynamisch programmieren ..................................... 525
18.1 Ansätze und Stufen der dynamischen Programmierung ..................................................... 526
18.2 Einzelnes Feld definieren ........................................ 53018.2.1 Daten übergeben ...................................... 53318.2.2 Werte prüfen ............................................. 53418.2.3 Schaltflächen ausblenden .......................... 53418.2.4 Programmlogik »austricksen« ..................... 53518.2.5 Programm zur Eingabe eines
einzelnen Wertes ....................................... 53518.2.6 Programm zur Eingabe mehrerer Felder ..... 538
18.3 Variable Felder definieren ....................................... 54318.3.1 Variable Felder verwenden ........................ 54418.3.2 Variable Feldwerte speichern ..................... 546
18.4 Mehrere Felder definieren ...................................... 54718.4.1 Dynamische Variablen definieren ............... 54818.4.2 Daten in das ABAP-Memory exportieren ... 55018.4.3 Funktionen kapseln ................................... 55118.4.4 Erfassung der variablen Werte einbauen .... 558
18.5 Interne Tabelle dynamisch erstellen ........................ 56118.6 Mehrere Werte erfassen ......................................... 568
18.6.1 Dynamische Datenerfassung kapseln ......... 56918.6.2 Einbau der dynamischen Datenerfassung ... 576
Inhalt
14
19 Personalisierung verwenden ................................... 579
19.1 Personalisierungsobjekt anlegen .............................. 58019.2 Struktur definieren .................................................. 58319.3 Dialogbaustein erstellen .......................................... 58419.4 Anwendung personalisieren ..................................... 591
20 Mit Webservices auf das SAP-System zugreifen .... 599
20.1 SOAP-Webservice erstellen ..................................... 60120.1.1 Funktionsgruppe ZBOOK_HTTP anlegen .... 60120.1.2 Funktionsbausteine erstellen ...................... 60220.1.3 Webservice für die Funktionsgruppe
generieren .................................................. 60420.1.4 Konfiguration des Webservices im
SOA-Management ..................................... 609
A Wiederkehrende Arbeitsschritte ........................................ 613A.1 Tastenkombinationen und Funktionstasten .............. 613A.2 Transportaufträge .................................................... 614A.3 ABAP Workbench verwenden .................................. 618A.4 Programm anlegen .................................................. 619
A.4.1 Programm anlegen mit Transaktion SE80 ... 619A.4.2 Programm anlegen mit Transaktion SE38 ... 620A.4.3 Programmeigenschaften erfassen ................ 620A.4.4 Unterobjekte von Programmen .................. 622
A.5 Dynpros anlegen und erweitern ............................... 623A.5.1 Custom-Control-Bereich erstellen ............... 623A.5.2 Resizing aktivieren ..................................... 625
A.6 Funktionsgruppe anlegen ........................................ 629A.7 Funktionsbaustein anlegen ...................................... 630A.8 Klasse und Methoden anlegen ................................. 633A.9 Datenelement anlegen ............................................ 634A.10 Domäne anlegen ..................................................... 636A.11 Tabelle anlegen ....................................................... 637A.12 Transaktionen anlegen ............................................. 643
B Die Autoren ....................................................................... 645
Index ........................................................................................ 647
18
Einleitung
Programmierbücher gibt es wie Sand am Meer. Auch Bücher überProgrammierkonzepte, Programmiermethoden sowie die Wartungund Weiterentwicklung von Applikationen findet man zuhauf. Fürden SAP-Bereich gibt es eine ganze Reihe Bücher, die dem LeserGrundlagen und Konzepte der ABAP-Programmierung nahebringenmöchten. Warum schreiben wir nun noch ein Buch über SAP-Pro-grammierung? Die Antwort ist einfach: Es gibt aus unserer Sicht nochkein Buch, das die wichtigsten und am einfachsten nutzbaren Pro-grammierwerkzeuge in einem SAP-System aus Programmierersichtbeleuchtet. Die meisten Programmierhandbücher zeigen sehrumfangreich und in großer Detailtiefe, wie Befehle angewandt wer-den und welche Befehlszusätze es gibt. Wir konzentrieren uns in die-sem Buch auf die in der Praxis am häufigsten eingesetzten Befehleund Tools. Darüber hinaus möchten wir Ihnen zeigen, warum dieseWerkzeuge verwendet werden sollten und für welche alltäglichenAufgaben welche Hilfsmittel am einfachsten nutzbar sind.
Einfache Konzepte Dabei geht es uns nicht um besonders anspruchsvolle Konzepte odersensationelle Ergebnisse. Es geht uns darum, zu zeigen, wie einfacheinige Dinge zu realisieren sind. Und es geht uns darum, wirkungs-volle Konzepte vorzustellen, die einerseits die Entwicklung undandererseits auch die Wartung vereinfachen. Wir werden immerwieder auf die Schlagworte Modularisierung und Wiederverwendbar-keit zurückkommen. Beides sind Konzepte, die in der Programmie-rung heute eigentlich selbstverständlich sein sollten. Dadurch, dassin SAP-Systemen jedoch fast ausschließlich Sonderlösungen entwi-ckelt werden, gerät der Leitgedanke der leichten Wiederverwendbar-keit leicht aus dem Fokus. Die Komplexität des SAP-Systems macht esnicht einfacher, zu erkennen, wo gleiche oder ähnliche Funktionenwie die bereits existierenden oder programmierten einsetzbarwären.
VorausgesetzteKenntnisse
Dieses Buch richtet sich sowohl an erfahrene Programmierer, die gernean der einen oder anderen Stelle dazulernen möchten, als auch an Pro-
19
Einleitung
grammieranfänger, die sich dafür interessieren, wie bestimmte Dingerichtig und einfach programmiert werden können.
KochbuchDas Buch soll Ihnen als Arbeitsbuch, Nachschlagewerk und Ideenge-ber dienen. Wir werden in den folgenden Kapiteln Lösungen zeigenund Konzepte vermitteln, die Ihnen – und Ihren Kollegen – das Lebeneinfacher machen können. Notwendige Arbeitsschritte wie das Anle-gen bestimmter Objekte, die immer wieder durchgeführt werdenmüssen, werden in Anhang A, »Wiederkehrende Arbeitsschritte«,beschrieben. Wenn Sie sich schon etwas in der Entwicklungsumge-bung des SAP-Systems auskennen, werden Sie die Anweisungen indiesem Buch auch ohne Hilfe des Anhangs leicht nachvollziehen kön-nen. Sollten Sie bei einer Anweisung nicht genau wissen, wie diese zuverstehen ist, können Sie auf die detaillierte Anleitung anhand einesBeispielobjekts im Anhang zurückgreifen. Mit diesem Konzept hoffenwir, Ihnen die Lektüre des Buches möglichst einfach zu gestalten.
RezepteDieses Buch heißt Kochbuch. Es enthält Rezepte zum Nachkochen. Wirlegen bei den Rezepten besonderen Wert darauf, dass Sie verstehen,warum die vorgestellten Zutaten sinnvoll sind, und darauf, dass Sieihr Zusammenwirken erkennen. Der Titel soll deutlich machen, wasSie erwartet: eine Sammlung von Rezepten für den täglichen Bedarf.Sie können jedes Kapitel separat bearbeiten. In einigen Kapitelnbeziehen wir uns explizit auf andere Kapitel oder Abschnitte. Damitaber genug der Kochmetaphern und zurück zum Programmieren.
TicketsystemDie Lösungen und Konzepte, die wir in diesem Buch für Sie beschrei-ben, sind nach unserer Erfahrung in vielen Applikationen enthaltenbzw. könnten viele bereits bestehende Programme bereichern undSie können sie im Downloadbereich zu diesem Buch auf www.sap-press.de herunterladen. Wir wollten diese Elemente in diesem Buchnicht einfach nur aneinanderreihen, sondern haben uns eine Bei-spielanwendung ausgedacht, in der alle Elemente ihren Platz haben.Diese Beispielanwendung ist ein Ticketsystem: Es können Serviceti-ckets erfasst werden, und innerhalb eines Tickets können verschie-dene Aktionen durchgeführt werden.
Auf den folgenden Seiten werden Sie zusammen mit uns diese inunseren Augen typische Anwendung erstellen. Ein Ticketsystem isteine praxisnahe Anwendung, die keinerlei Fachwissen über einzelneModule voraussetzt. Es sollte daher für jedermann verständlich undnachvollziehbar sein.
20
Einleitung
Diese Beispielanwendung wird an vielen Stellen stark vereinfachtsein und ist nicht dazu gedacht, vollständig in einem System einge-setzt zu werden. Zugunsten der Verständlichkeit verzichten wir aufFehlerbehandlungen. Einige Funktionen müssten für eine sinnvolleVerwendung besser ausprogrammiert werden. Wir gehen nichtexplizit darauf ein, welches Feld ein Muss-Feld ist oder welche Felderin bestimmten Situationen nicht geändert werden dürften. Das sollSie jedoch nicht stören, denn Sie werden den Sinn und Zweck dereinzelnen Anwendungsbestandteile verstehen. Zu einer ausgereiftenAnwendung gehören mehr Bestandteile, als wir hier im Rahmeneines Arbeitsbuches präsentieren können.
Aufbau des Buches In Kapitel 1, »Grundlagen der Anwendungsprogrammierung«, er-fahren Sie, was Sie vor und während der Entwicklung einer Anwen-dung im Allgemeinen und einer SAP-Anwendung im Speziellen be-denken sollten.
In Kapitel 2, »Mit Tabellenpflegedialogen arbeiten«, erstellen Sieeine Tabelle mit dem entsprechenden Tabellenpflegedialog. Wahr-scheinlich haben Sie bereits mit dieser Form der Datenpflege zu tungehabt? Wir zeigen Ihnen, wie einfach das Erstellen eines Tabellen-pflegedialogs ist, und zusätzlich verraten wir Ihnen, wie Sie den Dia-log »pimpen« können. Zu den Tabellenpflegedialogen gehören fastunweigerlich die Viewcluster. Mit Tabellenpflegedialogen kannjeweils eine Tabelle bearbeitet werden, oftmals hängen jedoch meh-rere Tabellen zusammen. Mit Viewclustern können Sie diese Bezie-hungen definieren und die Daten komfortabel bearbeiten. Wie dasgeht, erfahren Sie in Kapitel 3, »Viewcluster verwenden«. Die Pfle-gedialoge dienen uns dazu, Grundeinstellungen für die Beispielan-wendung vornehmen zu können.
Der eigentlichen Anwendung widmen wir uns in Kapitel 4, »Dialogerstellen«. Hier legen wir den Grundstein für alle weiteren Program-mierschritte in diesem Buch. Der Ticketdialog wird ein einfaches Pro-gramm mit dem Zweck, Ticketdaten zu erfassen und zu ändern. Eswird einige Ein- und Ausgabefelder geben und eine Funktion zumSpeichern des Tickets.
Die zentralen Grundideen in diesem Buch sind Modularisierung undWiederverwendbarkeit. In Kapitel 5, »Komponenten wiederverwen-den«, erklären wir, was wir uns darunter vorstellen und was unswichtig erscheint. Sie werden zwei eigenständige Module erstellen.
21
Einleitung
Das erste Modul wird eine besondere Schaltfläche auf HTML-Basissein, die Sie in den Dialog einbinden werden. Als Nächstes erstellenSie ein Modul mithilfe eines Subscreens in dem verschiedene aus-wählbare Standorte angezeigt werden.
Auch die darauffolgenden Kapitel sind den Themen Modularisierungund Wiederverwendbarkeit gewidmet. In Kapitel 6, »Mit dem Text-Edit Control arbeiten«, werden Sie ein Modul entwickeln, das jeweilsden aktuellen Meldungstext an den bereits vorhandenen anhängtund speichert. In Kapitel 7, »Mit dem Applikationslog arbeiten«,wird es ebenfalls um Meldungen gehen, allerdings in Form eines Pro-tokolls: dem Anwendungslog, einem Standardhilfsmittel in vielenSAP-Transaktionen. Mit dem Log können Sie Meldungen sammeln,speichern und in vielfältiger Weise aufbereitet darstellen. Ein Tool,das Sie unbedingt kennen sollten!
Änderungsbelege sind kein wirklich spannendes Thema. Schon garkein Thema, dem man viele Geheimnisse entlocken könnte. Wirhaben uns jedoch entschlossen, die Änderungsbelege mit in das Buchaufzunehmen, da sie zur Anwendungsentwicklung gehören. Undwer weiß, vielleicht erfahren Sie in Kapitel 8, »Änderungsbelege ver-wenden«, ja noch etwas Neues?
Wir fahren mit einem weiteren Modul fort, das wir in unsere An-wendung einbauen möchten. Sie werden in Kapitel 9, »Mit TreeControls arbeiten«, das Tree Control kennenlernen und mit diesemControl die Darstellung einer Teamstruktur programmieren. Wirwerden Sie umfassend über die Vor- und Nachteile sowie über dieUnterschiede der verschiedenen zur Verfügung stehenden Tree-Vari-ationen informieren. Das Tree Control werden wir in Kapitel 14,»Drag & Drop implementieren«, noch einmal erweitern.
Beim nächsten eingesetzten Modul geht es um ein Control, das Siebereits in Kapitel 5, »Komponenten wiederverwenden«, kennenler-nen: das HTML-Control. In Kapitel 10, »Dynamische Dokumenteverwenden«, beschäftigen wir uns mit der Anzeige und den Interak-tionsmöglichkeiten dynamischer Dokumente.
In Kapitel 11, »Controls in Dialog einbauen«, werden Sie die bishererstellten Module in das Hauptprogramm – den Ticketdialog – ein-bauen. Sie werden dabei sehen, wie einfach die Integration dererstellten Module ist.
22
Einleitung
Ein wenig bekanntes Control ist das als »Schubladen-Control« bezeich-nete vertikale Tabstrip. Diesen Exoten werden Sie in Kapitel 12, »Fra-meworks verwenden«, kennenlernen. Hier werden Sie ebenfalls bereitserstellte Module einbauen, und zwar mithilfe eines eigenständigen Fra-meworks, das ähnlich wie das Schubladen-Control funktioniert.
Kapitel 13, »ALV Grid erstellen«, möchten wir nutzen, um Ihneneinige Funktionen des ALV Grid Controls zu präsentieren. Sie wer-den einen Report anlegen, der die erstellten Tickets auflistet. Sie ler-nen verschiedene Layout- und Interaktionsmöglichkeiten kennen. InKapitel 14, »Drag & Drop implementieren«, lernen Sie, die Drag-&-Drop-Funktionalität in das bereits erstellte Tree Control zu imple-mentieren.
Bei einem Rundumschlag um die Grundfunktionen eines SAP-Systemsdürfen SAP Smart Forms nicht fehlen. Dabei handelt es sich um denNachfolger der ungeliebten SAPScript-Formulare. Kapitel 15, »Formu-lare erstellen«, führt Sie in die Erstellung eines Formulars ein. Sie wer-den sehen, dass es nicht so schwierig ist, wie Sie vielleicht denken.
Ein weiteres spannendes Standard-SAP-Hilfsmittel beschreiben wirin Kapitel 16, »Generische Objektdienste verwenden«. Dahinter ver-birgt sich eine Sammlung nützlicher Funktionen, um externe Doku-mente in einer Transaktion verwalten und ablegen zu können. Wirzeigen Ihnen, wie Sie Excel-Dateien, PDF-Dokumente und einfacheTexte oder Links mithilfe der generischen Objektdienste in IhreTicketanwendung einbinden.
Kommunikation ist wichtig. Wie eine Kommunikationsmöglichkeitzwischen den Anwendern des Dialogs technisch elegant in dasTicketsystem eingebunden werden kann, demonstrieren wir Ihnenin Kapitel 17, »E-Mails versenden«. Sie werden die Klassen zumE-Mail-Versand nutzen und ein mittels SAP Smart Forms erstelltesFormular versenden. Zudem zeigen wir Ihnen, wie Sie Zugriff auf dieüber generische Objektdienste Services importierten Dokumenteerhalten, um diese ebenfalls zu versenden.
Dynamische Programmierung ist ein Lieblingsthema von uns. Hierkann man als Programmierer zeigen, was man kann! Kapitel 18,»Dynamisch programmieren«, zeigt Ihnen, wie hilfreich dynami-sches Programmieren in der Praxis ist. Zudem zeigen wir Ihnen eineelegante Art der Datenerfassung und Datenspeicherung für dyna-misch erzeugte Daten.
23
Einleitung
Ein wenig bekanntes Hilfsmittel ist das Personalisierungs-Frame-work, mit dessen Hilfe Sie dem Anwender eine einfache Möglichkeitbieten, die Anwendung zu personalisieren. Wir werden Ihnen inKapitel 19, »Personalisierung verwenden«, zeigen, welche Vorteiledie Personalisierung für Sie und für den Anwender hat.
Kapitel 20, »Mit Webservices auf das SAP-System zugreifen«, sollaufzeigen, wie schnell ein Webservice erstellt ist. Ein Webservice istdie Voraussetzung für die Kommunikation zwischen Intranet undInternet. Mit einem Webservice können Sie z.B. die Anzahl der offe-nen Tickets, die ein Kollege noch zu bearbeiten hat, in Ihrem Firmen-portal darstellen.
Hinweise zur Lektüre
Wir hoffen, dass Sie durch dieses Buch viele Handgriffe lernen, dieIhnen im Alltag helfen, und Ideen für Ihre eigenen Entwicklungenbekommen. Sie finden in diesem Buch mehrere Orientierungshilfen,die Ihnen die Arbeit mit dem Buch erleichtern sollen.
In hervorgehobenen Informationskästen sind Inhalte zu finden, die wis-senswert und hilfreich sind, aber etwas außerhalb der eigentlichenErläuterung stehen. Damit Sie die Informationen in den Kästen soforteinordnen können, haben wir die Kästen mit Symbolen gekennzeichnet:
Die mit diesem Symbol gekennzeichneten Tipps geben Ihnen spezi-elle Empfehlungen, die Ihnen die Arbeit erleichtern können.
In Kästen, die mit diesem Symbol gekennzeichnet sind, finden SieInformationen zu weiterführenden Themen oder wichtigen Inhalten,die Sie sich merken sollten.
Dieses Symbol weist Sie auf Besonderheiten hin, die Sie beachten soll-ten. Es warnt Sie außerdem vor häufig gemachten Fehlern oder Pro-blemen, die auftreten können.
Beispiele, durch dieses Symbol kenntlich gemacht, weisen auf Szena-rien aus der Praxis hin und veranschaulichen die dargestellten Funk-tionen.
Danksagung
Endlich ist es fertig, das ABAP-Kochbuch. Für uns alle war es daserste Buch, das wir geschrieben haben. Es war mehr Arbeit und hatmehr Zeit gekostet, als wir zu Beginn ahnten. Es gibt jedoch noch
24
Einleitung
viele andere Menschen, die ebenfalls viel Zeit mit dem Buch zuge-bracht haben und ohne die eine Veröffentlichung kaum möglichgewesen wäre:
Wir danken Galileo Press für die Gelegenheit, das ABAP-Kochbuchveröffentlichen zu können, und speziell unserer Lektorin JaninaSchweitzer, die uns bei der Entstehung des Buches mit Rat und Tatzur Seite stand. Bedanken möchten wir uns auch bei Stefan Proksch,der die Initialzündung für das Buch gab und es verstand, seine undunsere Ideen konstruktiv voranzubringen.
Danken möchten wir auch unserem Chef Frank Bachmann, der unsstets beratend und tatkräftig zur Seite steht und uns erlaubt hat, dieEntwicklungen für dieses Buch auf dem SAP-System der InwerkenAG vorzunehmen. Ein spezieller Dank geht an unseren ProbeleserRené Eberstein, der unsere Kapitel Stück für Stück durcharbeitete.Mit René haben wir den idealen Testleser gefunden, da er mit seinemBerater-Wiki (www.berater-wiki.de) weiß, worauf es bei der Doku-mentation und Beschreibung von Quellcode und Programmiertech-niken ankommt. Ebenfalls bedanken möchten wir uns bei StefanSchmöcker, der uns mit seiner Programmierkunst und seinen Ideenbei der dynamischen Programmierung unterstützte.
Ganz herzlich möchten wir uns auch bei Dr. Rüdiger Plantiko bedan-ken, der uns seine Anwendung zur Onlinebereitstellung der ABAP-Quelltexte zur Verfügung stellte. Diese Technik nutzte Rüdigerbereits für sein eigenes BSP-Praxisbuch (erschienen im dpunkt.ver-lag), um den Lesern den Quellcode des Buches online zur Verfügungzu stellen.
Ebenso möchten wir uns bei unserer Fotografin Svenja Wichers undihrer Assistentin Galina Lisowski bedanken, die unsere Schokoladen-seiten gefunden und fotografiert haben. Nico Schmarje möchten wirdafür danken, dass er uns mit seiner jahrelangen Erfahrung bei derErstellung des Smart-Forms-Kapitels zur Seite stand.
Unser allergrößter Dank gebührt jedoch unseren Familien, unserenFrauen, Lebenspartnerinnen und Kindern, die sich während der häu-figen und intensiven Schreibphasen sicherlich oftmals eine andereAbend- und Wochenendgestaltung gewünscht haben. Wir möchtenuns ganz herzlich für die Geduld und Unterstützung unserer Familienbedanken!
221
Durch die Kapselung von Funktionen (»Separation of Con-cerns«) werden diese wiederverwendbar. Dieses Prinzip set-zen wir in diesem Kapitel mit einem TextEdit-Control und GUI-Containern um.
6 Mit dem TextEdit Control arbeiten
Das TextEdit Control (Klasse CL_GUI_TEXTEDIT) ermöglicht dieAnzeige bzw. das Editieren von Langtexten innerhalb einer Programm-oberfläche. In diesem Kapitel werden wir dieses Control zur Anzeigeder Tickethistorie in unserer Beispiel-Ticketanwendung verwenden.In der Tickethistorie werden alle Änderungen am Ticket zusammenmit einem Zeitstempel und dem Bearbeiter in Textform gespeichert.Sie ist in einer eigenständigen Datenbanktabelle abgelegt. Um dieAnzeige der Historie losgelöst vom Kontext zu realisieren, verwen-den wir drei Stilmittel:
� Das Model ist eine einfache Klasse, die die Datenhaltung realisiert.
� Der Controller realisiert den externen Zugriff und regelt die Kom-munikation mit dem View.
� Der View ist in unserem Beispiel das TextEdit Control.
Wir werden also das sogenannte Model-View-Controller-Prinzip ein-setzen. Dieses Design Pattern (siehe auch Abschnitt 1.1, »Entwurfs-muster«) wird unter anderem auch in Web-Dynpro-Anwendungenverwendet, hier allerdings nur in vereinfachter Form angewandt.
Dabei kommen folgende Techniken zum Einsatz:
� Singleton-PatternDer Controller soll genau einmal existieren, da zu einem Zeitpunktgenau eine Historie angezeigt wird.
� Factory-PatternDas Model stellt sicher, dass zu jeder Historie genau eine Instanzdes Models existiert.
222
Mit dem TextEdit Control arbeiten6
� EreignisseDas Model löst ein Ereignis aus, wenn der Historientext geändertwird. Der Controller reagiert auf dieses Ereignis und aktualisiertim Bedarfsfall die Anzeige bzw. den View. Da der Auslöser desEreignisses die Verbraucher, d.h. die Klassen, die auf das Ereignisreagieren, nicht kennt, wird von einer losen Bindung (Loose Bin-ding) gesprochen.
Resultat der in diesem Kapitel durchgeführten Programmierungen wirdeine Sammlung von Klassen sein, die eine konsistente Anzeige derTickethistorie gewährleistet – unabhängig vom aufrufenden Programm.
6.1 Datenhaltung und Model
Die Tickethistorie wird in einer eigenen Tabelle abgelegt. In diesemAbschnitt werden wir diese Tabelle sowie die zugehörige Zugriffs-klasse, das Model, anlegen.
6.1.1 Dictionary-Objekte anlegen
Datenelement Die Tickethistorie wird als einfaches STRING-Feld abgebildet. Feldervom Typ STRING sind zeichenartig und in ihrer Länge nicht beschränkt.Um eine solche Entscheidung im Bedarfsfall zu einem späteren Zeit-punkt einfach und konsistent revidieren zu können, legen wir ein ent-sprechendes Datenelement an. Die Anlage eines Datenelements ist inAnhang A.9, »Datenelement anlegen«, beschrieben. Verwenden Sie diefolgenden Werte:
� Name des Datenelements: ZBOOK_TICKET_HISTORY
� Datentyp � Eingebauter Typ: STRING
� Feldbezeichner: Historie
Datenbanktabelle Legen Sie die Tickethistorie in der Datenbanktabelle ZBOOK_HISTORY,die lediglich drei Felder beinhaltet, ab. Die Anlage einer Datenbank-tabelle ist in Anhang A.11, »Tabelle anlegen«, beschrieben. Tragen Sieauf der Registerkarte Auslieferung und Pflege folgende Werte ein:
� Name der Tabelle: ZBOOK_HISTORY
� Auslieferungsklasse: A
Springen Sie dann auf die Registerkarte Felder, und pflegen Sie dieWerte aus Tabelle 6.1 ein.
223
Datenhaltung und Model 6.1
In den Technische Einstellungen zur Tabelle tragen Sie die Daten-
art »APPL0« (Stammdaten, transparente Tabellen) und die Größen-
kategorie »0« ein. Aktivieren Sie anschließend die Tabelle.
6.1.2 Model-Klasse anlegen
In diesem Abschnitt legen wir die Model-Klasse an, die sich um denZugriff auf den Langtext der Meldung kümmern wird.
Private Instanziierung und Factory-Methode
Die Model-Klasse kontrolliert die Erzeugung ihrer Instanzen, umDatenkonsistenz zu gewährleisten. Daher können Instanzen der
Feldname Key Datenelement
MANDT X MANDT
TIKNR X ZBOOK_TICKET_NR
HISTORY ZBOOK_TICKET_HISTORY
Tabelle 6.1 Felder der Datenbanktabelle ZBOOK_HISTORY
Strings in Datenbanktabellen
Bei der Verwendung des Datentyps STRING in einem Datenelement wirddie Warnung »Länge ist unbeschränkt« angezeigt. Lassen Sie sich davonnicht irritieren; fassen Sie diesen Hinweis stattdessen als Beweis dafür auf,dass Sie alles richtig gemacht haben. Der Grund für diese Warnungbesteht in der Verwendung in einer Datenbanktabelle, wie in diesem Bei-spiel gezeigt: Felder dieses Typs können beliebig groß werden, sodasseine Vorhersage der Größe der Tabelle in der Datenbank erschwert wird.
Felder vom Typ STRING sind ab SAP NetWeaver 2004 verfügbar. In frühe-ren Releases haben Sie zwei Möglichkeiten:
� Sie typisieren das Datenelement ZBOOK_TICKET_HISTORY auf ein ent-sprechend großes CHAR-Feld, in dem Sie Groß- und Kleinschreibung zu-lassen, und nehmen die entsprechenden Nachteile in Kauf (beschränkteFeldlänge und gegebenenfalls vergeudeter Speicherplatz).
� Sie wählen ein komplett anderes Konzept und legen den Langtext inden Tabellen STXH und STXL ab. (Dieses Vorgehen wird in diesemBuch nicht behandelt.) Nähere Informationen dazu finden Sie in derSAP-Hilfe unter http://help.sap.com/saphelp_nw73ehp1/helpdata/de/4e/1c2a130b4d1a26e10000000a42189e/frameset.htm
Die Ablage des Langtextes als String ist aber die beste Wahl für unsereZielsetzung.
224
Mit dem TextEdit Control arbeiten6
Klasse nur in der Klasse selbst angelegt werden, und diese werden ineiner internen Tabelle gespeichert. Fordert der Benutzer der Klasseeine Instanz an, werden bereits vorhandene Instanzen aus der inter-nen Tabelle gelesen. Von außen können die Instanzen über einesogenannte Factory-Methode erzeugt bzw. abgerufen werden.
Instanziierungreglementieren
Um die Instanziierung der Model-Klasse einzustellen, gehen Sie wiefolgt vor:
1. Starten Sie den Class Builder (Transaktion SE24).
2. Geben Sie im Feld Objekttyp den Namen der anzulegenden Klasse(hier ZCL_BOOK_TICKET_HIST_MODEL) ein, und klicken Sie aufAnlegen, bzw. drücken Sie (F5) (siehe Abbildung 6.1).
Abbildung 6.1 Model-Klasse anlegen
3. In dem sich öffnenden Pop-up-Fenster wählen Sie aus der Aus-wahlliste Inst.-Erzeugung den Wert 0 Private aus (siehe Abbil-dung 6.2). Dadurch wird nur die Klasse selbst in der Lage sein,Instanzen von sich zu erzeugen.
4. Geben Sie anschließend im Feld Beschreibung eine Kurzbeschrei-bung ein. Für die anderen Werte können Sie die jeweiligen Vor-einstellungen übernehmen. Klicken Sie auf Sichern.
Speicherverbrauch
Eine Instanz einer Klasse bleibt im Hauptspeicher, bis die letzte auf sie zei-gende Referenz gelöscht wird. Danach kann auf die Instanz nicht mehrzugegriffen werden, sodass der Garbage Collector den Speicher freigebenkann.
Bei Verwendung einer Instanzentabelle bleiben alle einmal angefordertenInstanzen bis zum Ende des internen Modus im Speicher, da in der Instan-zentabelle immer eine Referenz auf jede Instanz existiert und der GarbageCollector die Instanz daher nicht abräumt. Werden sehr viele Instanzenbearbeitet, führt das zu einem erhöhten Speicherverbrauch.
225
Datenhaltung und Model 6.1
Abbildung 6.2 Eigenschaften der Model-Klasse festlegen
5. Die neu angelegte Klasse wird nun im Class Builder angezeigt. Kli-cken Sie auf Lokale Typen ((Strg) + (F5)). Legen Sie dort einenStrukturtyp sowie einen Tabellentyp an, wie in Listing 6.1 gezeigt.Der Tabellentyp wird später zur Typisierung eines statischen Attri-buts benötigt, in dem die bereits erzeugten Instanzen der Klassegespeichert werden.
TYPES
: BEGIN OF gys_inst,
tiknr TYPE zbook_ticket_nr,
r_inst TYPE REF TO zcl_book_ticket_hist_model,
END OF gys_inst,
gyt_inst TYPE HASHED TABLE OF gys_inst
WITH UNIQUE KEY tiknr.
Listing 6.1 Typdefinitionen der Model-Klasse
Sichern Sie anschließend, und gehen Sie mit (F3) zurück zum ClassBuilder.
6. Wechseln Sie auf die Registerkarte Attribute, und legen Sie dortdrei Attribute an (siehe Abbildung 6.3).
� Das Attribut GV_TIKNR enthält die Ticketnummer und dient zurIdentifikation der Instanzen der Klasse.
� Im Attribut GV_HISTORY wird zur Laufzeit die gesamte Historiezum Ticket gespeichert.
226
Mit dem TextEdit Control arbeiten6
� Das Attribut GT_INST wird zur Laufzeit Referenzen auf alle exis-tierenden Instanzen der Klasse enthalten. Durch Nachlesen indieser Tabelle wird die Factory-Methode herausfinden können,ob eine Instanz zu einer vorgegebenen Ticketnummer bereitsexistiert oder neu angelegt werden muss.
Abbildung 6.3 Attribute der Model-Klasse
Konstruktoranlegen
Um nun den Konstruktor anzulegen, wechseln Sie auf die Register-karte Methoden und führen die folgenden Schritte aus:
1. Klicken Sie auf Konstruktor (Taste (F5)). Es wird automatisch dieMethode CONSTRUCTOR als Instanzmethode mit der SichtbarkeitPublic angelegt. Stellen Sie den Cursor auf diese Methode, und kli-cken Sie auf Parameter. Legen Sie den Parameter IV_TIKNR an. AlsBezugstyp geben Sie »ZBOOK_TICKET_NR« ein.
2. Klicken Sie auf Methoden und anschließend doppelt auf dieMethode CONSTRUCTOR, und tragen Sie die Methodenimplementie-rung aus Listing 6.2 ein.
METHOD constructor.
me->gv_tiknr = iv_tiknr.
SELECT SINGLE history
FROM zbook_history
INTO me->gv_history
WHERE tiknr = me->gv_tiknr.
ENDMETHOD.
Listing 6.2 Coding des Model-Klassenkonstruktors
3. Sichern Sie, und gehen Sie mit der Taste (F3) zurück in die Metho-denübersicht.
Factory-Methodeanlegen
Hier legen Sie die Factory-Methode GET_INSTANCE als öffentliche sta-tische Methode an:
1. Klicken Sie auf die Spalte Parameter, und legen Sie die beidenParameter aus Abbildung 6.4 als Signatur an.
227
Datenhaltung und Model 6.1
Abbildung 6.4 Parameter der Methode GET_INSTANCE
2. Implementieren Sie die Methode gemäß Listing 6.3.
METHOD get_instance.
DATA ls_inst TYPE gys_inst.
" Prüfen, ob bereits eine Instanz zum Ticket
" existiert
READ TABLE gt_inst INTO ls_inst
WITH TABLE KEY
tiknr = iv_tiknr.
IF sy-subrc <> 0.
" Nein: Instanz anlegen ...
ls_inst-tiknr = iv_tiknr.
CREATE OBJECT ls_inst-r_inst
EXPORTING
iv_tiknr = iv_tiknr.
" ... und in die Instanztabelle eintragen.
INSERT ls_inst INTO TABLE gt_inst.
ENDIF.
rr_inst = ls_inst-r_inst.
ENDMETHOD.
Listing 6.3 Coding der Methode GET_INSTANCE der Model-Klasse
3. Gehen Sie zurück in die Übersicht der Klasse, und drücken Sie(F8), um die Klasse zu testen. Im Vergleich zur Testumgebunganderer Klassen werden Sie feststellen, dass der normalerweisevorhandene Button Instanz (siehe Abbildung 6.5 unten) zurInstanziierung der Klasse nun ausgeblendet ist (siehe Abbildung6.5 oben), da die Instanzerzeugung auf Private gesetzt wurde.
228
Mit dem TextEdit Control arbeiten6
Abbildung 6.5 Private Instanziierung der Klasse ZCL_BOOK_TICKET_HIST_MODEL
Klicken Sie auf das Icon (Ausführen) neben der Methode GET_INSTANCE, geben Sie eine beliebige Ticketnummer ein, und klickenSie erneut auf das Icon . Im Ergebnis-Zweig des Ergebnis-Bild-schirms sehen Sie den Inhalt des Parameters RR_INST: eine Instanzder Klasse ZCL_BOOK_TICKET_HIST_MODEL. Klicken Sie auf dieseInstanz, um sie sich anzeigen zu lassen. Es werden Ihnen die öffent-lichen Member (d.h. Attribute und Methoden) der Instanz angezeigt.
Historie ändern und Änderungen publizieren
Der Model-Klasse fügen wir nun eine neue Methode zu, mit der dieHistorie um einen neuen Eintrag ergänzt werden kann. DieseMethode löst gleichzeitig ein Ereignis aus, mit dem sich andere Klas-sen für die Benachrichtigung über Änderungen an der Historie regis-trieren können. Genau das wird der Controller tun, den wir inAbschnitt 6.2, »Controller anlegen«, behandeln.
Ereignis anlegen Zunächst müssen Sie das Ereignis anlegen:
1. Gehen Sie im Class Builder in die Übersicht zur Klasse ZCL_BOOK_TICKET_HISTORY_MODEL.
2. Wechseln Sie zur Registerkarte Ereignisse.
3. Legen Sie ein öffentliches Instanzereignis HISTORY_CHANGED mitden Parametern aus Abbildung 6.6 an.
Abbildung 6.6 Ereignis der Model-Klasse
229
Datenhaltung und Model 6.1
4. Wechseln Sie zur Registerkarte Methoden, und legen Sie dieöffentliche Instanzmethode ADD_HISTORY an. Diese Methode hatzwei Parameter (siehe Abbildung 6.7).
Abbildung 6.7 Parameter der Methode ADD_HISTORY
5. Implementieren Sie die Methode gemäß Listing 6.4.
METHOD add_history.
DATA ld_date TYPE char10.
DATA ld_time TYPE char8.
IF NOT gv_history IS INITIAL.
" Zeilenumbruch
CONCATENATE gv_history cl_abap_char_utilities=>cr_lf
INTO gv_history.
ENDIF.
" Historie um neuen Eintrag ergänzen
CONCATENATE gv_history cl_abap_char_utilities=>cr_lf
INTO gv_history.
GET TIME.
WRITE sy-datum TO ld_date.
WRITE sy-uzeit TO ld_time.
CONCATENATE gv_history 'Ticket geändert durch' sy-uname
'am' ld_date
'um' ld_time
cl_abap_char_utilities=>cr_lf iv_history
INTO gv_history
SEPARATED BY space.
rv_history = me->get_history( ).
" Event auslösen
RAISE EVENT history_changed.
ENDMETHOD.
Listing 6.4 Implementierung der Methode ADD_HISTORY
230
Mit dem TextEdit Control arbeiten6
Die Historie wird in Listing 6.4 zunächst mit einem »Änderungsstem-pel«, anschließend durch die eigentliche Änderung aktualisiert. DerRückgabeparameter erhält seinen Wert durch den Aufruf derMethode GET_HISTORY, auf die wir im folgenden Abschnitt noch wei-ter eingehen. Wenn Sie die Klasse im augenblicklichen Zustand tes-ten wollen, kommentieren Sie die Zeile aus, und ersetzen Sie siedurch eine einfache Zuweisung. Abschließend wird das EventHISTORY_CHANGED ausgelöst.
Vervollständigung der Klasse
Akzessormethode Nun müssen Sie noch eine Akzessormethode für die Historie imple-mentieren:
1. Legen Sie die öffentliche Instanzmethode GET_HISTORY an. DieMethode hat einen Parameter (siehe Abbildung 6.8).
String-Templates ab SAP NetWeaver 7.03/7.3 einsetzen
Die Ergänzung der Historie durch den Änderungsstempel erfolgt in unse-rem Beispiel durch die Verwendung zweier Hilfsvariablen für die Konver-tierung von Datum und Uhrzeit. Mit den ab SAP NetWeaver 7.03/7.3 ver-fügbaren String-Templates lässt sich die Konvertierung deutlich eleganterlösen (siehe Listing 6.5).
METHOD add_history. IF NOT gv_history IS INITIAL. " Zeilenumbruch gv_history = |{ gv_history }| && |{ cl_abap_char_utilities=>cr_lf }|. ENDIF.
" Historie um neuen Eintrag ergänzen GET TIME. gv_history = |{ gv_history }{ cl_abap_char_utilities=>cr_lf } && |Ticket geändert durch { sy-uname } | && |am { sy-datum date = user } | && |um { sy-uzeit time = user } | && |{ cl_abap_char_utilities=>cr_lf }|. rv_history = me->get_history( ).
" Event auslösen RAISE EVENT history_changed.ENDMETHOD.
Listing 6.5 Datums- und Uhrzeitenkonvertierung mit String-Templates
231
Datenhaltung und Model 6.1
Abbildung 6.8 Parameter der Methode GET_HISTORY
2. Implementieren Sie die Methode gemäß Listing 6.6.
METHOD get_history.
rv_history = me->gv_history.
ENDMETHOD.
Listing 6.6 Implementierung der Methode GET_HISTORY
Historie sichernUm die Tickethistorie zu sichern, legen Sie die öffentliche Instanz-methode SAVE an. Die Methode hat keine Parameter. Die Implemen-tierung sehen Sie in Listing 6.7.
METHOD save.
DATA ls_history TYPE zbook_history.
ls_history-tiknr = me->gv_tiknr.
ls_history-history = me->gv_history.
MODIFY zbook_history FROM ls_history.
ENDMETHOD.
Listing 6.7 Implementierung der Methode SAVE
Alle Historien sichern
Schließlich legen Sie die öffentliche statische Methode SAVE_ALL an(siehe Listing 6.8). Auch diese Methode hat keine Parameter.
METHOD save_all.
DATA ls_inst TYPE gys_inst.
LOOP AT gt_inst INTO ls_inst.
ls_inst-r_inst->save( ).
ENDLOOP.
ENDMETHOD.
Listing 6.8 Implementierung der Methode SAVE_ALL
Die Klasse ZCL_BOOK_TICKET_HISTORY_MODEL ist nun fertig model-liert und implementiert. In Abbildung 6.9 erhalten Sie noch einmaleinen Überblick über alle Methoden der Model-Klasse. Sie könnendie Klasse nun über die Testfunktion des Class Builders testen.
232
Mit dem TextEdit Control arbeiten6
Abbildung 6.9 Die Methoden der Model-Klasse
6.2 Controller anlegen
Unser Controller stellt sicher, dass genau eine Historie in einembeliebigen Frontend-Container angezeigt wird. Dieser Controllerkann für diesen Zweck sowohl von einem Applikations-Controller alsauch von einem kleinen Testprogramm genutzt werden.
Um die Einzigartigkeit der Historie zu gewährleisten, werden wir indiesem Abschnitt das Singleton-Pattern (auch Highlander-Patterngenannt) verwenden, das bewirkt, dass es genau eine Instanz desControllers gibt.
6.2.1 Anlegen der Controller-Klasse
Singleton-Referenz Zunächst müssen Sie die Controller-Klasse mit einer Singleton-Refe-renz anlegen.
1. Legen Sie die Klasse ZCL_BOOK_TICKET_HIST_CNTL im Class Builderan. Stellen Sie die Instanzerzeugung auf Private.
2. Legen Sie das Attribut GR_SINGLETON an (siehe Abbildung 6.10).
Abbildung 6.10 Singleton-Attribut im Controller
233
Controller anlegen 6.2
3. Legen Sie nun, analog zur im Abschnitt »Private Instanziierungund Factory-Methode« beschriebenen Vorgehensweise, die Fac-tory-Methode an. Es handelt sich in diesem Fall um eine öffentli-che statische Methode namens GET_INSTANCE. Die Parameter derMethode entnehmen Sie Abbildung 6.11.
Abbildung 6.11 Parameter der Methode GET_INSTANCE des Controllers
4. Implementieren Sie die Methode gemäß Listing 6.9.
METHOD get_instance.
IF NOT gr_singleton IS BOUND.
" Singleton erstellen
CREATE OBJECT gr_singleton.
ENDIF.
rr_inst = gr_singleton.
ENDMETHOD.
Listing 6.9 Implementierung der Methode GET_INSTANCE des Controllers
EinzelinstanzDas hier angewandte Prinzip entspricht dem des Models, nur dassvom Controller lediglich eine einzige Instanz erstellt werden kann.Dementsprechend erübrigt sich die im Model vorhandene Instanzen-tabelle. Stattdessen genügt im Falle der Singleton-Referenz ein einfa-ches Attribut, in dem die Referenz auf die einzige Instanz der Klasseabgelegt wird. Diese Instanz wird beim erstmaligen Aufruf derMethode GET_INSTANCE erzeugt, bei jedem weiteren Aufruf wirdlediglich die bereits erzeugte Referenz verwendet.
6.2.2 Weitere Attribute anlegen
Die Controller-Klasse benötigt neben der Singleton-Referenz nocheinige weitere Attribute. Da wären zunächst das aktuell bearbeiteteModel (GR_MODEL), außerdem der View (GR_VIEW) sowie eine Referenzauf den GUI-Container (GR_CONTAINER), in dem der View angezeigtwerden soll. Der Anwender soll die Anzeige der Dokumentation akti-vieren bzw. deaktivieren können, daher benötigt der Controller einweiteres Attribut (VISIBLE), das die Sichtbarkeit von View und Contai-
234
Mit dem TextEdit Control arbeiten6
ner steuert. Legen Sie deshalb zusätzlich zum Attribut GR_SINGLETONvier weitere Attribute an, die in Abbildung 6.12 dargestellt sind.
Abbildung 6.12 Attribute der Controller-Klasse
Model setzen
Ticketnummerübergeben
Das Model im Controller wird gesetzt, indem eine Ticketnummervon außen übergeben wird. Legen Sie dazu eine öffentliche Instanz-methode SET_TICKET_NUMBER an. Legen Sie den Parameter IV_TIKNRmit der Art »Importing« an. Als Bezugstyp geben Sie »ZBOOK_TICKET_NR« an und als Typisierungsart »Type«. Die Auswahlkäst-chen Wertübergabe und Optional lassen Sie frei. ImplementierenSie die Methode gemäß Listing 6.10.
METHOD set_ticket_number.
IF me->gr_model IS BOUND.
" Event-Behandler deregistrieren
SET HANDLER me->hndl_history_changed
FOR me->gr_model ACTIVATION space.
ENDIF.
me->gr_model = zcl_book_ticket_hist_model=>get_instance(
iv_tiknr = iv_tiknr ).
" Reaktion auf Änderungen der Historie vorbereiten
SET HANDLER me->hndl_history_changed FOR me->gr_model.
ENDMETHOD.
Listing 6.10 Implementierung der Methode SET_TICKET_NUMBER
Sollte bereits ein Model vorhanden sein (d.h., die Referenz GR_MODEList an eine Instanz gebunden), wird der Ereignisbehandler durch denZusatz ACTIVATION SPACE zunächst deregistriert. Anschließend wird
235
Controller anlegen 6.2
die Referenz auf das neue Model über die Factory-Methode derModel-Klasse aufgerufen und der Ereignisbehandler für das neueModel registriert.
Ereignisbehandler
Das Model informiert über das Ereignis HISTORY_CHANGED seineAnwender darüber, dass die Historie geändert wurde. Um dieAnzeige im Bedarfsfall aktualisieren zu können, benötigt der Control-ler eine Methode, die auf das Ereignis reagiert.
Methode HNDL_HISTORY_CHAN-GED
Legen Sie daher eine private Instanzmethode HNDL_HISTORY_CHANGEDan:
1. Die Methode benötigt keine Parameter. Markieren Sie dieMethode, und klicken Sie auf den Button (Detailsicht). Aktivie-ren Sie die Checkbox Ereignisbehandler für.
2. Tragen Sie anschließend in das Feld Klasse/Interf. die Klasse»ZCL_BOOK_TICKET_HIST_MODEL« und in das Feld Ereignis
»HISTORY_CHANGED« ein (siehe Abbildung 6.13).
Abbildung 6.13 Methode als Event Handler festlegen
3. Implementieren Sie die Methode gemäß Listing 6.11.
236
Mit dem TextEdit Control arbeiten6
METHOD hndl_history_changed.
IF me->gr_view IS BOUND.
me->gr_view->delete_text( ).
me->gr_view->set_textstream(
text = gr_model->gv_history ).
ENDIF.
ENDMETHOD.
Listing 6.11 Implementierung der Methode HNDL_HISTORY_CHANGED
Der Inhalt des Views (d.h. des TextEdit Controls) wird komplettgelöscht und durch die im Model hinterlegte Historie ersetzt. Dieskann nur passieren, wenn der View bereits gebunden ist, also aufeine Instanz zeigt.
Historie anzeigen
Controls»umhängen«
Die Historie soll in der fertigen Applikation in unterschiedlichen,nach Möglichkeit frei wählbaren Containern angezeigt werden. Das»Umhängen« eines Controls in einen anderen Container wird nichtunterstützt, daher müssen Sie zwei private Methoden anlegen, diedas TextEdit Control auf- bzw. abbauen. Diese werden dann voneiner öffentlichen Steuermethode aufgerufen.
View aufbauen Um den View aufzubauen, legen Sie eine parameterlose privateInstanzmethode CREATE_VIEW an, wie in Listing 6.12 gezeigt.
METHOD create_view.
" Text-View erstellen
CREATE OBJECT gr_view
Umhängen von Controls
Immer wieder wird in Internetforen und auch in Projekten diese Fragegestellt: Wie kann ich ein Frontend Control von einem Container in einenanderen schieben? Die Antwort ist: gar nicht. Stattdessen müssen die vor-handenen Controls (inklusive des Containers) gelöscht und anschließendneu aufgebaut werden.
Das Auf- und Abbauen der Views ist im Falle des TextEdit Controls sehreinfach. Soll ein komplexeres Control wie ein ALV oder ein Tree Controlauf ähnliche Art »umgehängt« werden, gestaltet sich der Vorgang unterUmständen deutlich schwieriger, da dann zusätzliche Informationen wiez.B. registrierte Ereignisbehandler, Cursor-Position, Filter und Sortierung(im Falle eines ALV Grids), geöffnete Knoten (im Falle eines Trees) etc.zwischengespeichert werden müssen.
237
Controller anlegen 6.2
EXPORTING
wordwrap_mode = cl_gui_textedit=>wordwrap_off
parent = me->gr_container.
" Eingabefähigkeit deaktivieren
CALL METHOD gr_view->set_readonly_mode
EXPORTING
readonly_mode = cl_gui_textedit=>true.
IF gr_model IS BOUND.
gr_view->set_textstream( text = gr_model->gv_history ).
ENDIF.
ENDMETHOD.
Listing 6.12 Coding der Methode CREATE_VIEW
Das TextEdit Control wird erstellt, die Eingabebereitschaft deakti-viert und mit der aktuell geladenen Historie gefüllt. Die Methodegeht davon aus, dass der Container bereits existiert.
View abbauenUm den View anschließend wieder abzubauen, legen Sie eine para-meterlose private Instanzmethode DESTROY_VIEW an. Die Implemen-tierung sehen Sie in Listing 6.13.
METHOD destroy_view.
IF gr_view IS BOUND.
gr_view->free( ).
ENDIF.
ENDMETHOD.
Listing 6.13 Implementierung der Methode DESTROY_VIEW
Frontend Controls rückstandsfrei entsorgen
Um Instanzen herkömmlicher Klassen abzubauen, reicht es aus, die letzteauf sie zeigende Referenz zu löschen. Dadurch wird der Garbage Collectorveranlasst, den Speicher wieder freizugeben, den die Instanz belegt hat.
Bei Frontend Controls sieht die Sache etwas anders aus, da sie aus zweiKomponenten bestehen: einer Backend-Komponente im Applikationsser-ver sowie einer Frontend-Komponente im SAP GUI. Außerdem behält dasControl Framework Referenzen auf seine Komponenten bei, sodass manunter Umständen gar nicht alle Referenzen löschen kann.
Die Methode FREE wird ausgehend von der Basisklasse aller FrontendControls CL_GUI_CONTROL an alle Frontend-Control-Klassen vererbt unddient dazu, das jeweilige Control abzubauen. Sie löscht alle Referenzen imBackend und sorgt dafür, dass auch die Frontend-Komponenten abgebautwerden. Wird die Methode nicht eingesetzt, kann das zu irritierendenEffekten führen, z.B. erscheinen im Frontend Controls, die im Backendlange als gelöscht gelten.
238
Mit dem TextEdit Control arbeiten6
Steuermethode Die Steuermethode zeigt die aktuell geladene Historie in dem GUI-Container an, der ihr übergeben wurde. Implementieren Sie dieseMethode wie folgt:
1. Legen Sie die öffentliche Instanzmethode SHOW_HISTORY an. DieParametervergabe entnehmen Sie Abbildung 6.14.
Abbildung 6.14 Parameter der Methode SHOW_HISTORY
Der Bezugstyp CL_GUI_CONTAINER ist die Basisklasse aller GUI-Con-tainer wie Docking-Container, Dialogbox oder Custom Container.Welcher dieser Container an die Methode übergeben wird, spieltdaher keine Rolle; es erfolgt implizit ein Narrowing Cast, d.h. eineeinschränkende Typumwandlung der Referenz. Innerhalb derMethode sind daher lediglich die Eigenschaften des Containers sicht-bar, die bereits in der Basisklasse CL_GUI_CONTAINER vereinbart wur-den, nicht jedoch spezielle Eigenschaften wie z.B. die Größe undPosition einer Dialogbox oder die Breite eines Docking-Containers.
2. Die Implementierung der Steuermethode SHOW_HISTORY sollte wiein Listing 6.14 aussehen:
METHOD show_history.
IF NOT ir_container IS BOUND.
" Übergebener Container zeigt auf nichts
RETURN.
ENDIF.
IF me->gr_container = ir_container.
" Anzeige erfolgt bereits in diesem Container
RETURN.
ENDIF.
me->gr_container = ir_container.
destroy_view( ).
create_view( ).
ENDMETHOD.
Listing 6.14 Implementierung der Methode SHOW_HISTORY
239
Controller anlegen 6.2
Die Methode übernimmt die Containerreferenz in das entspre-chende Instanzattribut und baut den View anschließend ab und wie-der auf.
Anzeige aus- und anschalten
Methode SWITCH_HISTORY
Das Aktivieren und Deaktivieren der Dokumentationsanzeige wirdüber die öffentliche Instanzmethode SWITCH_HISTORY gesteuert. Imp-lementieren Sie diese, wie in Listing 6.15 dargestellt.
METHOD switch_history.
CALL METHOD gr_view->get_visible
IMPORTING visible = visible.
" Der FLUSH der Automation Queue muss erfolgen, da der " Wert von VISIBLE sonst nicht übertragen wird!
cl_gui_cfw=>flush( ).
IF visible = '1'.
visible = '0'.
ELSE.
visible = '1'.
ENDIF.
gr_view->set_visible( visible ).
gr_container->set_visible( visible ).
ENDMETHOD.
Listing 6.15 Implementierung der Methode SWITCH_HISTORY
Control FrameworkFrontend Controls werden über das Control Framework gesteuert, dasdie Kommunikation zwischen der Anwendungslogik und den imFrontend sichtbaren Controls übernimmt. Methodenaufrufe vonControls werden in der Automation Queue zwischengespeichert, dieautomatisiert zu bestimmten Zeitpunkten abgearbeitet wird (Flush).Dieser Mechanismus dient dazu, die Anwendungsperformance zuerhöhen, da bei synchroner Verarbeitung der Kommunikationskanalzwischen Anwendung und Frontend sehr häufig geöffnet undgeschlossen werden müsste. Diese Abstimmung ist häufig jedochnicht nach jedem einzelnen Schritt notwendig, da meistens mehrere
Sichtbarkeit von Containern
Nach Aufruf der Methode SET_VISIBLE wird der Container nur ausge-blendet, falls es sich um einen Docking-Container handelt. Alle anderenContainer werden lediglich leer dargestellt.
240
Mit dem TextEdit Control arbeiten6
Methoden unabhängig voneinander aufgerufen und verarbeitet wer-den und die Synchronisation mit dem Frontend erst am Ende derVerarbeitung stattfinden muss.
Auch der Aufruf der Methode GET_VISIBLE wird zunächst in derAutomation Queue zwischengespeichert. Dies hat zur Folge, dass dasErgebnis, also der Wert des Attributs VISIBLE, nicht direkt zurückge-liefert wird, sondern erst nach der Abarbeitung der AutomationQueue. Um diese auszulösen, wird die statische Methode FLUSH desControl Frameworks (Klasse CL_GUI_CFW) aufgerufen.
6.2.3 Weitere Methoden des Controllers
Der Controller verfügt über zwei weitere Methoden, SAVE und ADD_HISTORY, die lediglich die entsprechenden Methoden des Modelsaufrufen. Einen kompletten Überblick über alle Methoden des Cont-rollers gibt Ihnen die Registerkarte Methoden zur Controller-KlasseZCL_BOOK_TICKET_HIT_CNTL (siehe Abbildung 6.15).
Abbildung 6.15 Methoden der Controller-Klasse
6.3 Testprogramm entwickeln
Programm-anforderungen
Zur Überprüfung des Zusammenspiels von Model und Controllerkann ein kleines Testprogramm dienen. Das Programm nimmt eineTicketnummer als Parameter entgegen und baut mehrere GUI-Con-
241
Testprogramm entwickeln 6.3
tainer auf, in denen die Tickethistorie dargestellt wird. In einem wei-teren Container findet ein editierbares TextEdit Control Platz, in demText eingegeben werden kann.
Die Container werden auf, neben und über einem Dynpro platziert,das zusätzlich mit mehreren Buttons ausgestattet wird, mit denen derAnwender den eingegebene Text in die Historie übernehmen und dieHistorienanzeige in die verschiedenen Container einhängen kann.
Implementierungs-schritte
Gehen Sie wie folgt vor, um das Testprogramm zu erstellen:
1. Legen Sie einen neuen Report an (z.B. ZBOOK_TEST_HIST, sieheauch Anhang A.5, »Programm anlegen«).
2. Legen Sie einen Parameter und ein globales Feld an, die beide aufdas Datenelement ZBOOK_TICKET_NR typisiert sind.
3. Legen Sie weitere globale Felder für die Container, das editierbareTextEdit Control CL_GUI_TEXTEDIT und Ihren Controller an (sieheListing 6.16).
DATA gr_dock_top TYPE REF TO cl_gui_docking_container.
DATA gr_text TYPE REF TO cl_gui_textedit.
DATA gv_text TYPE zbook_ticket_history.
" Container für die Historie
DATA gr_dock_right TYPE REF TO cl_gui_docking_container.
DATA gr_dialogbox TYPE REF TO cl_gui_dialogbox_container.
DATA gr_custom TYPE REF TO cl_gui_custom_container.
" Historie
DATA gr_hist_cntl TYPE REF TO zcl_book_ticket_hist_cntl.
Listing 6.16 Datendeklarationen im Testprogramm
4. Zum Zeitpunkt START-OF-SELECTION übergeben Sie den Parameteran das globale Feld und rufen das Dynpro 0100 auf.
5. Legen Sie einen Status zum Dynpro an. Aktivieren Sie denZurück-Button als Exit-Funktion, und belegen Sie den Speichern-Button mit dem Funktionscode SAVE.
6. Erstellen Sie auf dem Dynpro 0100 fünf Buttons mit den Namenund Funktionscodes aus Tabelle 6.2.
242
Mit dem TextEdit Control arbeiten6
7. Legen Sie außerdem einen Custom-Container-Bereich namensCUSTOM an.
8. Legen Sie ein PBO-Modul (Process Before Output) INIT_0100 an,in dem die Controls erstellt und der Controller initialisiert werden(siehe Listing 6.17).
IF NOT gr_dock_top IS BOUND.
" Texteditor für hinzuzufügenden Text
CREATE OBJECT gr_dock_top
EXPORTING
side = cl_gui_docking_container=>dock_at_top
ratio = 30.
CREATE OBJECT gr_text
EXPORTING
wordwrap_mode = cl_gui_textedit=>wordwrap_off
parent = gr_dock_top.
" Container für Historienanzeige instanziieren
CREATE OBJECT gr_dock_right
EXPORTING
side = cl_gui_docking_container=>dock_at_right
ratio = 30.
CREATE OBJECT gr_custom
EXPORTING
container_name = 'CUSTOM'.
CREATE OBJECT gr_dialogbox
EXPORTING
width = 600
height = 100
top = 50
left = 50
caption = 'Ticket Historie'.
" Historie einschalten
gr_hist_cntl = zcl_book_ticket_hist_cntl=>get_instance( ).
gr_hist_cntl->set_ticket_number( iv_tiknr = gv_ticket ).
Name Funktionscode
TO_DOCK DOCK
TO_CUSTOM CUSTOM
TO_DIALOG DIALOG
ON_OFF ON_OFF
TEXT2HIST TEXT2HIST
Tabelle 6.2 Buttons auf Dynpro 100 des Testprogramms
243
Testprogramm entwickeln 6.3
gr_hist_cntl->show_history( ir_container = gr_dock_right ).
ENDIF.
Listing 6.17 Coding zum PBO-Modul des Dynpros 0100
9. Im Verarbeitungsblock PAI des Dynpros werten Sie den Funkti-onscode aus (siehe Listing 6.18).
CASE sy-ucomm.
WHEN 'TEXT2HIST'.
gr_text->get_textstream( IMPORTING text = gv_text ).
cl_gui_cfw=>flush( ).
gr_text->delete_text( ).
gr_hist_cntl->add_history( iv_history = gv_text ).
WHEN 'CUSTOM'.
" Historie im Custom Container anzeigen
gr_hist_cntl->show_history( gr_custom ).
WHEN 'DIALOG'.
" Historie in der Dialogbox anzeigen
gr_hist_cntl->show_history( gr_dialogbox ).
WHEN 'DOCK'.
" Historie im Docking-Container anzeigen
gr_hist_cntl->show_history( gr_dock_right ).
WHEN 'ON_OFF'.
" Historie an-/ausschalten
gr_hist_cntl->switch_history( ).
WHEN 'SAVE'.
" Historie speichern
gr_hist_cntl->save( ).
WHEN OTHERS.
ENDCASE.
Listing 6.18 Coding zum Zeitpunkt PAI des Dynpros 0100
10. Legen Sie mit dem gleichen Vorgehen ein PAI-Modul an, das beieinem Exit-Kommando durchlaufen wird, und füllen Sie es mitLEAVE TO SCREEN 0. Diese Anweisung beendet das Programm andieser Stelle und führt den Benutzer zurück zum Einstiegsbild.
11. Aktivieren Sie Ihr Programm, und starten Sie einen Testlauf.
Sie können nun testen, ob das »Umhängen« der Tickethistorie in dieContainer einwandfrei funktioniert und was passiert, wenn Sie dieAnzeige der einzelnen Container ausschalten. Abbildung 6.16 bisAbbildung 6.18 zeigen Ihnen, wie sich das Programm verhaltensollte. Wie Sie sehen, wird der gleiche Texteditor in verschiedenenContainern angezeigt.
244
Mit dem TextEdit Control arbeiten6
Abbildung 6.16 Anzeige der Historie im Docking-Container
Abbildung 6.17 Anzeige der Historie in der Dialogbox
245
Testprogramm entwickeln 6.3
Abbildung 6.18 Anzeige der Historie in einem Custom Container
647
Index
A
ABAP Dictionary 27, 42, 58, 94ABAP Editor 27, 620ABAP List Viewer 379ABAP Objects 29ABAP Repository 27ABAP Workbench 26, 210, 350, 591,
618ABAP-Dictionary-Struktur 387ABAP-Laufzeitumgebung 324ABAP-Webservice 601Ableitung 195, 306Absatzformat 471Adobe LiveCycle Designer 466Adressgruppe 55Aktualparameter 266Akzessormethode 230allgemeine Tabellenpflege 48ALV Grid 143, 149
aktualisieren 464Änderbarkeit 389Ereignisbehandlung 390Pufferung 388
ALV Tree Control 301ALV-Liste 380Änderung 279Änderungsbeleg 279, 287Änderungsbelegobjekt 279, 291Änderungsnummer 286Änderungsprotokoll 279Änderungsrelevanz 280Änderungszeiger 286Anlagenliste 487Anmeldeticket 607API (Änderungsbelege)
CHANGEDOCUMENT_CLOSE 288CHANGEDOCUMENT_DISPLAY
290CHANGEDOCUMENT_MULTIPLE_
CASE 288CHANGEDOCUMENT_OPEN 287CHANGEDOCUMENT_READ 290CHANGEDOCUMENT_SINGLE_CASE
288API (Applikationslog) 247
BAL_ARCHIVE_LOAD 278BAL_ARCHIVE_SEARCH 278BAL_CNTL_CREATE 265, 276BAL_CNTL_REFRESH 265, 276BAL_DB_LOAD 261BAL_DB_SAVE 263, 264BAL_DB_SEARCH 261, 277BAL_DSP_LOG_DISPLAY 250BAL_DSP_PROFILE_POPUP_GET
275BAL_LOG_CREATE 249, 261BAL_LOG_MSG_ADD 250, 263BAL_LOG_MSG_ADD_FREE_TEXT
250API (Tabellenpflege)
VIEW_MAINTENANCE_CALL 72VIEW_MAINTENANCE_SINGLE_EN
TRY 73API-Baustein 291Application Event 321Application Programming Interface �
APIApplikationslog 247, 278, 515Applikationslogik 468Attribut
GR_GOS_MANAGER 492HTML_TABLE 340ITEM_INDEX 447T_CITEM_TABLE 447T_LITEM_TABLE 447
Aufrufer 317Aufzeichnungsroutine 80Auslieferungsklasse 80Ausrichtung 328Authentifizierung 606Auto-Alignment 328Automation Queue 239
B
BAPI 252, 257Befehl
ASSIGN 528, 547, 563ASSIGN COMPONENT 528, 588CALL TRANSFORMATION 573
648
Index
COMMIT WORK 501CONCATENATE 549CREATE OBJECT 335EXPORT TO MEMORY 533FIELD-SYMBOLS 528GENERATE SUBROUTINE POOL
530IMPORT FROM MEMORY 533interner 530IS ASSIGNED 528MODIFY 555READ TABLE 324SELECT 529SELECT-OPTIONS 399SET HANDLER 358SET PF-STATUS 334
Behaviour 441, 460Beleg 485Benutzer-/Passwort-Abfragen 607Benutzerpflege 580Benutzerverwaltung 593Berechtigungsobjekt
S_TABU_DIS 45, 78S_TABU_NAM 45, 78S_TCODE 78
Berechtigungsverwaltung 580Binding 611BOR-Objekt 492Browser 618Business Application Programming
Interface (BAPI) 252, 257Business Object Builder 488Business Object Repository 488
C
Callback 267, 493, 589Callback-Routine 271Cast 464Class Builder 224, 228, 268, 307, 339,
346, 507, 633CLEAR-Anweisung 177Cluster 575Column Tree 300Command Chaining 266Container 236Content Repository 496Control
Control Framework 239Custom Control 187, 333Drag-&-Drop-Fähigkeit 438objektorientiertes 437umhängen 236
Controller 221Custom Container 187, 335, 398Customizing-Daten 40
D
Data Browser 45, 575DATA-Anweisung 141Daten normalisieren 41Datenart 638Datenbankanweisung 28Datenbanktabelle erstellen 111Datenbankzugriff, Protokoll 248Datendefinition 622Datendeklaration
allgemeine 285objektspezifische 286
Datenelementändern 138änderungsrelevant 280anlegen 111, 634
Datenreferenz 562, 571Datensatz, Einzelbearbeitung 73Datenselektion 139Datenstruktur 41Datentyp, lokaler 167Debugger 28Design Pattern 221Design Pattern � EntwurfsmusterDesign-Zeit 485Dialog
Detailbild 47einstufiger 47
Dialogfenster, modales 212Dictionary-Struktur 141Dirty-Assign 528Docking-Container 65, 218, 361Dokument 465, 468
dynamisches 337Konzeption 468
Domäneanlegen 111, 636einrichten 501
Domänenfestwert 545
649
Index
DO-Schleife 504Downcasting 199Drag & Drop 433, 440
Applikationsserver-Service 440Behaviour 435Datenübertragung 441Drag 435Drop 435Handle 435Objekt 435
Dragsource 435, 441Drawer Control � Schubladen-ControlDropdown-Liste 418Droptarget 435Druckprogramm 468Dynamic Data Grid 569dynamisches Dokument 337Dynpro 39, 47, 114, 241, 437
Ablauflogik 114anlegen 155Arbeitsbereich 141kopieren 82Modulpool 139nachbearbeiten 81
Dynpro-Element 192
E
EDIT-Ereignis 391Effekt 435, 461Eingabehilfe 115E-Mail 497
Ausgangsqueue 501Hintergrund 509Host 501Instanz 512Port 501Versanddialog 507
Endlosschleife 326Endpunkt 609Enjoy Control 349Entwicklungsklasse 615Entwurfsmuster 25, 195Ereignis 139, 222, 228
anlegen 228Application Event 321BEFORE_USER_COMMAND 425Drag & Drop 437EXPAND_NO_CHILDREN 327
ITEM_DOUBLE_CLICK 321ONDRAG 439, 441, 448ONDROP 440, 441, 462ONDROPCOMPLETE 440, 441ONGETFLAVOR 439, 441Quellereignis 439STATUS_CHANGED 341, 344TOOLBAR 423
Ereignisbehandler 235, 344Ereignisbehandlung 304, 358, 437Ergebnismenge sortieren 133Event Handler 235, 344Event � EreignisException 456, 464, 513Exit-Kommando 158Exit-Steuerung 326externe Identifikation 248, 253
F
F4-Wertehilfe 114Factory-Methode 224, 262Factory-Pattern 26, 221Feld
dynamisches 468, 473Redefinition 150variables 525
Feldabhängigkeit 91Feldattribut 141Feldbezeichner 44Feldeigenschaft ändern 165Feldkatalog 276, 385, 571, 588
automatischer 386manueller 385
Feldsteuerung 114, 164, 166Feldsymbol 527, 548, 587Festwert 116, 126Flavor 435, 439, 441Flush 239Flush-Abwicklung 299Font 328Form Builder 470, 472Form Painter 470FORM-Routine 63Formular 465, 468, 470
Ablauflogik 468anlegen 471Grafik einbinden 472offline-interaktives 467
650
Index
online-interaktives 467Formularschnittstelle 468, 469, 472Framework 357Framework einbinden 375Fremdschlüssel 641
Definition 117Prüfung 162
Frontend Control 236, 237, 239Function Builder 130, 215, 632Funktionsbaustein 192
anlegen 602, 630BAL_DB_SEARCH 277Callback 269DD_DOMVALUES_GET 420DDUT_INPUT_CHECK 534DYNP_VALUES_READ 115F4UT_FIXED_VALUES_TEXT_ADD
126F4UT_ICONS_DISPLAY 129, 132F4UT_PARAMETER_SORT 125F4UT_PARAMETER_VALUE_GET
130ICON_CREATE 423NUMBER_CHECK 179NUMBER_GET_NEXT 180, 181POPUP_GET_VALUES_USER_HELP
588READ_TEXT 517remotefähiger 182, 602RS_SET_SELSCREEN_STATUS 534RS_SUPPORT_SELECTIONS 401SSF_FUNCTION_MODULE_NAME
482Typen 182Verbuchungsbaustein 183VIEW_MAINTENANCE_CALL 72VIEW_MAINTENANCE_SINGLE_
ENTRY 73VIEWCLUSTER_MAINTENANCE_
CALL 99Funktionseigenschaft 158Funktionsgruppe 39, 247, 283, 601Funktionsgruppe anlegen 210, 629
G
Garbage Collector 224, 237Generic Object Services � GOSgenerische Objektdienste � GOS
gepackte Zahl 107GOS 485
GOS-Anhang 497GOS-Anlage 495, 523GOS-Manager 492, 493GOS-Menü 486GOS-Toolbar 498Verbuchungssteuerung 495
Gruppenname 148, 153GUI-Status 114, 140, 157, 336GUI-Titel 140
H
Highlander-Pattern � Singleton-Pattern
Hilfsbaustein 128HTML Control 339HTML-Button 349HTTP 600
I
Image Repository 473Import-Parameter 136, 472Include 285
benanntes 142, 148Gruppenname 148umbenanntes 150, 153
INCLUDE-Befehl 148Instanz 224
Attribut 452erzeugen 316, 460Variable 443
Instanzentabelle 224Instanziierung 188, 223Instanzmethode 230, 255, 502Instanzvariable 503Integerwert 107Interface 303
IF_DRAGDROP 438Methode 493
Item-Tabelle 447
J
Job-Protokoll 247
651
Index
K
Kapselung 304Kategorie 41Klasse 192, 304
Basisklasse 195, 199CL_BCS 498CL_DD_DOCUMENT 339CL_DRAGDROBOBJECT 435CL_DRAGDROP 460CL_DRAGDROPOBJECT 441CL_GOS_MANAGER 492CL_GUI_ALV_GRID 383CL_GUI_CONTAINER 238CL_GUI_CONTAINER_BAR 360CL_GUI_DOCKING_CONTAINER
218CL_GUI_TEXTEDIT 185, 221, 237,
241CL_LIST_TREE_MODEL 321CL_PERS_ADMIN 580Ereignisbehandlung 358globale 339, 367, 442, 445Instanz 224lokale 339, 442programmieren 66programmlokale importieren 346statische 358Vererbbarkeit 192
Knoten 298Identifikation 314
Knotenschlüssel 323Knowledge Provider 496Komponente 218, 562, 571Konsistenzcheck 147Konstante 503
CV_CRLF 503EVENTID_ITEM_DOUBLE_CLICK
321NODE_SEL_MODE_SINGLE 320
Konstruktor 226, 260, 320, 322, 493Konstruktormethode 255Kopfdaten 471Kopfeintrag 87
L
Laufzeitanalyse 28Laufzeitkomprimierung 171
Layout 401Layout Editor 212Layoutstruktur 383, 384List Tree 300Listbox 69Logo 472Loop 176, 477lose Bindung 222
M
Makro 526Mandant 638Methode 192
ADD 453, 461ADD_CALLBACK 268ADD_HISTORY 229ADD_INFO 461ADD_NODE 322, 323, 324, 456ADD_PARAM 269ADD_TICKET_LINK 509anlegen 633Aufruf 239BUILD_DISPLAY_OPTIONS 414,
460BUILD_DROPDOWN_TABLE 420BUILD_ITEMS 323, 327CHECK_CHANGED_DATA 425CHECK_RESPONSIBLE 331CONSTRUCTOR 255, 340CREATE_MAIL_DIALOG 502CREATE_MAIL_TEXT_DARK 511CREATE_PERSISTENT 512CREATE_TREE_CONTROL 321DESTROY_VIEW 237DISPLAY_DOCUMENT 339, 341DOCUMENT 502EXPAND_ROOT_NODES 322FLUSH 240, 464FREE 237funktionale 320, 330GET_CITEM_TABLE 451GET_DATA 320, 322GET_HANDLE 461GET_HISTORY 230GET_INSTANCE 227, 233, 262,
319, 335, 412, 444GET_LITEM_TABLE 450, 464GET_MAIL_AS_TEXT 502, 505
652
Index
GET_MAIL_BODY 502, 503GET_MSG 257GET_NODE_KEY 451GET_OBJECT 494GET_SUBJECT 505GET_TEXT_TEMPLATE 516GET_TEXTSTREAM 188GET_VISIBLE 240HANDLE_BEFORE_USER_
COMMAND 425HANDLE_BUTTON_CLICK 427HANDLE_DRAG 454, 455HANDLE_ITEM_DOUBLE_CLICK
330HANDLE_USER_COMMAND 427implementieren 227, 320INIT 168MERGE_DOCUMENT 339RECIPIENTS 502redefinieren 195REFRESH 341REFRESH_TABLE_DISPLAY 464REGISTER_EDIT_EVENT 418SAVE 231, 263SAVE_ALL 231SET_CITEM_TABLE 448SET_CONTAINER 264SET_FIELD_INACTIVE 169SET_FIELD_NO_INPUT 169SET_FLAVOR 440, 441SET_LITEM_TABLE 448SET_NODE_KEY 449SET_STATUS 341SET_VISIBLE 239SETUP_ALV 417SETUP_DRAG_DROP 460SHORT_MESSAGE 499statische 256
Model 26, 221Model View Controller (MVC) 26Model-Klasse 223Model-View-Controller-Prinzip 221Modifikationsgruppe 165, 170Modul 174, 177, 218, 357Modularisierung 18, 191Modulpool 139, 622Muss-Feld-Prüfung 62
N
NachrichtKontext 272
Nachrichtenklasse 254Namensraum 281Narrowing Cast 238Native SQL 28Nummernkreis 178
Intervall 179intervall 178Objekt 178Vergabe 179
Nummernvergabe 178
O
Object Browser 26Object Navigator 618Objekt 26, 248, 252
definieren 27dynamisches 493statisches 491
Objektbaum 618Objektdienste, generische � GOSObjektkatalogeintrag 614Objektliste 622Objektreferenz 358, 563Objektreferenzvariable 364On-Demand-Ansatz 326Open SQL 28Operation 610
P
PAI 243, 321PAI-Modul 157, 185, 333Paket 615Parameter 195Parameter-ID 426Parametrisierung 195PBO 242, 321PBO-Modul 157, 170, 198, 242, 333,
444PC-Editor 470PDF-Dokument 466Personalisierung 579Personalisierungsobjekt 579, 581,
590
653
Index
Präsentationslogik 468Präsentationsschicht 26Pretty Printer 27Problemklasse 249Process After Input 243, 321Process After Input (PAI) 114, 156Process Before Output 242, 321Process Before Output (PBO) 114, 157Programm
Arten 139Aufbau 110ausführbares 140, 332
Programmieransatzdynamischer 152, 525generischer 526iterativer 325objektorientierter 26, 199, 296prozeduraler 296rekursiver 325
Programmprüfungerweiterte 29
Protokoll 247, 612Hauptspeicher 249Kategorisierung 248Nummer 249persistentes 249, 251transientes 249
Protokoll-Handle 248Protokollklasse 266Prüftabelle 116
R
Rahmenprogramm 100Range-Tabelle 277, 393, 403Range-Tabellentyp 394READ TABLE 176Referenzparameter 183Referenzvariable 376, 492Rekursivität 325Remote Function Call (RFC) 180Report 139, 241, 338
RSSCD100 293RSSCD500 293
Repository Browser 210, 558, 618, 622
Repository-Objekt 281Resizing 625Returncode 535
Returning-Parameter 319, 503Reuse-Datenbank 194Rolle 580Rollenpflege 592Rückgabeparameter 507Rückgabewert 502, 507Rücksprungroutine 268Runtime Type Creation (RTTC) 530Runtime Type Identification (RTTI)
530Runtime Type Services (RTTS) 530,
562
S
SAP Business Workplace 498SAP Code Inspector 29SAP Content Server 496SAP GUI for HTML 299SAP Interactive Forms by Adobe 466SAP List Viewer 379SAP Smart Forms 466SAP Tree 298SAP Tree Model 298, 301SAP-Link 509SAPscript 465, 485SAP-Shortcut 509SAP-System, externer Zugriff 599SAP-Tree-Klasse 298Schablone 476, 477Schleifenzähler 549Schlüsselfeld 638Schnittstelle 498Schubladen-Control 360Schubladen-Framework 358Screen Painter 27, 82, 160, 172, 187,
623Selektionsbild 139Selektionsparameter 73Serviceprovider 600Shortdump 549Signatur 633Simple Tree 300Single Sign-on 607Singleton-Pattern 26, 221, 232, 318,
320Singleton-Referenz 232, 233Smart Form 482Smart Forms � SAP Smart FormsSMTP-Server 501
654
Index
SOAP 600, 608Sonderzeichen 154SOS-Funktion 147Spezialisierung 206Splitter-Framework 358Sprachkennzeichen 49SQL Trace 28SSO 607Stack 326Stammdaten 40Statustyp
Dialogfenster 334Dialogstatus 334
Statusübersicht 338Steuermethode 238Stil 470String 502, 506, 573STRING-Feld 222String-Template 230Struktur
anlegen 469dynamische 587einbinden 143flache 175globale 212S_LAYOUT 460tiefe 175
Struktur-zu-Struktur-Zuweisung 149Style 387Style-Konstante 388Subscreen 192, 209Suchhilfe 115
elementare 115, 120, 135Ereignisse 130erweitern 123Exit 125, 128inkludierte 137Sammelsuchhilfe 116, 135
Suffix 143, 153Support 497SY-INDEX 549Syntaxprüfung 29Systemcluster 575System-ID 511Systemlandschaft 599Systemtabelle 87Systemvariable 518
SYST-DATUM 518
T
Tabelleanlegen 637CDHDR 279, 293CDPOS 279, 293Datenselektion 176erstellen 42Erweiterungskategorie 640INDX 575inkludierte 143interne 168, 477Pufferung 639SCREEN 165SGOSATTR 495SOC3 496technische Einstellungen 638
Tabellenarbeitsbereich 180Tabellenpflege, Änderungen doku-
mentieren 56Tabellenpflegedialog 39
ändern 51Berechtigung 78generieren 39gruppieren 85zeitabhängiger 74
Tabellenpflegegenerator 43, 46, 78Table Control 82Table Painter 478TABLES*-Anweisung 141TABLES-Anweisung 141Tabstrip, vertikales � Schubladen-
ControlTastenkombination 613Teamarbeit 36Testprogramm, Protokoll 249Testumgebung 28Textbaustein 471TextEdit Control 185, 221Textfeld 328Textknoten 471Texttabelle 48Ticket anlegen 523Tickethistorie 221Toolbar 367TOP-Include 140, 141, 361, 364, 376,
622Trace 612
655
Index
Transaktionanlegen 164DWDM 302OAC0 496PERSREG 580SCDO 281, 283SCI 29SCOT 501SCU3 640SE03 615SE09 617SE10 617SE11 42, 51, 58, 280SE16 314SE16N 45SE24 66, 206, 224, 254, 298, 346,
437, 633SE37 269, 585, 632SE38 27, 620SE51 27SE54 46, 86, 97, 100SE63 471SE78 473SE80 26, 210, 350, 618SE93 53, 164SLG0 252SLG1 248SM30 28, 48, 51SM34 92, 98SMARTFORMS 470SNRO 179SO01 501SO10 515SOAMANAGER 608, 609SOST 501SPERS_DIALOG 590ST05 28SWO1 488
Transaktion SE24 445Transport 27Transport Organizer 615Transportauftrag 614, 616Transportgarantie 606Tree Control 295
Aufbau 298Ereignis 306
Tree-Control-Instanz 321Tree-Control-Klasse 327Tree-Klasse 296Tree-Model-Instanz 320
Tree-Typ 295TYPE-Referenzierung 145
U
Übergabestruktur 469Unterobjekt 248, 252Unterroutine 160Update-Kennzeichen 290
globales 286tabellenspezifisches 286
Usability 579User-Exit 101, 589
V
Variable 156, 526globale 160, 443lokale 160, 323LV_PARENT 323VCL_STOP 107
Variante 140, 401Variantensteuerung, benutzerabhän-
gige 385Verbucher generieren 283Verbuchung 178, 184Verbuchungsbaustein 183, 287Vererbung 195, 306Verkaufsbeleg 292Versionierung 29Verweis, dynamischer 544Verwendungsnachweis 27, 29View 26, 58, 221Viewcluster 85
Kopfeintrag 87Objektstruktur 88
Viewcluster-Pflege 92Vorabprüfung auf Dubletten 299Vorgänger 90Vorwärtsnavigation 27
W
Wartbarkeit 479Webservice 599
ABAP-Webservice 601Endpunkt 609erstellen 601
656
Index
Konsument 601Provider 601Sicherheit 606SOAP-Webservice 600Wizard 601
Wertetabelle 48WHERE-Bedingung 165Wiederverwendbarkeit 18, 191Wrapper-Instanz 492Wrapper-Klasse 492WSDL 608Wurzelknoten 321
X
X.509-Zertifikat 607XML-Format 467XML-String 574
Z
Zeichenformat 471Zeilenformat 471Zeilentyp 478Zeitpunkt 57, 62, 64, 69Zugriffsklasse 254