Addison Wesley - SAP Prozesse - ABAP Programmierung
Addison Wesley - SAP Prozesse - ABAP Programmierung
Addison Wesley - SAP Prozesse - ABAP Programmierung
ABAP®-Programmierung
Edition SAP®
Bernd Matzke
ABAP/4
3., erweiterte Auflage, 1999, ISBN 3-8273-1553-0
Gerhard Oberniedermaier
Vertriebslogistik mit SAP R/3
1. Auflage, 2000, ISBN 3-8273-1610-3
Michael Umlauff
SAP R/3 Übungsbuch
1. Auflage, 2001, ISBN 3-8273-1788-6
Erich Dräger
Projektmanagement mit SAP R/3
2. Auflage, 2001, ISBN 3-8273-1707-X
Gerhard Oberniedermaier
Daten- und Dokumentenmanagement mit SAP R/3
1. Auflage, 2001, ISBN 3-8273-1761-4
®
Rainer Riekert
ABAP -Programmierung
®
Fortgeschrittene
Programmiertechniken
für ABAP
Sämtliche in diesem Buch abgedruckten Abbildungen und Bildschirmabzüge unterliegen dem Urheber-
recht © der SAP AG, Neurottstraße 16, D-69190 Walldorf.
SAP®, R/2®, R/3®, mySAP.com®, RIVA®, ABAP®, SAPaccess®, SAPmail®, SAPOffice®, SAP-EDI®,
SAP Business Workflow®, SAP EarlyWatch®, SAP ArchiveLink®, R/3 Retail®, ALE/WEB®, SAPTRONIC® sind
eingetragene Warenzeichen der SAP AG.
Andere Produktnamen werden nur zur Identifikation der Produkte verwendet und können eingetragene
Marken der entsprechenden Hersteller sein.
Die Informationen in diesem Produkt werden ohne Rücksicht auf einen eventuellen Patentschutz
veröffentlicht.
Warennamen werden ohne Gewährleistung der freien Verwendbarkeit benutzt.
Bei der Zusammenstellung von Texten und Abbildungen wurde mit größter Sorgfalt vorgegangen.
Trotzdem können Fehler nicht vollständig ausgeschlossen werden.
Verlag, Herausgeber und Autoren können für fehlerhafte Angaben und deren Folgen weder eine
juristische Verantwortung noch irgendeine Haftung übernehmen.
Für Verbesserungsvorschläge und Hinweise auf Fehler sind Verlag und Herausgeber dankbar.
Alle Rechte vorbehalten, auch die der fotomechanischen Wiedergabe und der Speicherung in
elektronischen Medien.
Die gewerbliche Nutzung der in diesem Produkt gezeigten Modelle und Arbeiten ist nicht zulässig.
Fast alle Hardware- und Softwarebezeichnungen, die in diesem Buch erwähnt werden, sind gleichzeitig
auch eingetragene Warenzeichen oder sollten als solche betrachtet werden.
Umwelthinweis:
Dieses Produkt wurde auf chlorfrei gebleichtem Papier gedruckt.
Die Einschrumpffolie – zum Schutz vor Verschmutzung – ist aus umweltverträglichem und recycling-
fähigem PE-Material.
10 9 8 7 6 5 4 3 2 1
04 03 02 01
ISBN 3-8273-1754-1
Printed in Germany
Für Robert Senger
Inhaltsverzeichnis
Vorwort 11
Kapitel 1
Grundlagen zur ABAP-Programmierung 13
1.1 Allgemeines 13
1.2 ABAP-Reports 13
1.3 Dialogtransaktionen 30
1.4 Benennen und verwenden von Variablen 37
1.5 Unterprogramm-Techniken 39
1.6 Typgruppen 42
1.7 Literale im Programmcode 44
Kapitel 2
Parametrisieren von Programmen 47
2.1 Warum Programme parametrisierbar machen? 47
2.2 Verwendung von Benutzerparametern 48
2.3 Anpassung über Berechtigungen 52
2.4 Kundeneigene Customizing-Tabellen 58
2.5 Funktionscodes als Programmschalter 66
2.6 Welche Methode verwenden 68
2.7 Zusammenfassung 71
Kapitel 3
Spezielle Dialogelemente 73
3.1 Tree-Views nach der »alten« Methode 73
3.2 Tab-Strips 119
3.3 Nochmal Bäume: Die »neue« Baumdarstellung 129
3.4 DropDown-Listen 165
3.5 Table-Views 170
7
Inhaltsverzeichnis
Kapitel 4
Arbeiten mit Texten 187
4.1 Textobjekte mit Formatierungen 188
4.2 Verwendung von Textobjekten 204
4.3 Texte ohne Formatierungen 206
4.4 Verwendete und wichtige Funktionsbausteine 221
Kapitel 5
Programmierung SAP-Grafik 229
5.1 Allgemeines zur Grafik 229
5.2 Grafiken über die Funktionsbausteinschnittstelle 230
5.3 Geschäftsgrafiken mit GRAPH_2D 230
5.4 Geschäftsgrafiken mit GRAPH_MATRIX_2D 237
5.5 Grafiken mit der Controls Technology 244
5.6 Erstellen einer Grafik mit einer Datenreihe 250
5.7 Darstellung mehrerer Datenreihen 261
5.8 Verwendete Funktionsbausteine 265
Kapitel 6
Batch-Input-Techniken 269
6.1 Was ist Batch-Input 269
6.2 Warum Batch-Input? 270
6.3 Funktionsweise von Batch-Input 271
6.4 Erzeugen einer Batch-Input-Tabelle 273
6.5 Verwendung von CALL TRANSACTION 280
6.6 Erzeugung einer Batch-Input-Mappe 285
6.7 Programmgesteuertes Abspielen von Batch-Input-Mappen 287
6.8 Der Batch-Input-Recorder 287
6.9 Tipps, Tricks & Fallen 293
6.10 Verwendete und wichtige Funktionsbausteine 302
Kapitel 7
Einplanen von Hintergrundjobs 305
7.1 Jobs in SAP R/3 305
7.2 Erstellen eines einfachen Jobs 306
7.3 Freigeben und Einplanen eines Jobs 312
7.4 Eingeplante Jobs freigeben 317
7.5 Jobs periodisch wiederholen 317
7.6 Einplanen eines Reports als Job 318
7.7 Verwendete Funktionsbausteine 318
Kapitel 8
Programmierung mit Verbuchern 325
8.1 Architektur von R/3 326
8.2 Logical Units of Work 331
8.3 Asynchrone Programmiertechniken 334
8
Kapitel 9
Programmieren mit Sperren 343
9.1 Allgemeines zu Sperrmechanismen 343
9.2 Der Sperrmechanismus von R/3 344
9.3 Sperren von Anwendungsobjekten 345
9.4 Bündeln von Sperranfragen 351
9.5 Anlegen von eigenen Sperrobjekten 352
9.6 Verwendete Funktionsbauteine 355
Kapitel 10
Versenden von Mails 359
10.1 SAPOffice – Das Ablagesystem in R/3 359
10.2 Senden einer einfachen Textmitteilung 361
10.3 Mails mit Ausführungsparametern 368
10.4 Verwendete Funktionsbausteine 374
Literaturverzeichnis 377
Stichwortverzeichnis 379
Inhaltsverzeichnis
9
Vorwort
Bei meiner Arbeit in den letzten Jahren sah ich mich immer wieder mit Proble-
men konfrontiert, zu denen es keine oder nur unzureichende Dokumentation
oder Literatur gab. Aufgrund der Schwierigkeiten, hilfreiche Informationen zu
den Themen zu finden erwies sich die Realisierung der Aufgaben oft als sehr
schwierig. Eine logische Konsequenz daraus war die Überlegung, das gewonne-
ne Wissen für Kollegen festzuhalten, um das Wissen im Team zur Verfügung zu
stellen. Der Aufwand, eine solche Dokumentation zu erstellen ist jedoch sehr
hoch und das Tagesgeschäft lässt leider oftmals viel zu wenig Raum für diese,
vermeindlich unproduktiven, Tätigkeiten. Und so kommt es, dass viele Pro-
grammierer immer wieder für die gleichen Probleme Lösungen erarbeiten müs-
sen.
Dieses Buch setzt Kenntnisse in der Programmiersprache ABAP voraus. Es han-
delt sich hierbei also nicht in erster Linie um ein Lehrbuch für die Programmier-
sprache ABAP. Hier sei auf entsprechende Bücher wie z. B. das sehr gute Buch
ABAP/4 von Bernd Matzke verwiesen.
Das Ziel dieses Buches ist ein anderes. Es soll die Programmiersprache ABAP in
der Anwendung zeigen. Die Kapitel versuchen jeweils einen Aspekt der Pro-
grammierung in ABAP detailliert und praxisnah zu betrachten. Dies umfasst
zum Teil konkrete Programmierprobleme wie z.B. die Programmierung mit den
neuen Dialog-Controls in Kapitel 3. Andere Kapitel behandeln nicht so konkrete
Themen, sondern zielen vielmehr darauf ab, über das reine Handwerk der Im-
plementierung von Programmen hinaus zu gehen und Fertigkeiten zu vermit-
teln, die die Qualität Ihrer Programme steigern sollen. Als Beispiel hierfür sei
Kapitel 2 erwähnt.
Die Kapitel dieses Buches bilden in sich abgeschlossene Einheiten, die in belie-
biger Reihenfolge gelesen werden können. Ausgenommen hiervon sind die
Kapitel 3 und 4, denen das gleiche Beispielprogramm zugrunde liegt.
11
Vorwort
Das erste Kapitel fällt im Vergleich zu den anderen Kapiteln etwas aus dem
Rahmen. Es ist gedacht, demjenigen, der gerade Kenntnisse in ABAP erworben
hat, aber noch keine eigenen Programme geschrieben hat, eine Hilfe an die
Hand zu geben, wie man den zunächst leeren Bildschirm mit Leben füllen kann.
Aber auch dem erfahreneren Programmierer kann das Kapitel sicherlich noch
die eine oder andere Anregung zur Gestaltung seiner Programme geben.
Die Quelltexte der meisten Beispielprogramme dieses Buches finden Sie auf der
beiliegenden CD. Da jedoch in manchen Kapiteln das zuvor erstellte Beispiel-
programm weiterentwickelt wird, um neue oder andere Möglichkeiten aufzu-
zeigen, können nicht alle Programmversionen lückenlos zur Verfügung gestellt
werden.
Sämtliche Programme wurden in einem R/3-System Release 4.6C entwickelt
und getestet.
Da das Format der Transportdateien sich immer wieder ändert und in den meis-
ten Fällen sehr schwierig ist, fremde Programme in das System einzuspielen,
wurde darauf verzichtet, direkt importierbare Dateien für die Beispiele zur Ver-
fügung zu stellen. Die Objekte der Entwicklungsumgebung, die nicht als Text-
dateien zur Verfügung gestellt werden können, müssen dabei vom Leser manu-
ell erstellt werden. Anhand der Ausführungen in den jeweiligen Kapiteln sollte
dies jedoch kein Problem darstellen.
Zum Schluss möchte ich noch Herrn Christian Schneider vom Verlag Addison-
Wesley für seine Geduld bei der Erstellung dieses Buches danken. Ihnen, dem
Leser, wünsche ich viel Spaß beim Lesen verbunden mit der Hoffnung, dass Ih-
nen viel mühsames Ausprobieren bei den dargestellten Themen erspart bleibt.
Rainer Riekert
Hannover im Mai 2001
12
Grundlagen zur ABAP-
Programmierung
1
1.1 Allgemeines
Dieses Kapitel ist in erster Linie an die Leser gerichtet, die zwar die Syntax der
Sprache ABAP kennen, aber erst wenige Programme geschrieben haben.
Die Ausführungen dieses Kapitels sollen nicht als Regeln verstanden werden,
die vom Programmierer eingehalten werden müssen. Es handelt sich vielmehr
um Anregungen, die sich aus der täglichen Arbeit mit R/3 und ABAP entwi-
ckelt haben und dem Neuling helfen sollen, sich schneller im System zurechtzu-
finden.
Sicher sind nicht alle hier dargestellten Anregungen für jeden Leser sinnvoll
oder praktikabel. Vielmehr sollen die Ausführungen dem Leser helfen, seinen
Programmierstil zu entwikkeln oder weiterzuentwickeln. Besonderes Augen-
merk verdienen in diesem Punkt hausinterne Konventionen, die in fast jedem
Betrieb, der R/3 einsetzt, in der einen oder anderen Form vorhanden sind.
1.2 ABAP-Reports
Beim Anlegen eines neuen Programms in ABAP muss im Dynpro »Programm-
attribute« (siehe Abbildung 1.1) der Typ des Programms festgelegt werden. Pro-
gramme vom Typ »Report« (in älteren Releaseständen Typ »1«) werden auch
ausführbare Programme genannt.
Reports können weiter unterteilt werden in logische Datenbanken, deren Zweck
darin besteht, Daten aus der Datenbank zu extrahieren und anderen Program-
men zur Verfügung zu stellen und Online-Reports (auch SQL-Reports genannt).
Reports, die eine logische Datenbank implementieren, sind alleine nicht ablauf-
fähig und bedürfen immer eines rufenden Programms, um sinnvolle Ergebnisse
zu liefern.
13
1.2 ABAP-Reports
Abbildung 1.1
Programmeigenschaften (© SAP AG)
Es gibt drei Möglichkeiten, einen Report in R/3 zu starten. Bei der Definition ei-
ner Dialogtransaktion kann entweder ein Start-Dynpro eines Modulpools oder
ein Online-Report definiert werden (siehe Abbildung 1.2). Im letzten Fall wird
beim Start der Transaktion automatisch der Report geladen und zur Ausfüh-
rung gebracht. Wenn eine solche Zuordnung nicht existiert, kann ein Online-Re-
port über die Transaktion SA38 direkt gestartet werden. Der wesentliche Unter-
schied dieser beiden Methoden liegt im Berechtigungswesen in R/3. Benutzer,
die für die Transaktion SA38 berechtigt sind, können alle Reports starten, die dies
nicht durch einen expliziten AUTHORITY CHECK verhindern. Bei Dialogtransaktio-
nen kann die Berechtigungsprüfung an jede einzelne Transaktion gebunden
werden, was – bei Transaktionen, die Reports aufrufen – die explizite Berechti-
gungsprüfung am Anfang des Reports nicht ersetzen kann, sondern lediglich
auf höherer Ebene ergänzt.
In der Transaktion SA38 können Reports auch über ihren eindeutigen Namen ge-
startet werden. Dies ist insbesondere für Programme sinnvoll, denen kein
Transaktionscode zugewiesen wurde. Aus ABAP-Programmen heraus können
Reports über das SUBMIT-Kommando der Sprache ABAP gestartet werden.
14
Abbildung 1.2
Eigenschaften eines Transaktionscode (© SAP AG)
15
1.2 ABAP-Reports
1.2.2 Datendeklarationen
In Anschluss an die REPORT-Klausel folgen die globalen Datendeklarationen, die
wiederum unterschieden werden können in
◗ Tabellen
◗ Typen
◗ Konstanten
◗ Strukturen/interne Tabellen
◗ einfache Daten
1. Der in diesem Zusammenhang verwendete Begriff Datei ist nicht mit einer Datei auf der
Ebene des jeweiligen Datei-Systems gleichzusetzen. Vielmehr werden ABAP-Programme
und alle dazugehörigen Objekte der Programmierung in der R/3-Datenbank abgelegt.
Der Begriff Datei ist hier also als Modularisierungseinheit zu sehen, deren Eigenschaften
denen einer Datei auf Dateisystemebene sehr ähnlich sind.
16
Die Reihenfolge dieser Deklarationen ist beliebig. Die hier gezeigte Reihenfolge
versucht die Daten mit absteigender Wichtigkeit im Programm darzustellen.
Tabellendeklarationen
Tabellendeklarationen werden in ABAP mit der TABLES-Anweisung durchge-
führt. Diese ist für jede im Programm verwendete Datenbanktabelle notwendig.
Weiterhin müssen Data Dictionary-Strukturen, die im Programm direkt ver-
wendet werden sollen, auf diese Art deklariert werden. Werden Strukturen nur
zur Beschreibung anderer Datenfelder mit der LIKE-Anweisung oder der
INCLUDE-STRUCTURE-Anweisung benutzt, ist eine Deklaration mit der TABLES-An-
weisung hingegen nicht notwendig.
Ein wichtiges Ziel der Programmierung sollte stets sein, den erzeugten Pro-
grammcode so lesbar wie möglich zu gestalten. Aus diesem Grund ist es sinn-
voll, hinter die Tabellennamen als Kommentar zumindest den Beginn der Kurz-
beschreibung der jeweiligen Tabelle oder Struktur zu setzten.
Besser lesbar als
TABLES: AUFK, CRHD, CRTX, EQUI, MARA, MAKT.
Es sollte immer bedacht werden, dass ein anderer Programmierer ein Pro-
gramm lesen und verstehen muss, der nicht so tief in der jeweiligen Materie
steckt, wie der ursprüngliche Autor. Auch erleichtert die hier gezeigte alphabe-
tische Sortierung der Deklarationen ein schnelles Zurechtfinden in der Aufzäh-
lung – insbesondere dann, wenn sehr viele Tabellen verwendet werden.
Eigene Datentypen
In ABAP besteht die Möglichkeit, basierend auf den ABAP-Typen oder Data
Dictionary-Elementen neue Datentypen innerhalb eines Programms zu dekla-
rieren.
Die Deklarationen eigener Datentypen erfolgt mit der TYPES-Anweisung nach
der Syntax:
TYPES <t> [ TYPE <type> | LIKE <dd-objekt> ].
17
1.2 ABAP-Reports
Während die Form mit TYPE Bezug zu einem ABAP-Typ (egal ob elementar oder
benutzerdefiniert) herstellt, referenziert die Variante mit LIKE ein Data Dictio-
nary-Objekt.
Diese Datentypen sind ausschließlich in dem Programm verwendbar, in dem sie
deklariert werden. Sollen eigene Datentypen über mehrere Programme hinweg
verwendet werden, ist die Definition der Datentypen in einem so genannten
TYPE-POOL (Programmtyp »T«) abzulegen. Man spricht hierbei von globalen Typ-
definitionen, da diese an beliebigen Stellen im R/3-System verwendet werden
können. Sollen in einem Programm globale Typdeklarationen verwendet wer-
den, müssen diese zuerst über die ABAP-Anweisung
TYPE-POOLS <typepoolname>.
Durch die Verwendung des Datentyps T_ANSWER sowohl in der Definition der
Konstanten als auch der des Datenfeldes G_ANSWER findet hier eine weitgehende
Entkopplung von der Realisierung als einstelliges Charakter-Felds statt. Soll die
Repräsentation auf einen anderen Datentyp verändert werden, kann dies ein-
fach durch Änderung der Typ-Deklaration und der global gültigen Konstanten
18
realisiert werden. Eine Modifikation des eigentlichen Programmcodes ist nicht
notwendig, bei häufiger Verwendung des Datentyps eine erhebliche Erleichte-
rung.
Werden die TYPES- und CONSTANTS-Anweisungen in einer eigenen Typgruppe ab-
gelegt, erfolgt hiermit eine vollkommene Entkopplung der Datentypen vom
Programmcode.
Konstanten
Bereits das kleine Beispiel im vorigen Abschnitt zeigt deutlich, wie sinnvoll die
Verwendung von Konstanten in Programmen ist. Konstanten werden in ABAP
genauso wie normale Datenobjekte entweder mit Bezug zu einem Typ oder mit
Bezug auf ein Data Dictionary-Element definiert.
Im Programmcode sollten im Normalfall keine literalen Informationen verwen-
det werden. Stattdessen bietet sich die Verwendung von Konstanten an. Da-
durch wird zum einen sichergestellt, dass für den gleichen Sachverhalt immer
der gleiche Wert verwendet wird, zum anderen vermindert es den Aufwand,
eine Einstellung im Programm zu ändern, erheblich.
Konstanten können entweder als einfache Datenobjekte oder – wie im Beispiel
gezeigt – als Struktur definiert werden. Die Verwendung von Strukturen bietet
Strukturen
Den bisher beschriebenen Informationen folgen die Datendeklarationen für die
globalen Datenobjekte des Programms. Diese werden mit der DATA-Anwei-
sung der ABAP-Sprache deklariert. Für Strukturen lautet die Grundform dieser
Anweisung
DATA: BEGIN OF <struktur>,
<feldname> [ TYPE <typ> | LIKE <dd-objekt> ],
...
END OF <struktur>.
19
1.2 ABAP-Reports
Die Anzahl der Felder in einer Struktur ist beliebig. Ebenso können in einer
Struktur sowohl Felder mit Typbezug als auch Felder mit Data Dictionary-Be-
zug deklariert werden. Die Deklaration der Struktur endet mit der Sequenz END
OF <struktur>.
Existiert bereits eine Data Dictionary-Struktur mit dem gleichen Aufbau, wie es
das Datenobjekt hat, kann das Datenobjekt auch durch die vereinfachte Schreib-
weise
DATA: <struktur> LIKE <dd-struktur>.
deklariert werden.
Soll eine interne Struktur den gleichen Aufbau wie eine bereits im Data Dictio-
nary definierte Struktur oder Tabelle haben und noch weitere Felder hinzufü-
gen, ist das folgende Konstrukt passend.
DATA: BEGIN OF <struktur>,
<feld> [ TYPE <typ> | LIKE <dd-objekt> ].
INCLUDE-STRUCTURE <dd-struktur>.
DATA: END OF <struktur>.
Auf diese Weise können neue Felder beliebig mit Data Dictionary-Strukturen
kombiniert werden. Es können sowohl mehrere neue Felder in der Struktur
angelegt werden, als auch Strukturen aus dem Data Dictionary eingebunden
werden.
Zu beachten ist lediglich, dass die Anweisung INCLUDE-STRUCTURE eine eigene
ABAP-Anweisung ist. Die vorige DATA-Anweisung muss also mit einem Punkt
abgeschlossen und die Folgende erneut mit dem Schlüsselwort DATA eingeleitet
werden.
Interne Tabellen
Interne Tabellen werden genauso wie Strukturen deklariert. Auch hier stehen
die drei oben beschriebenen Methoden zur Verfügung, werden jedoch um ein
weiteres Schlüsselwort ergänzt.
Im ersten Fall wird die BEGIN OF-Anweisung um das Schlüsselwort OCCURS,
gefolgt von der initialen Größe des zur Verfügung gestellten Datenbereichs
ergänzt. In früheren Versionen von R/3 musste hier ein möglichst nahe an der
erwarteten Tabellengröße liegender Wert angegeben werden. In neueren Release-
ständen von R/3 spielt dies keine Rolle mehr und es kann generell der Wert 0
verwendet werden.
DATA: BEGIN OF <itab> OCCURS 0,
<feldname> [ TYPE <typ> | LIKE <dd-objekt> ],
...
END OF <itab>.
20
Bei der zweiten Variante muss beachtet werden, dass R/3 in diesem Fall stan-
dardmäßig keine Kopfzeile zur Tabelle definiert. Diese muss bei Bedarf explizit
durch den Zusatz WITH HEADER LINE definiert werden. Die vollständige Anwei-
sung zur Deklaration einer internen Tabelle mit Dictionary-Bezug lautet dem-
nach
DATA: <itab> LIKE <dd-struktur> OCCURS 0 [ WITH HEADER LINE ].
In Release 4.0 sind umfangreiche Möglichkeiten bei der Definition von internen
Tabellen hinzugekommen. So können interne Tabellen jetzt wie Datenbankta-
bellen mit einem Schlüsselbereich versehen oder automatisch sortiert abgelegt
werden. Bei diesen Definitionen handelt es sich immer um eine Erweiterung der
oben dargestellten Methoden. Die bisherigen Anweisungen zur Verwendung
interner Tabellen funktionieren nach wie vor und werden jetzt unter dem Tabel-
lentyp STANDARD TABLE zusammengefasst. Die neuen Funktionalitäten werden in
den Tabellentypen HASHED TABLE bzw. SORTED TABLE definiert.
Einfache Datenfelder
An letzter Stelle des Deklarationsbereichs eines Programms stehen schließlich
die Deklarationen der einfachen Datenfelder. Diese werden, so wie die internen
Tabellen und Strukturen, mit der DATA-Anweisung der ABAP-Sprache dekla-
riert.
Die Syntax der Anweisung in diesem Fall lautet:
DATA <feld> [ TYPE <typ> | LIKE <dd-objekt> ].
Bei der Programmierung von Reports sollte die Verwendung von globalen Da-
21
1.2 ABAP-Reports
und
SELECTION-SCREEN END OF SCREEN <dynnr>.
definiert. Werden diese Kommandos nicht verwendet, beziehen sich die Anga-
ben implizit auf das Standard-Selektions-Dynpro mit der Nummer 1000. Über
den optionalen Zusatz AS WINDOW kann ein Selektions-Dynpro als modales Dia-
logfenster definiert werden. Warnungen und Meldungen, die während der Ver-
arbeitung des Dynpros auftreten, werden in diesem Fall ebenfalls als modale
Dialogfenster dargestellt.
Zwischen diesen beiden Anweisungen (falls vorhanden) wird der Aufbau des
Dynpros beschrieben. Hierzu stehen die ABAP-Kommandos PARAMETERS, SELECT-
OPTIONS sowie SELECTION-SCREEN zur Verfügung.
Wenn Reports mit der SUBMIT-Anweisung gestartet werden, kann das zu ver-
wendende Selektions-Dynpro als Parameter an die SUBMIT-Anweisung ange-
fügt werden. Reports mit mehrere Selektions-Dynpros werden in der folgen-
den Form gestartet:
SUBMIT <report> USING SELECTION-SCREEN <dynnr>.
22
Die Grundform dieser Deklaration ist identisch mit der Grundform der DATA-
Anweisung. Gleichzeitig wird mit dieser Anweisung auch das Feld <p> als glo-
bales Datenobjekt angelegt.
Wenn ein Parameter mit Dictionary-Bezug deklariert wird, werden automatisch
die Eigenschaften des entsprechenden Feldes für das Dynpro-Feld übernom-
men. Dies schließt auch die (F1)-Hilfe sowie die Eingabehilfe (F4) ein. Soll auch
die Werthilfeprüfung aus der Data Dictionary-Definition übernommen werden,
ist der optionale Zusatz VALUE CHECK an die PARAMETERS-Anweisung anzufügen.
Über den Zusatz DEFAULT <wert> kann das Dynpro-Feld mit einem Wert vorbe-
legt werden. Diese Vorbelegung erfolgt vor der Ausführung aller Ereignisblö-
cke. Während der Verarbeitung der Ereignisblöcke kann dieser Defaultwert
demnach wieder überschrieben werden.
Character-Felder mit der Länge 1 können auf dem Selektions-Dynpro auch als
Ankreuzfelder bzw. Auswahlfelder dargestellt werden.
Die Definition als Ankreuzfeld erfolgt mit dem Zusatz AS CHECKBOX. Soll das
Ankreuzfeld beim Starten des Dynpros vorselektiert sein, kann dies mit dem
Zusatz DEFAULT ‘X‘ erreicht werden.
Eine Gruppe von Auswahlfeldern wird auf dem Dynpro generiert, indem das
Feld mit dem Zusatz RADIOBUTTON GROUP <gruppenname> deklariert wird. Alle Fel-
der einer Auswahlfeld-Gruppe müssen hierbei den gleichen Gruppennamen
verwenden. Auch hier gilt, dass das Feld, welches initial ausgewählt sein soll,
mit dem Zusatz DEFAULT ‘X‘ versehen werden muss.
Weitere Optionen sind bei der Verwendung der PARAMETERS-Anweisung die Op-
tionen OBLIGATORY für Pflichtfelder, DECIMALS <n> für die Anzahl von Dezimalstel-
Selektionen
Während über die PARAMETERS-Anweisung lediglich Einzelwerte erfasst werden
können, besteht bei SELECT-OPTIONS die Möglichkeit komplexere Wertabgrenzun-
gen zu erfassen. Über die ABAP-Anweisung
SELECT-OPTIONS <option> FOR <feld>.
wird eine interne Tabelle mit dem in Tabelle 1.1 dargestellten Aufbau deklariert.
Diese Tabelle kann in der WHERE-Klausel der SELECT-Anweisung direkt mit dem
Operator IN verwendet werden.
23
1.2 ABAP-Reports
Tabelle 1.1
Struktur der internen Tabellen für SELECT-OPTIONS
Eine solche Tabelle kann – ohne Selektionsbildschirm – auch mit dem ABAP-
Kommando RANGES deklariert werden. Die RANGES-Anweisung hat den Aufbau
RANGES <rangetab> FOR <feld>.
erzeugt werden. <n> steht hierbei für die Anzahl Leerzeilen. Wird <n> nicht
angegeben, wird als Default der Wert 1 angenommen.
24
Um eine horizontale Trennlinie auf dem Bildschirm zu erzeugen, verwendet
man die Anweisung
SELECTION-SCREEN ULINE [ [ / ] <pos>(<len>) ] [ MODIF ID <key> ].
Für die Position der Linie gelten die gleichen Parameter wie bei der WRITE-An-
weisung in Listen. Mit dem optionalen Zusatz MODIF ID <key> kann auf die Linie
zugegriffen werden, um dynamische Änderungen am Dynpro-Layout vorzu-
nehmen (siehe Abschnitt 2.2.3).
Kommentare und Zeichenketten werden auf dem Dynpro mit der Anweisung
SELECTION-SCREEN COMMENT [ / ] <pos(len)> <text> [ FOR FIELD <feld> ]
[ MODIF ID <key> ].
erzeugt. Bei Kommentaren kann, wie bei horizontalen Linien, die Position in-
nerhalb der Bildschirmzeile über die optionalen Parameter / <pos(len)> festge-
legt werden. Soll der Text einen Bezug zu einem Eingabefeld auf dem Dynpro
haben, kann dieser mit der Option FOR FIELD <feld> hergestellt werden.
Sollen mehrere Elemente in einer Dynpro-Zeile erscheinen, müssen diese zwi-
schen die Anweisungen
SELECTION-SCREEN BEGIN OF LINE.
und
SELECTION-SCREEN END OF LINE.
platziert werden. Innerhalb einer Zeile kann die Position eines Elementes mit
der Anweisung
festgelegt werden.
Elemente auf einem Dynpro können zu Gruppen zusammengefasst werden.
Diese Gruppen können bei Bedarf mit einem Rahmen eingefasst und dieser mit
einem Titel versehen werden. Hierzu müssen die Elemente der Gruppe zwi-
schen den Anweisungen
SELECTION-SCREEN BEGIN OF BLOCK <block> [ WITH FRAME [ TITLE <titel> ] ]
[ NO INTERVALS ].
und
SELECTION-SCREEN END OF BLOCK <block>.
gesetzt werden.
So wie im Dynpro-Editor ist es auch auf Selektionsbildschirmen möglich, eine
Drucktaste darzustellen und dieser einen Funktionscode zuzuweisen. Auch
hierfür wird die SELECTION-SCREEN-Anweisung verwendet.
25
1.2 ABAP-Reports
Innerhalb einer Zeile kann die Position und Größe des Buttons identisch mit den
Optionen beim PARAMETERS-Kommando oder bei der Option ULINE beim SELEC-
TION-SCREEN-Kommando definiert werden.
Wird die Drucktaste auf dem Dynpro gedrückt, wird sofort das Ereignis AT SE-
LECTION-SCREEN (siehe Kapitel 1.2.4) ausgelöst. Welcher Button gedrückt wurde,
kann aus dem Feld UCOMM der Systemstruktur SSCRFIELDS entnommen werden. Zu
beachten ist, dass diese Struktur vor der Verwendung in einer TABLES-Anwei-
sung deklariert werden muss.
Über die Option MODIF ID <key> kann die Schaltfläche dynamisch im Programm
verändert werden (z.B. ausgeblendet).
Der Wert <fkey> kann hierbei die Werte »1« bis »5« annehmen und identifiziert
die einzelnen Schaltflächen. Im Programm müssen die Schaltflächen anschlie-
ßend mit einer Beschriftung versehen werden. Hierzu stehen in der Struktur
SSCRFIELDS die Felder FUNCTXT_01 bis FUNCTXT_05 zur Verfügung. Wird eine der
Schaltflächen im Dynpro gedrückt, wird sofort das Ereignis AT SELECTION-SCREEN
ausgelöst. Der Funktionscode des gedrückten Buttons wird im Feld SSCRFIELDS-
UCOMM abgelegt und ist FC01 bis FC05 für die fünf möglichen Schaltflächen.
Das folgende, an sich vollkommen nutzlose Beispiel soll die Verwendung von
Drucktasten auf dem Selektions-Dynpro verdeutlichen.
REPORT ZBTEST.
TABLES: SCCRFIELDS.
26
SELECTION-SCREEN: FUNCTION KEY 1,
FUNCTION KEY 2,
FUNCTION KEY 3.
INITIALIZATION.
* Beschriftung der Drucktasten setzten
SSCRFIELDS-FUNCTXT_01 = TEXT-001.
SSCRFIELDS-FUNCTXT_02 = TEXT-002.
SSCRFIELDS-FUNCTXT_03 = TEXT-003.
AT SELECTION-SCREEN.
* Auswerten der gedruckten Drucktaste
CASE SSCRFIELDS-UCOMM.
WHEN C_FCODES-FC01.
P_UCOMM = C_FCODES-FC01.
WHEN C_FCODES-FC02.
P_UCOMM = C_FCODES-FC02.
WHEN C_FCODES-FC03.
P_UCOMM = C_FCODES-FC03.
ENDCASE.
START-OF-SELECTION.
* Ausgabe des Inhalts des Feldes
WRITE: / TEXT-004,
Im Beispiel wird auf dem Selektions-Dynpro ein Feld ausgeben, da ein leeres Se-
lektions-Dynpro in R/3 nicht angezeigt wird. Über die Schaltflächen kann man
das angezeigte Feld mit den Werten FC01 bis FC03 vorbelegen.
Die Beschriftung der Drucktasten wird über die Textelemente des Reports
ermittelt. Nach dem Drücken der (F8)-Taste wird der START-OF-SELECTION-Block
ausgeführt, der den aktuellen Wert des Eingabefeldes des Selektions-Dynpros
ausgibt.
27
1.2 ABAP-Reports
Die Verarbeitung eines Reports beginnt immer mit dem Ereignis LOAD-OF-PRO-
GRAMM (siehe Abbildung 1.3). Dieses Ereignis, es wird auch Programmkonstruk-
tor genannt, wird ausgelöst, sobald der Report geladen wird. Es wird vor allen
anderen Ereignisblöcken ausgeführt.
Diesem Ereignis folgt immer das Ereignis INITIALIZE. Es wird jedesmal beim
Starten des Reports prozessiert. Im Verarbeitungsblock dieses Ereignisses kön-
nen Steuertabellen gepuffert oder Variable initialisiert werden. Weiterhin kön-
nen in diesem Bereich dynamische Änderungen am Selektions-Dynpro vorge-
nommen werden.
Abbildung 1.3
Ereignisfolge im Report - Dialogteil
28
die Kontrolle wieder an den ABAP-Prozessor zurückgibt, wird zunächst für
jedes Feld des Selektionsbildschirms das Ereignis AT SELECTION-SCREEN FIELD
<feld> ausgelöst. Hier können Prüfungen auf der Feldebene vorgenommen wer-
den. Wird in diesen Ereignisblöcken eine Fehlermeldung (E-Message) ausgege-
ben, ist lediglich dieses Feld des Dynpros eingabebereit. Im Anschluss an diese
Ereignisse wird das Ereignis AT SELECTION-SCREEN ausgelöst. Hier werden die
Eingaben des Benutzers für alle Felder plausibilisiert und bei Bedarf Fehlermel-
dungen ausgegeben. Fehlermeldungen in diesem Block bewirken, dass alle Fel-
der des Selektions-Dynpros eingabebereit bleiben.
Ableitungen von Feldinhalten sind in der Regel besser im AT SELECTION-SCREEN
OUTPUT-Block aufgehoben, da sie auch dann funktionieren, wenn im INITIALIZE
oder auf anderem Wege Felder auf dem Dynpro vorbelegt werden. Wenn der
Benutzer keinen Funktionscode mit Typ »E« (Exit-Command) ausgelöst oder die
Selektion mit (F8) gestartet hat, kehrt die Verarbeitung anschließend wieder in
den AT SELECTION-SCREEN OUTPUT-Block zurück und prozessiert das Dynpro er-
neut.
Betätigt der Benutzer die (F8)-Taste, werden wie oben beschrieben zunächst die
AT SELECTION-SCREEN-Ereignisblöcke abgearbeitet und anschließend der Verar-
beitungsteil des Reports mit dem Block START-OF-SELECTION ausgeführt. Hier fin-
det die eigentliche Listenverarbeitung eines Reports statt. Bei konsequenter An-
wendung sollten hier lediglich die Daten für die Listenverarbeitung selektiert
und im anschließend auszuführenden Ereignisblock END-OF-SELECTION ausgege-
ben werden. In der Praxis wird auf diese Teilung häufig verzichtet und die ge-
samte Programmlogik des Reports im START-OF-SELECTION-Ereignis realisiert.
Mit dem END-OF-SELECTION-Ereignisblock ist der dunkel verarbeitete Teil des Pro-
29
1.3 Dialogtransaktionen
Anfang jeder Seite das Ereignis TOP-OF-PAGE ausgelöst. Hier kann ein zusätzli-
cher Seitenkopf oder Ähnliches ausgegeben werden.
Während der Listanzeige werden die Ereignisse AT LINE-SELECTION, AT USER-
COMMAND sowie AT PFxxx prozessiert. Ersteres wird ausgelöst, wenn der Benutzer
einen Doppelklick auf eine der Listenzeilen durchführt oder den Cursor auf die
gewünschte Zeile setzt und (F2) betätigt2. Das Ereignis AT USER-COMMAND wird
ausgeführt, wenn ein im GUI-Status definierter Funktionscode ausgelöst wur-
de. Um diese Funktionalität zu nutzen, muss ein eigener Listenstatus definiert
werden. Dies ist nicht notwendig, wenn die Funktionstasten mit dem Ereignis
AT PF<xx> ausgewertet werden, wobei <xx> für die Funktionstasten von 01 bis 24
steht. SAP empfiehlt dieses Vorgehen jedoch lediglich für vorläufige Testversi-
onen von Programmen. Sollen in einem produktiven Umfeld Funktionstasten in
der Listenanzeige ausgewertet werden, wird das Vorgehen mit AT USER-COMMAND
nahegelegt.
Werden diese drei Ereignisse in einem Programm ausgewertet, spricht man von
interaktivem Reporting. Auch hier gilt, dass der Report, wenn die Listenanzeige
verlassen wird, erneut gestartet und mit dem Ereignis INITIALIZE fortgefahren
wird.
1.3 Dialogtransaktionen
2. Hierzu muss im aktuellen Status ein Funktionscode PICK existieren und der Funktions-
taste (F2) zugewiesen sein. Im standardmäßig verwendeten GUI der Listendarstellung ist
dies der Fall.
30
1.3.2 Ablaufsteuerung und Module
In der Ablaufsteuerung von Dynpros können so genannte Module aufgerufen
werden. Module sind spezielle Unterprogramme der Ablaufsteuerung. Module
haben keine Schnittstelle für Parameter, können also ausschließlich auf globale
Datenfelder zugreifen. Die Implementierung von Modulen sollte lediglich ein-
fache Strukturen enthalten. Komplexe Logik ist besser in FORM-Routinen zu im-
plementieren, die wiederum von den Modulen aufgerufen werden. Diese FORM-
Routinen erhalten sämtliche benötigten Parameter in der Aufrufschnittstelle
übergeben und nutzen keine globalen Datenfelder, um an anderer Stelle wieder-
verwendet werden zu können.
Die Namen von Modulen sollten immer die Dynpro-Nummer, in der sie ver-
wendet werden, beinhalten. Soll auf mehreren Dynpros die gleiche Funktiona-
lität ausgeführt werden, ist das passende Mittel, für jedes Dynpro eigene Modu-
le zu implementieren und die eigentlich auszuführende Logik in gemeinsam
genutzte FORM-Routinen auszulagern.
In der Ablauflogik können Module auf drei verschiedene Arten aufgerufen wer-
den.
Als einfache Aufrufe nach dem Muster:
MODULE <modulname> [ ON EXIT COMMAND ].
Modulaufrufe, die ohne Bezug zu einem Dynpro-Element stehen, werden auf je-
den Fall während der Ablaufsteuerung aufgerufen. Bei Verwendung dieser Me-
thode ist unbedingt auf die Ausführungen des nächsten Abschnitts bezüglich
des Transports der Dynpro-Feldinhalte in die Programmvariable zu achten.
31
1.3 Dialogtransaktionen
In diesem Fall wird zunächst der Feldinhalt aus dem Dynpro-Feld in die
Programmvariable transportiert und anschließend das Modul aufgerufen. Der
optionale Zusatz ON REQUEST bewirkt, dass das Modul nur aufgerufen wird,
wenn im Dynpro-Element eine Veränderung vorgenommen wurde, während
der Zusatz ON INPUT bewirkt, dass das Modul immer aufgerufen wird, wenn der
Feldinhalt des Dynpro-Elements nicht initial ist.
Wird innerhalb der Verarbeitung des Moduls eine Fehlermeldung ausgegeben
(E-Message), sind alle Dynpro-Felder bis auf das in der FIELD-Anweisung ange-
gebene Feld gegen Eingaben gesperrt. Lediglich das definierte Dynpro-Feld ist
eingabebereit. Der Benutzer muss durch Veränderung der Eingabe in diesem
Feld den Fehler beheben oder ein Exit-Command (siehe oben) auslösen. Andere
Module werden in diesem Zustand nicht verarbeitet.
Sollen Prüfungen über mehrere Dynpro-Felder vorgenommen werden, so kön-
nen diese in einer CHAIN-Anweisung gruppiert und gemeinsam ausgewertet
werden. Zwischen den Anweisungen CHAIN und ENDCHAIN können mehrere FIELD-
Anweisungen und ggf. mehrere MODULE-Aufrufe stehen.
CHAIN.
FIELD: <feld1>,
<feld2>,
....
<feldn>.
MODULE <modul1>.
MODULE <modul2>.
MODULE <modul3> [ ON CHAIN-REQUEST | ON CHAIN-INPUT ].
ENDCHAIN.
32
Eine spezielle Anweisung in der Ablaufsteuerung bildet die LOOP-Schleife, die
Verwendung findet, wenn auf dem Dynpro entweder Step-Loops oder Table-
Views enthalten sind.
33
1.3 Dialogtransaktionen
INVALID_DYNPROFIELD = 02
INVALID_DYNPRONAME = 03
INVALID_Dynpro-Nummer = 04
INVALID_REQUEST = 05
NO_FIELDDESCRIPTION = 06
UNDEFINED_ERROR = 07.
Im Parameter DYNAME wird der Name des Modulpools, in dem das betreffende
Dynpro definiert wurde, übergeben. Das Feld DYNUMB enthält die Nummer des
Dynpros im jeweiligen Modulpool. Mit dem Parameter TRANSLATE_TO_UPPER kann
festgelegt werden, dass der Inhalt der übertragenen Felder in Großbuchstaben
konvertiert wird. Schließlich wird dem Funktionsbaustein eine interne Tabelle
übergeben, die beim Aufruf des Funktionsbausteins lediglich die Namen der zu
übertragenden Felder enthält und nach erfolgreichem Aufruf auch die Werte
der jeweiligen Felder sowie ein Flag, ob das Feld auf dem Dynpro eingabebereit
ist oder nicht. Dieser Tabellenparameter hat den Aufbau der Dictionary-Struk-
tur DYNPREAD, wie in Tabelle 1.2 dargestellt.
Tabelle 1.2
Aufbau der Struktur DYNPREAD
Sollen mit dieser Funktion Feldinhalte aus einem Step-Loop oder einem Table-
View ausgelesen werden, muss zunächst durch einen Aufruf der Funktion
DYNP_GET_STEPL die gewünschte Loop-Zeile gesetzt werden, bevor mit
DYNP_VALUE_READ der Feldinhalt dieser Zeile ausgelesen werden kann. Die Feld-
namen des Parameters DYNPFIELDS enthalten keinen Index oder Ähnliches, um
eine bestimmte Loop-Zeile zu bestimmen.
Die Aufruf-Schnittstelle dieses Funktionsbausteins ist folgendermaßen aufge-
baut:
FUNCTION DYNP_GET_STEPL
DYNP_VALUES_UPDATE
Mit dem Funktionsbaustein DYNP_VALUE_UPDATE können Feldinhalte in einem
Dynpro vor dem dazugehörgen PBO-Ereignis gesetzt werden. Dies macht vor
allen Dingen dann Sinn, wenn mit einer Werthilfe mehrere Feldinhalte gesetzt
34
werden sollen (z.B. bei Arbeitsplätzen), oder wenn vor der Ausgabe einer Warn-
meldung der neue Wert bereits in das betreffende Dynpro-Feld übertragen wer-
den soll.
Die Aufrufschnittstelle des Funktionsbausteins ähnelt der des Funktionsbau-
steins DYNP_VALUE_READ, lediglich der Parameter TRANSLATE_TO_UPPER entfällt hier.
FUNCTION DYNP_VALUE_UPDATE
IMPORTING
DYNAME
DYNUMB
TABLES
DYNPFIELDS
EXCEPTIONS
INVALID_ABAPWORKAREA = 01
INVALID_DYNPROFIELD = 02
INVALID_DYNPRONAME = 03
INVALID_Dynpro-Nummer = 04
INVALID_REQUEST = 05
NO_FIELDDESCRIPTION = 06
UNDEFINED_ERROR = 07.
35
1.3 Dialogtransaktionen
CHAIN.
FIELD: ARBPL,
WERK.
MODULE CHECK_ARBPL ON CHAIN-REQUEST.
ENDCHAIN.
...
In der Implementierung des Moduls CHECK_WERK wird lediglich das Werk auf
Gültigkeit überprüft. Die Werke sind in R/3 in der Tabelle T001W definiert. Pri-
märschlüssel dieser Tabelle ist neben dem Mandanten ausschließlich das ent-
sprechende Werk. Bei der Prüfung besteht daher keine Abhängigkeit zu einem
anderen Dynpro-Feld.
Anders verhält es sich allerdings bei dem Feld ARBPL. Ein Arbeitsplatz wird in
SAP in der Tabelle CRHD definiert. Der Primärschlüssel dieser Tabelle besteht je-
doch nicht aus dem Arbeitsplatz, sondern aus der Objekt-Typ und dem Objekt-
Schlüssel. Der Arbeitsplatz bildet zusammen mit dem Werk einen Sekundär-
schlüssel auf diese Tabelle. Es genügt demnach nicht, lediglich das Feld ARBPL in
eine Feldprüfung aufzunehmen, obwohl im Beispiel auch der Wert des Werkes
zum Zeitpunkt der Prüfung bereits ins ABAP übertragen wurde. Ist der Arbeits-
platz nicht im angegebenen Werk gültig, muss der Benutzer die Möglichkeit be-
sitzen, sowohl Arbeitsplatz als auch Werk zu ändern, um einen gültigen Zu-
stand herzustellen und die Feldprüfungen zu passieren. Aus diesem Grund
wurde hier eine CHAIN-Anweisung über diese beiden Felder implementiert. Falls
das eingegebene Werk gültig ist, der Arbeitsplatz jedoch in diesem Werk nicht
existiert, stehen dem Benutzer beide Felder offen, um seine Eingaben zu korri-
gieren.
Wie bereits erwähnt, stehen dem Benutzer nach Auftreten einer Fehlermeldung
nur die Felder des aktuellen Kontext zur Verfügung. Der Benutzer kann diesen
Zustand nur verlassen, indem er über diese Felder einen gültigen Zustand her-
stellt oder ein Exit-Command auslöst. Daher sollte in jedem Dynpro zumindest
36
eine Abbrechen-Funktion als Exit-Command definiert werden, um dem Benut-
zer bei Bedarf zumindest das Abbrechen der Transaktion zu ermöglichen. Be-
denken Sie hierbei jedoch, dass im Modul, in dem das Exit-Command verarbei-
tet wird, keinerlei Feldinhalte automatisch übernommen werden. Unabhängig
davon, wo in der Ablaufsteuerung die Anweisung MODULE <module> AT EXIT
COMMAND steht, wird dieses Modul vor jeder übrigen Verarbeitung des PAI verar-
beitet. Unbenommen ist jedoch die oben beschriebene Möglichkeit, Dynpro-
Feldinhalte über den Funktionsbaustein DYNP_READ_VALUES auszulesen und zu
verarbeiten.
37
1.4 Benennen und verwenden von Variablen
durch Verwendung von Präfixen bewerkstelligt werden. Tabelle 1.3 soll als An-
regung für verschiedene Präfixe dienen, die in Programmen verwendet werden
können.
Präfix Verwendung
L_ lokale Variable
G_ globale Variable
C_ Konstanten
T_ Typ-Deklarationen
Tabelle 1.3
Vorschlagswerte für Variablen-Präfixe
38
verwendet werden. Diese beiden Schreibweisen sind identisch, die erste ist je-
doch aufgrund ihrer Kompaktheit zu bevorzugen, wenn keine weiteren Felder
in die interne Tabelle eingefügt werden sollen. Beachtenswert ist hierbei, dass
die INCLUDE-Anweisung eine eigene Anweisung ist. Die einleitende DATA-Anwei-
sung muss daher unbedingt mit einem Punkt abgeschlossen werden. Für die END
OF-Anweisung muss eine neue DATA-Anweisung eingefügt werden.
1.5 Unterprogramm-Techniken
In R/3 sind Unterprogramm-Techniken zur Strukturierung des Programm-
codes vorgesehen. Im Einzelnen handelt es sich hierbei um FORM-Routinen im
lokalen Kontext sowie Funktionsbausteine im globalen Umfeld.
Während FORM-Routinen in jedem ABAP-Programm verwendet werden können,
müssen Funktionsbausteine in speziellen Modulen, den so genannten Funkti-
onsgruppen definiert werden. Aber auch in anderer Hinsicht unterscheiden sich
FORM-Routinen wesentlich von Funktionsbausteinen.
Analog dazu erfolgt der externe Aufruf einer FORM-Routine mit in der Form:
PERFORM <name>(programm) [ TABLES <tabellenparameter> ... ]
[ USING <in-parameter> ... ]
[ CHANGING <in-out-parameter> ... ].
39
1.5 Unterprogramm-Techniken
1.5.2 Funktionsbausteine
Während die Deklaration und Verwendung von FORM-Routinen eher spontan er-
folgen kann, verlangen Funktionsbausteine ein etwas formelleres Vorgehen.
Funktionsbausteine verfügen, ähnlich wie FORM-Routinen, über eine wohldefi-
nierte Aufrufschnittstelle, über die sowohl Parameter in den Funktionsbaustein
hineingereicht, als auch Ergebnisparameter zurückgeliefert werden können.
40
Anders als FORM-Routinen, die im laufenden Programmquelltext an nahezu be-
liebiger Stelle eingefügt werden können, müssen Funktionsbausteine in speziel-
len ABAP-Programmen, den Funktionsgruppen (auch FUNCTION POOL), angelegt
werden.
Funktionsgruppen sind ABAP-Programme, die keinen direkt ausführbaren
Charakter haben, sondern lediglich Funktionsbausteine enthalten können.
Funktionsgruppen können ebenfalls globale Datendeklarationen besitzen. Die-
se sind jedoch nur für die Elemente der Funktionsgruppe sichtbar und erhalten
Ihren Wert solange das aufrufende Dialogprogramm/Report aktiv ist.
Da Funktionsbausteine in eigenen ABAP-Programmen abgelegt sind, haben sie
– anders als interne FORM-Routinen – keine Möglichkeit, auf die globalen Daten,
die im rufenden Programm deklariert wurden, zuzugreifen.
Im Gegensatz zu FORM-Routinen können Funktionsbausteine verwendet werden,
um asynchrone Verarbeitungen zu bestimmten Zeitpunkten zu starten. Näheres
hierzu wird in Kapitel 8 beschrieben.
Funktionsbausteine werden in R/3 in einer zentralen Funktionsbibliothek
verwaltet. Aus diesem Grund müssen die Namen von Funktionsbausteinen
systemweit eindeutig sein. Beim Aufruf eines Funktionsbausteins ist es nicht
notwendig, die Funktionsgruppe, in der der gewünschte Funktionsbaustein
definiert wurde, anzugeben.
Neben den von FORM-Routinen her bekannten Schnittstellenparametern können
in der Funktionsbibliothek zu jedem Funktionsbaustein so genannte Aus-
nahmen (auch Exceptions) definiert werden, die einen fehlerhaften Abbruch
der Verarbeitung des Funktionsbausteins anzeigen. Wird innerhalb eines
41
1.6 Typgruppen
1.6 Typgruppen
Typgruppen sind spezielle ABAP-Programme, die, ähnlich wie Funktionsgrup-
pen, für sich gesehen nicht alleine ablaufbar sind. Typgruppen dienen lediglich
als Deklarationspool für Benutzerdatentypen und Konstantendefinitionen. Aus
diesem Grund sind in Typgruppen nur TYPES- und CONSTANTS-Deklarationen er-
laubt.
Ein Typpool wird innerhalb der ABAP-Workbench unter den Data Dictionary-
Objekten eingeordnet. Eine Typgruppe kann im Object Navigator (Transaktion
SE80) unter der Rubrik »Anderes Objekt« angelegt werden. In dem in Abbil-
dung 1.4 dargestellten Dynpro muss der Name der neuen Typgruppe eingege-
ben werden. Dieser darf bis zu fünf Stellen lang sein und muss im Kundenna-
mensraum liegen. Im Anschluss an das Einstiegsdynpro erscheint ein weiteres
Dynpro, in dem eine Beschreibung zu der Typgruppe definiert werden muss.
Bevor schließlich der Editor für die Typgruppe geöffnet wird, muss zuletzt noch
die Entwicklungsklasse, in der die Typgruppe angelegt werden soll, festgelegt
werden.
Sind alle diese Schritte durchlaufen, erscheint der ABAP-Editor. Jetzt können
beliebig Typen und Konstanen deklariert werden. Zu beachten ist jedoch, dass
alle innerhalb einer Typgruppe deklarierten Objekte den Namen der Typgrup-
pe gefolgt von einem Unterstrich als Präfix im Namen tragen müssen. Die in
Abschnitt 1.4 empfohlenen Präfixe müssen also noch einen weiteren Präfix er-
halten.
Exemplarisch soll an dieser Stelle nochmals das Beispiel aus Abschnitt 1.2.2
(Eigene Datentypen) aufgegriffen werden.
Es wird eine Typgruppe ZBUCH definiert, die sowohl die Typ-Deklaration als
auch die Definition der Programmkonstanten enthält. Der Quelltext der Typ-
gruppe hat in diesem Fall folgendes Aussehen:
TYPE-POOL ZBUCH.
42
IF G_ANSWER = ZBUCH_C_ANSWER-YES.
...
ENDIF.
...
Abbildung 1.4
Einstieg in Typgruppe anlegen (© SAP AG)
43
1.7 Literale im Programmcode
1.7.1 Textliterale
Es gibt verschiedene Arten von Literalen, die in Programmen vorkommen kön-
nen. Text-Literale sind Strings oder Zeichenketten, die zur Ausgabe auf einem
Dynpro oder in einer Liste verwendet werden. Aus Gründen der Übersetzbar-
keit von Programmen ist es dringend angeraten, auf Text-Literale innerhalb des
Programmcodes vollständig zu verzichten. Die Alternative zur Anweisung
WRITE 'Berechtigungen je Benutzer'.
könnte
WRITE TEXT-001.
lauten. Im zweiten Fall muss das Textelement 001 des Progamms entsprechend
dem ersten Beispiel lauten. Eine Kombination beider Möglichkeiten stellt die
Form
WRITE 'Berechtigungen je Benutzer'(001).
da. Ist das Textelemente 001 in der jeweiligen Sprache nicht definiert, kommt der
im Programmcode abgelegte Text zur Ausgabe. Bei der Programmierung kann
zunächst die zuerst genannte Form geschrieben werden. Bei einem Doppelclick
auf das Textliteral erkennt R/3, dass hierzu noch kein Textelement definiert
wurde und schlägt die automatische Erzeugung eines Textelements mit der
nächsten freien Nummer vor. Wird hiervon Gebrauch gemacht, wird der Zusatz
(001) anschließend automatisch in den Programmquelltext eingefügt.
44
den und die datentechnische Repräsentation von Typen von ihrer Verwendung
in Programmen entkoppeln.
Die Verwendung von Konstanten ist im Programmbeispiel in Abschnitt 1.2.3
anschaulich dargestellt. Um die gültigen Funktionscodes der Drucktastenleiste
nicht im Quelltext des Reports zu verstecken, werden am Beginn des Pro-
gramms Konstanten innerhalb einer Struktur definiert. Über den Verwendungs-
nachweis können alle Stellen, an denen der Wert im Kontext ausgewertet wird,
leicht nachvollzogen werden. Eine Möglichkeit, die bei Verwendung von Lite-
ralen – vor allem in großen Programmen mit mehreren Includes – nicht so ein-
fach möglich wäre.
45
Parametrisieren von
Programmen
2
2.1 Warum Programme parametrisierbar
machen?
Der große Erfolg der Software R/3 auf dem Markt liegt darin begründet, dass
sämtliche betriebswirtschaftlichen Abläufe in Unternehmen beliebiger Größe im
System abgebildet werden können. Dies rührt nicht daher, dass die Prozesse in
allen Unternehmen gleich sind oder im Rahmen der SAP-Einführung gleich ge-
staltet werden sollen, sondern vielmehr von der großen Flexibilität von R/3.
Diese Anpassungsfähigkeit wurde von SAP über verschiedene Techniken reali-
siert. Im Einzelnen sind dies:
◗ Benutzerparameter
◗ Berechtigungen
◗ Customizing- und Steuertabellen
◗ Erweiterungskonzept
Über die genannten Möglichkeiten kann – wo vorgesehen - auf Programme im
SAP-System Einfluss genommen werden, ohne den Programmcode selbst zu
verändern. Diese Anforderung kann jedoch nicht nur aus den von SAP entwi-
ckelten Programmen heraus entstehen, auch in Kundenentwicklungen macht
die Möglichkeit der Einflussnahme von außen großen Sinn. Hierbei stehen je-
doch nur die ersten drei der oben genannten Möglichkeiten zur Verfügung, da
seitens SAP keine Möglichkeit zur Verfügung gestellt wird, eigene Customer-
Exits oder Menu-Exits im Rahmen des SAP-Erweiterungskonzeptes zu definie-
ren. Da das Erweiterungskonzept von SAP im Zusammenhang dieses Kapitels
nicht verwendbar ist, wird in diesem Abschnitt nicht weiter auf dieses Thema
eingegangen. Dafür kann eine weitere Möglichkeit genutzt werden, den Pro-
grammlauf von außen beeinflussbar zu machen, indem Funktionscodes als
Schalter definiert werden. Diese Methode eignet sich jedoch nur, um einfache
47
2.2 Verwendung von Benutzerparametern
48
immer als Zeichenkette abgelegt ist. Parameter-Ids müssen vor ihrer Verwen-
dung in Programmen oder Dynpros definiert werden. Dies geschieht entweder
im Object Navigator (Transaktion SE80) oder über die Transaktion SM31 durch
Erzeugung eines Eintrages in der Tabelle TPARAM, wobei hier der Transport des
Tabelleneintrags in das Produktivsystem nicht vergessen werden darf. Die
Parameter-Ids werden im Kundennamensraum angelegt.
In R/3 werden Benutzerparameter hauptsächlich als komfortabler, transakti-
onsübergreifender Zwischenspeicher genutzt. Sie sind die einzige Möglichkeit,
Informationen über die verschiedenen Modi einer Anmeldung hinweg auszu-
tauschen. Beispielsweise steht die Auftragsnummer eines neu erstellten Auf-
trags im SAP nach Beendigung der Standard-Transaktion in der Parameter-ID
ANR zur Verfügung. In Dynpros kann definiert werden, ob Feldinhalte aus Para-
meter-Ids vorbelegt werden bzw. Feldeingaben den Wert von Benutzerparame-
tern überschreiben.
An anderen Stellen verwendet jedoch auch SAP Benutzerparameter, um das
Verhalten von Transaktionen zu beeinflussen. So steuert beispielsweise die Pa-
rameter-ID EKG die Feldattribute von Feldern in der Einkaufssicht einer Bedarf-
sanforderung (im Modul MM-Einkauf).
Abbildung 2.1
Benutzer pflegen: Parameter (© SAP AG)
49
2.2 Verwendung von Benutzerparametern
Jeder Benutzer kann die Werte der Benutzerparameter nach der Anmeldung
selbst festlegen. Abbildung 2.1 zeigt das Dynpro der Transaktion SU52 (»Benut-
zer pflegen: Parameter«). Durch Eintragen einer Parameter-ID in die linke Spal-
te und einen Wert in das entsprechenden Feld auf der rechten Seite können Ini-
tialwerte für Benutzerparameter festgelegt werden. Wie bereits erwähnt,
können auf dieser Maske nicht die aktuellen Werte der Benutzerparameter und
auch nicht alle gesetzten Benutzerparameter ersehen werden. Beim Speichern
werden jedoch die hier dargestellten Benutzerparameter wieder auf den im
Dynpro angezeigten Wert zurückgesetzt.
Eine entsprechende Berechtigung vorausgesetzt, können die Benutzerparame-
ter für beliebige Benutzer in der Transaktion SU01 (Benutzer pflegen: Einstieg)
angezeigt oder gepflegt werden.
schreibend und
GET PARAMETER ID <Parameter> FIELD <Field>.
lesend zugegriffen. Der Wert von <Parameter> muss hierbei in Hochkomma ge-
schrieben werden. Eine Zuweisung von Werten ist ausschließlich über Variable
möglich. Literale können – auch beim SET – nicht verwendet werden.
Ein Benutzerparameter ist eine Kombination aus einem Schlüssel und einem
Wert, d.h. jeder Parameter-ID kann genau ein Wert zugewiesen werden, es kön-
nen keine strukturierten Datentypen verwendet werden.
50
...
PROCESS-BEFORE-OUTPUT
...
MODULE 9000_OPEN_CLOSE_FIELDS.
...
In der Form-Routine wird zunächst eine lokale Variable zur Aufnahme des
Wertes aus dem Benutzerparameter definiert. Das eigentliche Auslesen des Be-
nutzerparameters erfolgt in einer eigenen FORM-Routine GET_PARAMETER_VALUE. In
den folgenden Beispielen dieses Kapitels wird lediglich die Implementierung
dieser FORM-Routine ausgetauscht, die Implementierung des Moduls und der
Routine OPEN_CLOSE_FIELDS bleibt im Folgenden unberührt.
Der Name des Benutzerparameters ist – wie bereits erwähnt – bis zu zwanzig-
stellig. Sollen eigene Benutzerparameter verwendet werden, so muss deren
Name im Kundennamensraum liegen. In älteren Versionen von R/3 war die
Länge der Parameter-Ids auf drei Stellen beschränkt.
51
2.3 Anpassung über Berechtigungen
SCREEN-OUTPUT = 0.
SCREEN-INVISIBLE = 1.
MODIFY SCREEN.
ENDIF.
ENDLOOP.
...
ENDFORM.
52
2.3.1 Berechtigungswesen in R/3
Grundsätzlich gilt im R/3-System, dass ein Benutzer für nichts berechtigt ist, es
sei denn, er oder sie hat eine Berechtigung explizit zugewiesen bekommen. Die-
se Berechtigungen und das Prüfen auf das Vorhandensein der entsprechenden
Berechtigungen ist Gegenstand des Berechtigungswesens in R/3.
Abbildung 2.2
Zusammenfassung von Berechtigungsobjekten in Klassen.
Beispiel:
Das Berechtigungsobjekt ZPARAM soll ein Feld ZTCODE mit Bezug zur Dictionary-
Domäne TCODE beinhalten. In einer konkreten Berechtigung könnte dieses Feld
beispielsweise mit den Einzelwerten ZFLIGHTGUI und ZFLIGHTSRV, den Transakti-
onscodes von Dialogtransaktionen belegt werden. Zusätzlich könnte auch der
53
2.3 Anpassung über Berechtigungen
Abbildung 2.3
Zusammenfassung von Berechtigungen in Profile
54
Prüfen von Berechtigungen
Das Prüfen, ob ein Benutzer eine konkrete Berechtigung hat, erfolgt mit der
ABAP-Anweisung AUTHORITY-CHECK. Mit Ausnahme von sehr wenigen Fällen
(z.B. Dialogtransaktionen) muss das Prüfen von Berechtigungen immer explizit
vom Programmierer realisiert werden. Dies geschieht hierbei ausschließlich auf
der Ebene des in R/3 integrierten Berechtigungswesens. Entsprechende Mecha-
nismen, wie sie die Hersteller der zugrunde liegenden Datenbanksysteme in der
Regel ausliefern, finden hier keine Beachtung.
Das Berechtigungswesen in R/3 sieht vor, dass alles im System verboten ist, was
nicht explizt durch Berechtigungen erlaubt wurde. Demnach kann das System
in seiner Grundausrichtung als sicher betrachtet werden. Sicherheitslücken ent-
stehen nur durch manuellen Eingriff von Administratoren. Umgekehrt gilt al-
lerdings auch, dass alles erlaubt ist, wenn keine Berechtigungsprüfung es ver-
hindert. Diese Aussage geht in Richtung der Programmierer, die angehalten
sind, schützenswerte Sachverhalte mit entsprechenden Berechtigungen zu ver-
sehen.
Diese Prüfungen werden explizit mit der ABAP-Anweisung AUTHORITY-CHECK,
deren Syntax im Folgenden dargestellt ist, realisiert.
AUTHORITY-CHECK <Berechtigungsobjekt>
ID <Feldname 1> FIELD <Wert 1>
ID <Feldname 2> FIELD <Wert 2>
...
ID <Feldname n> FIELD <Wert n>.
Hierbei muss für jedes Feld, welches innerhalb des Berechtigungsobjekts defi-
niert wurde, eine Überprüfung in Form eines ID <Feldname> FIELD <Wert>-Blockes
stattfinden.
55
2.3 Anpassung über Berechtigungen
56
Abbildung 2.4
Anlegen eines Berechtigungsfeldes (© SAP AG)
Abbildung 2.5
Anlegen eines Berechtigungsobjekts (© SAP AG)
57
2.4 Kundeneigene Customizing-Tabellen
AUTHORITY-CHECK 'ZPARAM'
ID 'ZTCODE' FIELD SY-TCODE.
58
Beim Anlegen von Steuertabellen sollte nicht vergessen werden, die dazugehö-
rigen Pflegedialoge zu generieren. Ohne die Pflegedialoge können keine Einträ-
ge in die Tabellen mit der Transaktion SM30 (bei Tabellen mit längeren Tabellen-
namen) bzw. SM31 (bei Tabellennamen bis 5 Zeichen Länge) vorgenommen
werden.
Da Customizing-Tabellen in der Regel nicht viele Sätze enthalten, können die
Zugriffszeiten auf die Einstellungen in der Regel vernachlässigt werden. Gege-
benenfalls können Zugriffe durch Verwendung von Pufferung nochmals opti-
miert werden. Aus Sicht der Programm-Ablaufgeschwindigkeit spielt die Ver-
wendung von Customizing-Tabellen demnach keine entscheidende Rolle.
Customizing-Tabellen können grob in zwei Typen unterschieden werden. Der
erste Typ, im Folgenden generische Steuertabellen genannt, definieren eine
Struktur, in der Einstellungen verschiedenster Arten abgelegt werden können.
Die zweite Art von Customizing-Tabellen definieren Einstellungen für einen
speziellen Sachverhalt. Sowohl der Schlüsselbereich als auch die Datenfelder
der Customizing-Tabelle sind dabei speziell auf eine Problemstellung abge-
stimmt. Dieser Tabellentyp wird im Folgenden spezielle Steuertabelle genannt.
Es ist sehr zu empfehlen, Customizing-Tabellen mandantenabhängig zu defi-
nieren. Oft sind unterschiedliche Voraussetzungen in den verschiedenen Man-
danten im vornhinein nicht abschätzbar. Zudem erschweren die Standard-
Mechanismen in R/3 die Pflege mandantenübergreifender Objekte.
59
2.4 Kundeneigene Customizing-Tabellen
Tabelle 2.1
Aufbau einer einfachen generischen Steuertabelle
60
Spezielle Customizing-Tabellen sollten dabei nach den gleichen Grundsätzen
angelegt werden, wie generische Steuertabellen. Die Tabellen sollten nach Mög-
lichkeit mandantenabhängig definiert werden. Um eine kontrollierte Pflege der
Tabelleninhalte zu ermöglichen, ist die Generierung von Pflegedialogen unbe-
dingt zu empfehlen.
61
2.4 Kundeneigene Customizing-Tabellen
Tabelle 2.2
Struktur für generische Steuertabelle
62
MANDT KEY USER VALUE
SY-MANDT MOREINFO *
Tabelle 2.3
Inhalt aus generischer Steuertabelle für MOREINFO
Die Einträge dieser Tabelle sollen bewirken, dass die zusätzlichen Felder für alle
Benutzer ausgeblendet werden, außer für den Benutzer »RIEKERT«. In der vor-
liegenden Implementierung könnte der erste Satz der Tabelle auch entfallen, da
als Default angenommen wird, dass das Flag nicht gesetzt ist (siehe Programm-
code).
Im Beispiel aus Abschnitt 2.2.3 muss in diesem Fall lediglich der Teil der FORM-
Routine OPEN_CLOSE_FIELDS verändert werden, in dem die Variable L_MOREINFO be-
legt wird.
Die GET PARAMETER-Anweisung der Routine muss entsprechend dem abgebilde-
ten Quellcode-Fragment verändert werden.
...
FORM GET_PARAMETER_VALUES CHANGING P_MOREINFO TYPE C.
63
2.4 Kundeneigene Customizing-Tabellen
Das Beispiel geht davon aus, dass die TABLES-Anweisung zur Tabelle ZBSP01 im
Deklarationsteil des Programms enthalten ist. Im ersten Schritt wird versucht,
auf die Tabelle mit dem korrekten Benutzernamen zuzugreifen. Ist für diesen
Schlüssel kein Satz in der Tabelle enthalten, wird in einem zweiten Schritt ein
Platzhalter ('*') für den Benutzernamen verwendet. Dieses Vorgehen ist sinn-
voll, um auch Default-Einstellungen in der Steuertabelle dokumentieren zu
können. Je nach Umfang des Schlüssels, können ein oder mehrere Felder mit
Platzhaltern versehen abgefragt werden.
Zuletzt wird der Wert dem Übergabeparameter der FORM-Routine zugewiesen. Sind
beide Zugriffe erfolglos, wird der Wert aus der leeren Kopfzeile übernommen.
Tabelle 2.4
Struktur für spezielle Steuertabelle
64
Über das Feld USER soll, wie im vorigen Beispiel, eine Einschränkung auf Benut-
zerebene möglich sein. Weiterhin kann das gewünschte Feld über die Kombina-
tion von Dynpro-Nummer und der ersten Feldgruppe (SCREEN-GROUP1) spezifi-
ziert werden. Für einen realen Einsatz könnte der Schlüssel noch wesentlich
ausgefeilter definiert werden, um weitere Steuermöglichkeiten, z.B. auf Felde-
bene, zuzulassen.
In der Tabelle 2.5 werden im vorliegenden Beispiel die in der Tabelle abgebilde-
ten Sätze eingefügt.
Tabelle 2.5
Datensätze für Tabelle ZBSP02
Die Einträge sollen bewirken, dass für alle Benutzer die Felder, bei denen der
Wert des Feldes SCREEN-GROUP1 »ZMI0« ist, ausgeblendet werden. Für den Benut-
zer »RIEKERT« wird davon abweichended definiert, dass die Felder sichtbar
aber nicht eingabebereit sein sollen.
Für dieses Beispiel muss die Implementierung der FORM-Routine OPEN_CLOSE_
FIELDS aus dem Abschnitt 2.2.3 neu implementiert werden.
...
FORM OPEN_CLOSE_FIELDS.
DATA: L_ZBSP02 LIKE ZBSP02 OCCURS 0 WITH HEADER-LINE.
65
2.5 Funktionscodes als Programmschalter
IF SY-SUBRC NE 0.
READ TABLE L_ZBSP02 WITH KEY USER = '*'.
GRP1 = SCREEN-GROUP1.
ENDIF.
* Feldattribute modifizieren
SCREEN-INPUT = L_ZBSP02-EIN.
SCREEN-REQUIRED = L_ZBSP02-OBL.
SCREEN-OUTPUT = L_ZBSP02-OUT.
SCREEN-INVISIBLE = L_ZBSP02-UNSI.
MODIFY SCREEN INDEX SY-TABIX.
ENDLOOP.
...
ENDFORM.
...
Zunächst werden alle Sätze der Steuertabelle, die den aktuellen User und das
aktuelle Dynpro betreffen in die interne Tabelle L_BSP02 eingelesen. Wenn dabei
keine Sätze gefunden wurden, wird die Verarbeitung abgebrochen.
Anschließend wird in einer Schleife über alle Dynpro-Elemente geprüft, ob die
Darstellungsattribute für das Feld verändert werden sollen oder nicht. Ist dies
der Fall, werden die Screen-Attribute gemäß den Einträgen der Steuertabelle
verändert.
Da es sich hier um eine spezielle Steuertabelle handelt, kann hier nicht nur ein
Flag abgelegt werden, sondern es werden alle wesentlichen Attribute mit dem
tatsächlichen Wert hinterlegt. Diese Variante bietet also bezüglich der Steuer-
barkeit eine erheblich höhere Flexibilität als die zuvor dargestellte Methode mit
der generischen Steuertabelle. Allerdings können in dieser Tabelle ausschließ-
lich Darstellungsattribute für Dynpro-Elemente definiert werden, während in
der generischen Variante auch völlig andersartige Einstellungen abgelegt wer-
den könnten.
66
welches auch komplexe Parameter gesetzt werden könnten. Diese Möglichkeit,
die ein erhebliches Maß an Programmieraufwand mit sich bringt, soll an dieser
Stelle jedoch nicht weiter dargestellt werden.
Bei der Verwendung von Funktionscodes zum Steuern von Transaktionen er-
folgt die Implementierung zweistufig. Im Command-Handler des Programms
müssen die verwendeten Funktionscodes ausgewertet werden und im globalen
Datenbereich des Programms in Variablen hinterlegt werden. Das Abfragen des
Schalters erfolgt, wie bei den übrigen Methoden zur Parametrisierung auch, an
den jeweiligen beeinflussten Stellen im Programm, im Beispiel also in der FORM-
Routine GET_PARAMETER_VALUES.
Wird das Beispiel aus den vorigen Abschnitten aufgegriffen, genügt es also
nicht, lediglich die Implementierung der Routine GET_PARAMETER_VALUES anzupas-
sen, da hier lediglich die Schalter ausgewertet werden können. Unter der An-
nahme, dass ein globales Datenfeld G_MOREINFO angelegt wurde, sähe die Imple-
mentierung der Routine bei Verwendung dieser Methode wie dargestellt aus.
...
FORM GET_PARAMETER_VALUES CHANGING P_MOREINFO TYPE C.
ENDFORM.
...
Auch wenn es in diesem Beispiel überzogen wirkt, für die einfache Zuweisung
eine eigene FORM-Routine zu definieren, ist dieses Vorgehen generell zu empfeh-
len. Hierdurch kann das verwendete Konzept zur Parametrisierung bei Bedarf
leicht erweitert oder geändert werden. Eine Kapselung darartiger Funktionali-
WHEN 'MOREINFO_OFF'.
67
2.6 Welche Methode verwenden
G_MOREINFO = SPACE.
...
ENDCASE.
68
werden. Die SAP-Basis kann für jeden Benutzer individuell einen Initialwert für
den Benutzerparameter zuweisen, den der Benutzer aber nach Belieben verän-
dern kann.
Da Funktionscodes nicht von vornherein gesetzt werden können, bietet sich die-
se Methode vor allen Dingen an, um Debugging-Möglichkeiten zur Fehlersuche
ein- bzw. auszuschalten. Sie eignen sich nicht, um Transaktionen generell para-
metrisierbar zu machen.
Für Einstellungen, die das Ergebnis eines Programmes beeinflussen, sind Steu-
ermöglichkeiten über Benutzerparameter keinesfalls zu empfehlen, da im nach-
hinein keine Möglichkeit besteht, die Benutzerparameter eines Benutzers zum
Zeitpunkt des Programmlaufs nachzuvollziehen (Nachweismöglichkeit!).
Berechtigungsobjekte werden normalerweise im Bereich der Basis-Betreuung
angesiedelt. Ein Benutzer hat demnach nie die Möglichkeit, selber Einfluss auf
den Programmlauf zu nehmen. Bei der Verwendung von Steuertabellen kann
die Pflege der Tabellen an das SAP-Berechtigungskonzept gekoppelt werden.
Somit sind nahezu beliebige Konfigurationen der Pflegeberechtigungen für die
Steuerinformationen möglich.
2.6.2 Abgrenzbarkeit
Wie bereits erwähnt, sind die Werte von Benutzerparametern für jeden User ge-
trennt abgelegt. Es gibt hierbei weder Konzepte, um eine Einstellung für meh-
rere Benutzer in einem Schritt zu tätigen, noch Einstellungen an andere Kriteri-
en als eine Benutzerkennung zu binden. Einstellungen, die das gesamte System
oder eine Gruppe von Benutzern betreffen sollen, können demnach nicht mit
Benutzerparametern abgebildet werden. Benutzerberechtigungen sind ein Weg,
um derartige Parameter einzustellen, wenn das Kriterium für die Abgrenzung
69
2.6 Welche Methode verwenden
2.6.3 Realisierungsaufwand
Wie schon aus den bisherigen Ausführungen erkennbar, unterscheiden sich die
Methoden zur Parametrisierung nicht zuletzt durch den damit verbundenen
Aufwand bei der Programmerstellung. Aufwand meint hierbei nicht nur den
tatsächlichen Programmieraufwand, sondern umfasst auch notwendige Ab-
stimmungsprozesse im Unternehmen usw.
Während dieser bei der Verwendung von Benutzerparametern und Funktion-
scodes minimal ist, steigert er sich bei Verwendung von Berechtigungsobjekten
oder Steuertabellen erheblich. Welche dieser beiden Methoden einen höheren
Aufwand bedeutet, kann nicht pauschal gesagt werden. Bei der reinen Pro-
grammierung ist der Aufwand von Berechtigungsobjekten ähnlich niedrig wie
bei der Verwendung von Benutzerparametern, während er bei Steuertabellen
entsprechend hoch ist. Der Abstimmungsaufwand in den Unternehmen wird
allerdings in der Regel bei den Berechtigungsobjekten wesentlich höher liegen,
da Berechtigungen üblicherweise nach dem 4- oder gar 6-Augen-Prinzip verge-
ben und aktiviert werden3.
70
2.7 Zusammenfassung
Es ist häufig sehr sinnvoll, auf den Ablauf eigener Programme Einfluss nehmen
zu können, ohne den Programmquelltext zu ändern. Programmänderungen
führen in der Regel neue Tests und Abnahmeprozeduren nach sich, die selbst
eine kleine Modifikation sehr teuer werden lässt.
Tabelle 2.6 soll nochmals im Überblick die Vor- und Nachteile der hier vorge-
stellten Methoden gegenübergestellen.
71
Spezielle
Dialogelemente
3
3.1 Tree-Views nach der »alten« Methode
Die Verwendung von Baumdarstellungen zur strukturierten Darstellung hie-
rarchischer Informationen wird seit jeher in der Datenverarbeitung häufig ver-
wendet. Auch in R/3 ist diese Darstellungsmöglichkeit seit längerer Zeit verfüg-
bar.
In R/3 werden Baumdarstellungen (Tree-Views) an verschiedensten Stellen im
System verwendet, um hierarchisch strukturierte Informationen übersichtlich
zu präsentieren. Offenkundigstes Beispiel im R/3-Release 4.6C ist das Easy Ac-
cess-Menü, welches unmittelbar nach der Anmeldung an das System erscheint.
Diese Art Bäume darzustellen, hat erst in neuere Releasestände von R/3 Einzug
gehalten. In älteren Versionen von R/3 war eine andere Darstellung von Bäu-
men üblich, die dem ABAP-Programmierer sicherlich in Form der Transport-
Workbench (Transaktion SE09) am geläufigsten sind. Diese älteren Tree-Views
sind – im Gegensatz zu der modernen Variante - keine Dialogelemente im enge-
ren Sinne in R/3 sondern lediglich eine besondere Variante des interaktiven Re-
portings. Demzufolge können diese Tree-Views nicht im Dynpro-Editor ange-
legt werden und können auch nicht mit anderen Dialogelementen kombiniert
werden. Die Programmierung von Bäumen in der Form, wie sie in Reports am
geläufigsten sind, wird in diesem Abschnitt ausführlich dargestellt. Die neue
Variante, Bäume zu verwenden wird in Abschnitt 3.3 gezeigt. Diese Teilung
wurde vorgenommen, da im dazwischen liegenden Abschnitt ein Beispielpro-
gramm für Tab-Strips angelegt wird, welches als Trägerprogramm für die Dia-
logelemente in den darauffolgenden Abschnitten dient.
Die Dokumentation seitens SAP zu der älteren Variante ist nicht sehr ausführ-
lich. Dies liegt sicherlich nicht zuletzt daran, dass diese Tree-Views keine Funk-
tionalität der Sprache ABAP an sich darstellen, sondern auf einer Reihe von
Funktionsbausteinen beruhen, die in der Funktionsgruppe SEUT zusammenge-
73
3.1 Tree-Views nach der »alten« Methode
fasst sind. Es handelt sich also nicht um Sprachelemente, sondern um eine fort-
geschrittene Programmiertechnik. In diesem Kapitel soll die Verwendung der
wesentlichen Funktionsbausteine dieser Funktionsgruppe anhand eines Bei-
spiels gezeigt werden. Eine detaillierte Beschreibung jeder einzelnen Funktion
findet sich im Abschnitt 3.1.8 wieder. Das hier beschriebene Beispiel wird auch
in den folgenden Abschnitten dieses Kapitels verwendet werden.
Ein Baum besteht aus Knoten (Nodes), die andere Knoten miteinander verknüp-
fen (hier Verbindungsknoten genannt) und anderen, die am Ende der Hierar-
chie stehen und Blätter (Leafs) genannt werden. Dem Knoten auf der obersten
Ebene (Wurzel oder Root genannt) kommt hierbei eine besondere Rolle zu. Er
ist der einzige Knoten im gesamten Baum, der keine Beziehung zu einem über-
geordneten Knoten (Parent bzw. Vater) unterhält (siehe Abbildung 3.1). Alle in
der Hierarchie unterhalb des Wurzelknotens stehenden Knoten haben genau
eine Verbindung zu ihrem Elternknoten (Parent) und keine, eine oder mehrere
Verbindungen zu wiederum untergeordneten Knoten (Child, Kinder). Knoten
auf gleicher Ebene, die einen gemeinsamen Parent haben, werden Geschwister-
knoten genannt. Bei der SAP Realisierung von Bäumen ist die Unterscheidung
zwischen Knoten und Blättern lediglich eine aus dem Datenbestand resultieren-
de Eigenschaft eines Knotens. Ein Blatt kann jederzeit zum Verbindungsknoten
werden, indem ihm untergeordnete Knoten zugewiesen werden und umge-
kehrt kann ein Verbindungsknoten jederzeit zum Blatt werden, wenn der dar-
unter liegende Teilbaum entfernt wird.
Neben der eindeutigen ID, spielt bei der Verwendung von Knoten der Knoten-
name eine wesentliche Rolle. Während die ID wie gesagt eindeutig im gesamten
Baum ist, muss dies bei den Knotennamen nicht unbedingt der Fall sein. Über
einen Schalter des Funktionsbausteins RS_TREE_LIST_DISPLAY kann festgelegt
werden, dass während der Baumdarstellung angelegte oder umbenannte Kno-
ten keine bereits verwendeten Namen haben dürfen oder automatisch zu Refe-
renzknoten werden. Beim programmgesteuerten Manipulieren in den Knoten
eines Baumes existiert diese Einschränkung nicht. Trotzdem sollten Knoten mit
dem gleichen Namen auch dieselben semantischen Knoten beschreiben. Dies
wird realisiert, indem diese Knoten als Referenzknoten (Link-Knoten) angelegt
werden (siehe hierzu auch Abschnitt 3.1.5).
Die folgenden Abschnitte sollen die wesentlichen Aufgaben bei der Program-
mierung von Baumdarstellungen aufzeigen. Dies soll mit einem Beispielpro-
gramm exemplarisch gezeigt werden.
Das Beispiel verwendet Tabellen, die in jedem SAP-System vorhanden sind. Zu
Schulungszwecken hat SAP eine Reihe von Tabellen sowie deren Inhalt defi-
niert, die Flugbewegungen von Fluggesellschaften abbilden. Der Datenbestand
der Tabellen ist übersichtlich. SAP verwendet die Tabellen in den Programmier-
beispielen der ABAP-Schulungen.
74
Abbildung 3.1
Schematische Darstellung eines Baumes
In Beispiel sollen alle Flüge je Fluggesellschaft angezeigt werden. Ein Flug kann
hierbei zu verschiedenen Terminen stattfinden. Dies soll in einer dritten Ebene
des Baumes dargestellt werden. Die Buchungen zum jeweiligen Flug können als
Zusatzinformationen für jeden Flug individuell angezeigt werden. Diese Zu-
satzinformationen sind nur an den Knoten der dritten Ebene, den konkreten
Flugereignissen, sinnvoll.
75
3.1 Tree-Views nach der »alten« Methode
Abbildung 3.2
Ausgabe des Beispielprogramms (© SAP AG)
Über den Parameter ROOT_NAME wird der Wurzelknoten benannt. Dieser Name
kann frei gewählt werden und erscheint standardmäßig als Text in der Darstel-
lung des Knotens (siehe unten). Weiterhin kann der Typ des Knotens definiert
werden. Dieser kann selbst vergeben werden und dient später, bei der Verarbei-
tung von Benutzeraktionen, zur Identifikation eines Knotentyps (siehe Ab-
76
schnitt 3.1.3). Daher ist es in der Regel ratsam, jeder Art von Knoten einen
eigenen Typ zuzuweisen.
Wie der Knoten auf dem Bildschirm des Benutzers dargestellt werden soll, wird
dem Funktionsbaustein in Form einer optionalen Struktur übergeben. Diese
Struktur (die wichtigsten Felder dieser Struktur sind in Tabelle 3.1 dargestellt) –
sie ist im Data Dictionary mit dem Namen STREEATTR abgelegt - definiert neben
den allgemeinen Eigenschaften des Knotens (in den Feldern NLENGTH, COLOR und
INTENSIV) zehn Darstellungsbereiche für den Knoten. Jedes dieser Knotenele-
mente wird durch die Attribute TEXT, TLENGHT, TCOLOR, TINTENSIV, TPOS sowie KIND
definiert.
77
3.1 Tree-Views nach der »alten« Methode
Tabelle 3.1
Darstellungsattribute eines Knotens (STREEATTR)
Wird diese Struktur nicht an den Funktionsbaustein übergeben, wird der Kno-
ten mit dem Knotennamen angezeigt. Es wird hierbei eine Default-Farbe und
eine Default-Länge angenommen. Diese kann bei der Anzeige des Baumes glo-
bal festgelegt werden. Wird die STREEATTR-Struktur übergeben, wird der Knoten
auf jeden Fall mit den darin definierten Werten angezeigt. Der Knotenname
dient in diesem Fall nur zur Identifikation des Knotens.
Ist das jeweilige Feld KINDx leer (Space), wird der Inhalt des Feldes TEXT als Be-
zeichnung interpretiert. Bei den Knotentypen »I«, »J« und »K« wird der Inhalt
dieses Feldes als Name der Ikone, bei »S«, »T« sowie »R« als Name des Symbols
ausgelegt. Die Knotentypen »C« und »B« repräsentieren Ankreuzfelder ohne
bzw. mit Text. Im letzteren Fall wird der Inhalt des Feldes TEXT als Beschriftung
des Feldes verwendet.
Über TLENGTH, TCOLOR sowie TINTENSIV kann die Darstellung des Knotenelements
auf dem Bildschirm definiert werden. Zu beachten ist hierbei, dass nicht alle
78
Symbole und Ikonen bei der Darstellung nur ein Zeichen benötigen. Verschie-
dene Elemente sind bis zu 4 Zeichen breit. Genauere Informationen über die
Breite des jeweiligen Symbols oder der jeweiligen Ikone sind im Include <SYM-
BOL> bzw. <ICON> definiert.
Das Feld TPOS kann zur spaltengenauen Platzierung des Knotenelements ver-
wendet werden. Nachfolgende Knotenelemente überschreiben hierbei ggf. vor-
hergehende Knotenelemente, falls eine Überschneidung definiert wurde. Der
Inhalt des Feldes TPOS gibt die Startposition des Textelements vom linken Bild-
schirmrand wieder. Die Hierarchieebene des Knotens spielt hierbei keine Rolle.
Wird das Feld TPOS nicht belegt, werden die Knoten hintereinander angeordnet.
Dieses Vorgehen ist in der Regel günstiger, als das explizite Platzieren von Kno-
tenelementen.
Je nach Anwendungsfall wird eine unterschiedliche Anzahl Knotenelemente
zur Darstellung eines Knotens benötigt. Knotenelemente, deren Längenfeld 0
enthält, werden nicht angezeigt.
Das Ergebnis des Funktionsbausteins RS_TREE_CREATE ist eine ID, mit welcher der
neu erzeugte Wurzelknoten eindeutig angesprochen werden kann. Während
die Namen der Knoten eines Baumes ggf. nicht eindeutig sind (siehe hierzu
Kapitel 3.1.5), ist die ID eines Knotens auf jeden Fall eindeutig.
Die erste Version des Beispielprogramms legt lediglich einen Wurzelknoten an
und zeigt diesen Minimalbaum an.
REPORT ZFLIGHTTREE.
*
* Type-Pools
*
TYPE-POOLS: STREE.
START-OF-SELECTION.
* Erzeuge Wurzelknoten
PERFORM CREATE_TREE CHANGING G_ROOT.
* Zeige Baum an
PERFORM SHOW_TREE.
*&---------------------------------------------------------------------*
*& Form CREATE_TREE
79
3.1 Tree-Views nach der »alten« Methode
*&---------------------------------------------------------------------*
* Erzeugt den Wurzelknoten
*----------------------------------------------------------------------*
* <--P_ROOT ID des Wurzelknotens
*----------------------------------------------------------------------*
FORM CREATE_TREE CHANGING P_ROOT LIKE SNODE-ID.
CALL FUNCTION 'RS_TREE_CREATE'
EXPORTING
ROOT_NAME = 'Flüge'(001)
* ROOT_TYPE =
* DISPLAY_ATTRIBUTES =
IMPORTING
ROOT_ID = P_ROOT.
ENDFORM. " CREATE_TREE
*&---------------------------------------------------------------------*
*& Form SHOW_TREE
*&---------------------------------------------------------------------*
* Zeigt den Baum an
*----------------------------------------------------------------------*
FORM SHOW_TREE.
CALL FUNCTION 'RS_TREE_LIST_DISPLAY'
* EXPORTING
* CALLBACK_PROGRAM =
* CALLBACK_USER_COMMAND =
* CALLBACK_TEXT_DISPLAY =
* CALLBACK_MOREINFO_DISPLAY =
* CALLBACK_COLOR_DISPLAY =
* CALLBACK_TOP_OF_PAGE =
* CALLBACK_GUI_STATUS =
* CALLBACK_CONTEXT_MENU =
* STATUS = 'IMPLICIT'
* CHECK_DUPLICATE_NAME = '1'
* COLOR_OF_NODE = '4'
* COLOR_OF_MARK = '3'
* COLOR_OF_LINK = '1'
* COLOR_OF_MATCH = '5'
* LOWER_CASE_SENSITIVE = ' '
* MODIFICATION_LOG = ' '
* NODE_LENGTH = 30
* TEXT_LENGTH = 75
* TEXT_LENGTH1 = 0
* TEXT_LENGTH2 = 0
* RETURN_MARKED_SUBTREE = ' '
* SCREEN_START_COLUMN = 0
* SCREEN_START_LINE = 0
* SCREEN_END_COLUMN = 0
80
* SCREEN_END_LINE = 0
* SUPPRESS_NODE_OUTPUT = ' '
* LAYOUT_MODE = ' '
* USE_CONTROL = STREE_USE_LIST
* IMPORTING
* F15 =
.
ENDFORM. " SHOW_TREE
Da beim Erzeugen des Wurzelknotens lediglich der Name des Knotens angege-
ben wird, ohne eine Darstellungsstruktur zu definieren, wird der Knoten mit
dem als ROOT_NAME übergebenen String mit den Standard-Attributen angezeigt.
Über den Funktionsbaustein RS_TREE_LIST_DISPLAY wird der zunächst im Spei-
cher definierte Baum auf dem Präsentations-Server (dem GUI des Benutzers)
angezeigt. Dieser Funktionsbaustein definiert eine ganze Reihe von Parametern,
über die das Verhalten und die Darstellung des Baumes beeinflusst werden
können. Die meisten Parameter werden in den folgenden Abschnitten genauer
betrachtet. Ansonsten sei an dieser Stelle auf die Online-Dokumentation zum
Funktionsbaustein RS_TREE_LIST_DISPLAY verwiesen.
81
3.1 Tree-Views nach der »alten« Methode
* Zeige Baum an
PERFORM SHOW_TREE.
...
*&---------------------------------------------------------------------*
*& Form CREATE_TREE_NODES
*&---------------------------------------------------------------------*
* Erzeugt alle Knoten unterhalt des Wurzelknotens
*----------------------------------------------------------------------*
* -->P_ROOT Id des Wurzelknotens
*----------------------------------------------------------------------*
FORM CREATE_TREE_NODES USING P_ROOT LIKE SNODE-ID.
DATA: LT_SCARR LIKE SCARR OCCURS 0 WITH HEADER LINE.
DATA: L_AIRLINE_NODE LIKE SNODE-ID.
* Airlines lesen
SELECT *
INTO TABLE LT_SCARR
FROM SCARR.
LOOP AT LT_SCARR.
* Knoten für Airline anlegen
PERFORM CREATE_AIRLINE_NODE USING LT_SCARR
P_ROOT
CHANGING L_AIRLINE_NODE.
ENDLOOP.
ENDFORM. " CREATE_TREE_NODES
*&---------------------------------------------------------------------*
*& Form CREATE_AIRLINE_NODE
*&---------------------------------------------------------------------*
* Legt einen neuen Knoten an
*----------------------------------------------------------------------*
82
* -->P_SCARR Struktur mit Airline-Information
* -->P_PARENT Knoten-Id des Parentnodes
* <--P_NODE Knoten-Id des neuen Knotens
*----------------------------------------------------------------------*
FORM CREATE_AIRLINE_NODE USING P_SCARR LIKE SCARR
P_PARENT LIKE SNODE-ID
CHANGING P_NODE LIKE SNODE-ID.
CALL FUNCTION 'RS_TREE_ADD_NODE'
EXPORTING
NEW_NAME = P_SCARR-CARRNAME
INSERT_ID = P_PARENT
RELATIONSHIP = STREE_RELTYPE_CHILD
* LINK = ' '
NEW_TYPE = C_NODETYPE-AIRLINE
* DISPLAY_ATTRIBUTES = ' '
IMPORTING
NEW_ID = P_NODE
* NODE_INFO =
EXCEPTIONS
ID_NOT_FOUND = 1
OTHERS = 2.
ENDFORM. " CREATE_AIRLINE_NODE
Im Beispiel wurde die Datenermittlung von der Definition der Darstellung des
Knotens getrennt. Dies empfielt sich, um den Programmcode übersichtlich zu
halten und ggf. an anderer Stelle gleiche Knoten einfügen zu können.
Um Knoten in den Baum einzufügen, wird der Funktionsbaustein
RS_TREE_ADD_NODE verwendet. Der Funktionsbaustein erhält als Parameter den
Namen des Knotens (NEW_NAME), die Id des referenzierten Knotens (INSERT_ID) so-
wie die Beziehung des neuen Knotens zum Bezugsknoten. Im Beispiel wird die
Beziehung STREE_RELTYPE_CHILD angewendet, d.h. der neue Knoten wird als
Unterknoten des referenzierten Knotens angelegt. Da der neue Child-Knoten
immer als erster in die Hierarchie eingetragen wird, ist es notwendig vor
Kapitel 3 – Spezielle Dialogelemente
dem Durchlaufen der LOOP-Schleife in der FORM-Routine CREATE_TREE_NODES die
Sätze in umgekehrter Reihenfolge zu sortieren.
Eine andere Möglichkeit, die Knoten in den Baum einzufügen wäre, den ersten
untergeordneten Knoten mit STREE_RELTYPE_CHILD und dem Parent als Referenz
und die folgenden Knoten mit der Beziehung STREE_RELTYPE_NEXT und dem vor-
hergehenden Knoten als Referenz anzulegen. Allein die Beschreibung zeigt,
dass dieses Verfahren ein wenig aufwendiger ist als einfach die Liste umzusor-
tieren. Wenn möglich wird daher in der Regel die erste Methode verwendet.
Auch in diesem Beispiel werden keine Anzeige-Attribute für den Knoten definiert
(DISPLAY_ATTRIBUTES). Die Darstellung des Knotens beschränkt sich daher auf den
Knotennamen mit den Standard-Attributen. Die erzeugten Knoten erhalten alle den
Knotentyp C_NODETYPE-AIRLINE, welcher am Anfang des Programms als Konstanten-
83
3.1 Tree-Views nach der »alten« Methode
definition angelegt wird. Auch für die in den späteren Abschnitten erzeugten
Knoten, sowie den Wurzelknoten werden Knotentypen definiert, so dass folgende
Definition am Anfang des Programms notwendig wird. Der Aufruf des Funktions-
bausteins RS_TREE_CREATE wird in diesem Schritt ebenfalls entsprechend angepasst,
um den definierten Knotentyp C_NODETYPE-ROOT zu verwenden.
CONSTANTS: BEGIN OF C_NODETYPE,
ROOT LIKE SNODE-TYPE VALUE 'ROOT',
AIRLINE LIKE SNODE-TYPE VALUE 'AIRL',
FLIGHT LIKE SNODE-TYPE VALUE 'PFLI',
FLIGHTEVENT LIKE SNODE-TYPE VALUE 'SFLI',
END OF C_NODETYPE.
In Abschnitt 3.1.3 wird gezeigt, wofür die Definition von Knotentypen für ver-
schiedene Knoten sinnvoll ist und wie sie verwendet werden.
Der Funktionsbaustein RS_TREE_ADD_NODE liefert eine Struktur für den neu
erzeugten Knoten zurück, in der die internen Informationen zum Knoten ent-
halten sind. Der Aufbau dieser Struktur ist im Data Dictionary mit dem Namen
SNODE definiert (siehe Tabelle 3.2).
Tabelle 3.2
Aufbau der Struktur SNODE
Diese Struktur beschreibt sowohl den Knoten (nicht dessen Darstellung) als
auch die Position des Knotens innerhalb des Baumes.
84
Knoten mit Textattributen
In der nächsten Ebene des Baumes soll ein Knoten durch mehrere Felder dar-
gestellt werden. Auch hier wird die Ermittlung der Daten von der Erzeugung
des Knotens getrennt. Die Datenermittlung wird in die FORM-Routine CREATE_
TREE_NODES integriert. Das Programmfragment zeigt die geänderte Version die-
ser FORM-Routine.
FORM CREATE_TREE_NODES USING P_ROOT LIKE SNODE-ID.
DATA: LT_SCARR LIKE SCARR OCCURS 0 WITH HEADER LINE,
LT_SPFLI LIKE SPFLI OCCURS 0 WITH HEADER LINE.
DATA: L_AIRLINE_NODE LIKE SNODE-ID,
L_FLIGHT_NODE LIKE SNODE-ID.
...
LOOP AT LT_SCARR.
...
* Flüge zu Airline lesen
SELECT *
INTO TABLE LT_SPFLI
FROM SPFLI
WHERE CARRID = LT_SCARR-CARRID.
LOOP AT LT_SPFLI.
* Knoten für Flug anlegen
PERFORM CREATE_FLIGHT_NODE USING LT_SPFLI
L_AIRLINE_NODE
CHANGING L_FLIGHT_NODE.
ENDLOOP.
ENDLOOP.
Innerhalb der LOOP-Schleife der Fluggesellschaften werden aus der Tabelle SPFLI
alle Flüge zur Airline ausgelesen, umsortiert (wie oben) und mit der Routine
CREATE_FLIGHT_NODE angezeigt. Die eigentlichen Unterschiede ergeben sich im
Unterprogramm CREATE_FLIGHT_NODE, welches folgenden Aufbau hat:
*&---------------------------------------------------------------------*
*& Form CREATE_FLIGHT_NODE
*&---------------------------------------------------------------------*
* Erstellt einen Knoten für einen Flug
*----------------------------------------------------------------------*
* -->P_SPFLI Datenstruktur des Fluges
* -->P_PARENT ID des Parent-Knotens
* <--P_NODE ID des neu erzeugten Knotens
85
3.1 Tree-Views nach der »alten« Methode
*----------------------------------------------------------------------*
FORM CREATE_FLIGHT_NODE USING P_SPFLI LIKE SPFLI
P_PARENT LIKE SNODE-ID
CHANGING P_NODE LIKE SNODE-ID.
DATA: L_STREEATTR LIKE STREEATTR.
L_STREEATTR-TLENGTH = 4.
L_STREEATTR-TLENGTH1 = 20.
L_STREEATTR-TLENGTH2 = 3.
L_STREEATTR-TLENGTH3 = 20.
L_STREEATTR-TLENGTH4 = 3.
L_STREEATTR-TLENGTH5 = 5.
Zunächst werden über eine Kette von WRITE-Anweisungen die Feldinhalte in die
entsprechenden Felder der Anzeige-Attribute übertragen. Die WRITE-Anweisung
wird verwendet, damit etwaige Konvertierungsexits bei der Ausgabe berück-
sichtigt werden. Im Anschluss daran werden die Längenfelder der einzelnen Be-
reiche gesetzt. Im dargestellten Beispiel werden lediglich 6 der 10 möglichen Be-
reiche genutzt. Da das Längenfeld der übrigen Felder »0« enthält, werden diese
bei der Ausgabe nicht berücksichtigt. Die so erzeugte Struktur wird im anschlie-
ßenden Aufruf von RS_ADD_TREE_NODE im Parameter DISPLAY_ATTRIBUTES an den
Funktionsbaustein übergeben.
86
Erweiterte Möglichkeiten von Knoten
Die Knoten der dritten Ebene, welche die konkreten Flugereignisse zeigen sol-
len, werden mit weiteren Attributen ausgestattet. Bei der Anzeige der freien
Plätze wird eine Farbcodierung eingeführt. Flüge mit weniger als 70% Belegung
werden hierbei grün dargestellt, Flüge mit mehr als 95% Sitzbelegung rot. Da-
zwischen soll die Anzeige der freien Plätze eines Fluges in gelb erfolgen. Analog
zu diesen Grenzwerten soll hinter den Datenspalten eine Ampel mit der glei-
chen Farbcodierung angezeigt werden.
Die angezeigten Informationen werden aus der Tabelle SFLIGHT zum jeweiligen
Flug ermittelt. Hierzu wird erneut die FORM-Routine CREATE_TREE_NODES erweitert.
Die Erzeugung des Knotens selbst wird – wie in den vorigen Programmversio-
nen auch – in eine eigene FORM-Routine CREATE_FLIGHT_EVENT_NODE ausgelagert.
Am Programmanfang wird eine konstante Struktur definiert, in der die Schwell-
werte für die Darstellung bei den freien Plätzen festgelegt wird. Diese Struktur
hat den Aufbau:
CONSTANTS: BEGIN OF C_BELEGUNG,
WARNING TYPE I VALUE 70,
ALERT TYPE I VALUE 95,
END OF C_BELEGUNG.
* Umgekehrt sortieren
87
3.1 Tree-Views nach der »alten« Methode
LOOP AT LT_SFLIGHT.
* Flugknoten anzeigen
PERFORM CREATE_FLIGHT_EVENT_NODE USING LT_SFLIGHT
L_FLIGHT_NODE
CHANGING L_EVENT_NODE.
ENDLOOP.
ENDLOOP.
ENDLOOP.
ENDFORM. " CREATE_TREE_NODES
*&---------------------------------------------------------------------*
*& Form CREATE_FLIGHT_EVENT_NODE
*&---------------------------------------------------------------------*
* Erzeugt einen Knoten für einen Flugevent
*----------------------------------------------------------------------*
* -->P_SFLIGHT Datenstruktur für Flug
* -->P_PARENT Id des Parent-Knotens
* <--P_NODE Id des neuen Knotens
*----------------------------------------------------------------------*
FORM CREATE_FLIGHT_EVENT_NODE USING P_SFLIGHT LIKE SFLIGHT
P_PARENT LIKE SNODE-ID
CHANGING P_NODE LIKE SNODE-ID.
DATA: L_STREEATTR LIKE STREEATTR.
DATA: L_BELEGUNG TYPE F.
L_STREEATTR-TLENGTH = 10.
L_STREEATTR-TLENGTH1 = 15.
L_STREEATTR-TLENGTH2 = 5.
L_STREEATTR-TLENGTH3 = 10.
L_STREEATTR-TLENGTH4 = 10.
L_STREEATTR-TLENGTH5 = 10.
L_STREEATTR-TLENGTH6 = 4.
L_STREEATTR-TCOLOR =
L_STREEATTR-TCOLOR1 =
L_STREEATTR-TCOLOR2 =
L_STREEATTR-TCOLOR3 =
88
L_STREEATTR-TCOLOR4 = 0.
IF P_SFLIGHT-SEATSMAX NE 0.
L_BELEGUNG = ( ( P_SFLIGHT-SEATSOCC / P_SFLIGHT-SEATSMAX ) * 100 ).
ELSE.
L_BELEGUNG = 0.
ENDIF.
* Defaultwerte setzten
L_STREEATTR-TCOLOR5 = 5.
L_STREEATTR-TEXT6 = 'ICON_GREEN_LIGHT'.
89
3.1 Tree-Views nach der »alten« Methode
90
Status sein und lediglich um eigene Funktionen erweitert werden. Nicht benö-
tigte oder unerwünschte Systemfunktionalitäten können aus dem Status ge-
löscht werden oder – besser noch – über die Option EXCLUDING <FCodes> beim
Setzten des Status deaktiviert werden (siehe Beispiel).
Der Wert STANDARD weist den Funktionsbaustein an, auf jeden Fall den System-
status LD_TREE zu setzten. Der Wert IMPLICIT setzt entweder den Standard-Status
oder behält den aktuellen GUI-Status bei. Der Systemstatus wird gesetzt, wenn
mindestens einer der Parameter CALLBACK_PROGRAMM oder CALLBACK_USER_COMMAND
nicht übergeben werden. Sind beide Parameter versorgt, wird der aktuelle GUI-
Status beibehalten.
Seit Release 4 wurde eine weitere Möglichkeit definiert, um den GUI-Status
während der Anzeige zu beeinflussen. Über den Parameter CALLBACK_GUI_STATUS
des Funktionsbausteins RS_TREE_LIST_DISPLAY kann eine FORM-Routine definiert
werden, die vom System vor Anzeige des Baumes aufgerufen wird, um den
GUI-Status zu setzen. Ist dieser Parameter (und der Parameter CALLBACK_PROGRAM)
versorgt, erfolgt keine Auswertung des Parameters STATUS. Die Aufrufschnitt-
stelle dieser FORM-Routine definiert keine Parameter, d.h. es werden weder Para-
meter an die Routine übergeben, noch werden Werte an das aufrufende Pro-
gramm zurückgeliefert.
1. In früheren R/3-Releases wurde das Programm in diesem Fall mit einem Kurzdump
abgebrochen. In neueren Releaseständen wird der Aufruf ignoriert.
91
3.1 Tree-Views nach der »alten« Methode
NEWCHILD CHAR 1 Enthält bei den Funktionscodes TRAD sowie TRMV ein X, falls
der neue Knoten als Kindknoten an den ausgewählten Kno-
ten angehangen werden soll
Tabelle 3.3
Aufbau der Struktur SEUCOMM
92
Funktionscode Bedeutung
TREP Der Teilbaum, auf dem der Cursor steht, wird vollständig expandiert.
Steht der Cursor auf keinem Knoten, wird der gesamte Baum expan-
diert.
TRCM Der Baum wird ab dem Knoten, auf dem der Cursor steht vollständig
komprimiert. Steht der Cursor auf keinem Knoten, wird der gesamte
Baum komprimiert.
TRN+ Der nächste Bruderknoten in der Hierarchie wird um eine Stufe expan-
diert. Der aktuelle Knoten wird komprimiert.
TRN- Der vorige Bruderknoten der Hierarchie wird um eine Stufe expan-
diert. Der aktuelle Knoten wird komprimiert.
TRZM Der Knoten, auf dem der Cursor aktuell steht, wird in der ersten Bild-
schirmzeiel dargestellt. Über der Baumdarstellung wird der Pfad im
Baum bis zum dargestellten Knoten ausgegeben.
TRMK Der aktuelle Knoten und der ggf. darunter liegende Teilbaum werden
markiert bzw. entmarkiert.
TRDL Knoten löschen. Die FORM-Routine muss die Löschung des Knotens
bestätigen, indem das Feld OK der Struktur SEUCOMM auf X gesetzt
wird.
93
3.1 Tree-Views nach der »alten« Methode
Funktionscode Bedeutung
BACK Der Funktionsbaustein wird ohne Aufruf der FORM-Routine für die
Funktionscodeauswertung verlassen.
TREX Beenden (F15). Wird der Parameter <Exit> der Schnittstelle zur Be-
handlung der Funktion auf X gesetzt, wird die Baumdarstellung ver-
lassen und der Rückgabeparameter F15 des Funktionsbausteins
RS_TREE_LIST_DISPLAY auf X gesetzt.
%PC Download
Tabelle 3.4
Funktionscodes im Standard-Status bei Baumdarstellungen
94
Bevor der Baum auf dem Bildschirm ausgegeben wird, wird durch Aufruf der
neuen FORM-Routine SET_PF_STATUS explizit der Benutzerstatus gesetzt. Um zu
verhindern, dass dieser bei der Anzeige des Baums wieder durch den Standard-
Status ersetzt wird, wird der Parameter STATUS mit dem Wert »OWN« belegt. Da im
dargestellten Beispiel auch die Parameter CALLBACK_PROGRAMM, sowie CALLBACK_
USER_COMMAND versorgt wurden, hätte der Parameter STATUS auch mit dem Wert
IMPLICIT belegt werden können.
Das gleiche Ergebnis wie oben dargestellt kann außerdem auch über die Ver-
wendung einer Callback-Routine zum Setzen des GUI-Status realisisert werden.
Da die erwartete FORM-Routine bei Verwendung dieses Verfahrens keine Para-
meterschnittstelle definiert, könnte das gleiche Verhalten wie im obigen Pro-
grammfragment auch durch folgenden Code erreicht werden.
FORM SHOW_TREE.
CALL FUNCTION 'RS_TREE_LIST_DISPLAY'
EXPORTING
CALLBACK_PROGRAM = SY-CPROG
CALLBACK_USER_COMMAND = 'COMMAND_HANDLER'
...
CALLBACK_GUI_STATUS = 'SET_PF_STATUS'
...
ENDFORM.
LT_EX_FCODES-FCODE = STREE_CMD_ADD_TYPE.
APPEND LT_EX_FCODES.
LT_EX_FCODES-FCODE = STREE_CMD_DELETE.
APPEND LT_EX_FCODES.
LT_EX_FCODES-FCODE = STREE_CMD_RENAME.
APPEND LT_EX_FCODES.
LT_EX_FCODES-FCODE = STREE_CMD_MOVE.
APPEND LT_EX_FCODES.
95
3.1 Tree-Views nach der »alten« Methode
Nachdem nun der gewünschte GUI-Status bei der Anzeige verwendet wird,
fehlt lediglich noch die Implementierung der Routine zur Behandlung der
Funktionscodes. Im ersten Schritt genügt es, diese ohne Verarbeitungen im Pro-
gramm einzufügen.
FORM COMMAND_HANDLER TABLES NODES STRUCTURE SEUCOMM
USING COMMAND
CHANGING EXIT
LIST_REFRESH.
ENDFORM.
Analog zum GUI-Status kann mit der Routine SET_PF_STATUS auch der Pro-
grammtitel beeinflusst werden.
Bis hierher wurde gezeigt, wie der verwendete GUI-Status während der Anzei-
ge eines Tree-Views beeinflusst werden kann. Durch die Verwendung einer Ko-
pie des vom System verwendeten GUI-Status LD_TREE des Programms SAPLSEUT
können eigene Funktionscodes definiert werden. System-Funktionscodes kön-
nen entweder durch explizites Ausschließen beim Setzten des GUI-Status (SET
PF-STATUS ... EXCLUDING ...) oder durch Entfernen der unerwünschten Funktio-
nen aus der Kopie des GUI-Status realisiert werden. Die Implementierung der
selbstdefinierten Funktionscodes erfolgt im Abschnitt 3.1.5.
Die Routine liefert im Parameter <Farb-Tab> eine Tabelle der verwendeten Farb-
definitionen zurück Die Struktur SEUCOLOR hat den in Tabelle 3.5 gezeigten Auf-
bau.
96
Feldname Datentyp Bedeutung
Tabelle 3.5
Aufbau der Struktur SEUCOLOR
In den Feldern COLOR und INTENSIV wird der jeweilige Farbwert definiert. Die üb-
rigen Felder dienen der Erklärung der Farbcodierung.
Der Tabellenparameter <Farb-Tab> ist beim Betreten der FORM-Routine mit den,
dem System bekannten, Farbwerten vorbelegt. Diese können in der Routine um
eigene Definition ergänzt werden.
Im Beispiel wird der Aufruf des Funktionsbausteins RS_TREE_LIST_DISPLAY wie
dargestellt erweitert:
CALL FUNCTION 'RS_TREE_LIST_DISPLAY'
EXPORTING
CALLBACK_PROGRAM = SY-CPROG
...
CALLBACK_COLOR_DISPLAY = 'COLOR_DISPLAY'
...
97
3.1 Tree-Views nach der »alten« Methode
Wird in der Anzeige der Funktionscode TRCL ausgewählt, erscheint das in Abbil-
dung 3.3 dargestellte Fenster.
Abbildung 3.3
Legende zum verwendeten Farbschema (© SAP AG)
98
3.1.5 Weitere Gestaltungsmöglichkeiten der Darstellung
* Tabellenparameter löschen
REFRESH P_MOREINFO_TAB.
Kapitel 3 – Spezielle Dialogelemente
* Knotenattribute ermitteln
CALL FUNCTION 'RS_TREE_GET_NODE'
EXPORTING
NODE_ID = P_NODE-ID
IMPORTING
NODE_INFO = L_NODETEXT
EXCEPTIONS
ID_NOT_FOUND = 1
OTHERS = 2.
99
3.1 Tree-Views nach der »alten« Methode
* Information aufbereiten
WRITE: SCUSTOM-NAME TO P_MOREINFO_TAB-TEXT,
SBOOK-CLASS TO P_MOREINFO_TAB-TEXT1.
P_MOREINFO_TAB-TLENGTH = 30.
P_MOREINFO_TAB-TLENGTH1 = 8.
APPEND P_MOREINFO_TAB.
ENDSELECT.
ENDFORM.
Um die Buchungen zum jeweiligen Flug aus der Tabelle SBOOK ermitteln zu kön-
nen, muss der Schlüssel des Fluges bekannt sein. Dieser wurde im HIDE-Bereich
des Knotens abgelegt (siehe Abschnitt 3.1.2). Die FORM-Routine MORE_INFO erhält
jedoch lediglich die Struktur STREENODE zum jeweiligen Knoten. In diesem sind
die benötigten Informationen nicht enthalten. Mit dem Funktionsbaustein
RS_TREE_GET_NODE können jedoch bei bekannter Knoten-ID die übrigen Attribute
(siehe Tabelle 3.6) zum Knoten ermittelt werden. Aus dem HIDE-Bereich des
Knotens wird der Datensatz des zugrunde liegenden Satzes der Tabelle SFLIGHT
rekonstruiert.
Jetzt können aus der Tabelle SBOOK die Buchungen zum Flug gelesen werden.
Über die Kundennummer wird aus der Tabelle SCUSTOM der zur Buchung gehö-
rige Kunde ausgelesen.
Die FORM-Routine MORE_INFO liefert an das rufende Programm eine Tabelle vom
Typ STREEATTR zurück. Innerhalb der beiden SELECT-Statements werden daher die
gewünschten Informationen in die Knontenattribute-Tabelle übertragen. Zur
Demonstration soll hier der Name des Kunden und die gebuchte Klasse genü-
gen.
Textausgaben am Seitenanfang
Analog zum normalen Reporting können auch bei der Darstellung von Bäumen
Informationen am Anfang der Seite ausgegeben werden. Da hier jedoch nicht
mit den Standardereignissen des Reportings gearbeitet werden kann – der Re-
100
portingteil des Programms befindet sich in der Funktionsgruppe SEUT – besteht
die Möglichkeit, eine FORM-Routine zu definieren, die von der Funktionsgruppe
SEUT aufgerufen wird, wenn in dieser das Ereigniss TOP-OF-PAGE eintritt.
Hierzu muss eine FORM-Routine ohne Parameter definiert werden. Der Name
dieser FORM-Routine wird dem Funktionsbaustein RS_TREE_LIST_DISPLAY im Para-
meter CALLBACK_TOP_OF_PAGE zusammen mit dem Programmnamen im Parameter
CALLBACK_PROGRAM übergeben. Die FORM-Routine wird dann während der Darstel-
lung des Baumes und beim Druck am Anfang jeder Seite aufgerufen und kann
beliebige Informationen mit der Anweisung WRITE in die Liste ausgeben.
Die Routine erhält für jeden darzustellenden Knoten einen Eintrag in der Tabel-
le <Node-Tab>. Die mit der WRITE-Anweisung getätigten Listenausgaben dieses
Funktionsbausteins werden vor dem Wurzelknoten auf dem Bildschirm des
Benutzers angezeigt bzw. dem Ausdruck gedruckt.
Die Struktur SNODETEXT (siehe Tabelle 3.6) enthält die vollständigen Informa-
tionen zu jedem Knoten. Dies beinhaltet zum einen die Informationen über die
Position des Knotens in der Baumhierarchie sowie die Darstellungsattribute
des Knotens.
101
3.1 Tree-Views nach der »alten« Methode
...
...
Tabelle 3.6
Aufbau der Struktur SNODETEXT
Die Struktur SNODETEXT wird in den folgenden Kapiteln noch häufiger verwen-
det. Sie wird generell verwendet, um Informationen über Knoten zu ermitteln
bzw. zu setzten.
102
CALL FUNCTION 'RS_TREE_ADD_NODE'
EXPORTING
NEW_NAME = P_SFLIGHT-FLDATE
INSERT_ID = P_PARENT
RELATIONSHIP = STREE_RELTYPE_CHILD
LINK = 'X'
NEW_TYPE = C_NODETYPE-FLIGHTEVENT
DISPLAY_ATTRIBUTES = L_STREEATTR
IMPORTING
NEW_ID = P_NODE
NODE_INFO =
EXCEPTIONS
ID_NOT_FOUND = 1
OTHERS = 2.
103
3.1 Tree-Views nach der »alten« Methode
Sämtliche Möglichkeiten, die bei der Baumdarstellung als gesamtes Fenster zur
Verfügung standen bleiben, bestehen. Die Baumdarstellung kann somit auch als
Auswahldialog verwendet werden. Hierzu muss dann allerdings ein Funk-
tionscode definiert werden, der das Fenster ordnungsgemäß schließt und die
aktuelle Selektion an das übergeordnete Programm weitergibt.
104
Abbildung 3.4
Baumdarstellung als modaler Dialog (© SAP AG)
105
3.1 Tree-Views nach der »alten« Methode
CASE P_COMMAND.
WHEN C_CMD-MORE_INFO.
LOOP AT P_NODES.
* Nur konkrete Flüge
CHECK P_NODES-TYPE EQ C_NODE_TYPE-FLIGHTEVENT.
* Knoten ermitteln
CALL FUNCTION 'RS_TREE_GET_NODE'
EXPORTING
NODE_ID = P_NODES-ID
IMPORTING
NODE_INFO = L_NODETEXT
EXCEPTIONS
ID_NOT_FOUND = 1
OTHERS = 2.
* More-Info-Flag aktualisieren
IF L_NODETEXT-MOREINFO EQ SPACE.
L_NODETEXT-MOREINFO = 'X'.
ELSE.
CLEAR L_NODETEXT-MOREINFO.
ENDIF.
106
* Knoten aktualisieren
CALL FUNCTION 'RS_TREE_SET_NODE'
EXPORTING
NODEINFO = L_NODETEXT
EXCEPTIONS
ID_NOT_FOUND = 1
OTHERS = 2.
ENDLOOP.
ENDCASE.
ENDFORM.
Knoten/Teilbäume löschen
Für die Realisierung des Funktionscodes DELE zum Löschen von Knoten bzw.
Teilbäumen muss in der im vorigen Abschnitt dargestellten FORM-Routine eine
weitere WHEN-Klausel implementiert werden. Für das Löschen von Knoten/Teil-
bäume aus einem Baum steht der Funktionsbaustein RS_TREE_DELETE_NODE zur
Verfügung. Der Funktionsbaustein löscht den Teilbaum unterhalb des gegebe-
nen Knotens und – auf Wunsch – auch den Knoten selbst. Der Ausgangsknoten
wird hierbei im Parameter NODE_ID übergeben. Über das Flag WITHOUT_ROOT kann
gesteuert werden, ob der Ausgangsknoten ebenfalls gelöscht wird (Space), oder
nur der darunter liegende Teilbaum (»X«).
Auch in diesem Beispiel besteht die Implementierung aus einer LOOP-Schleife
über die selektierten Knoten mit einem Aufruf des genannten Funktionsbau-
steins.
FORM COMMAND_HANDLER TABLES P_NODES STRUCTURE SEUCOMM
USING P_COMMAND
CHANGING P_EXIT
P_LIST_REFRESH.
DATA: L_NODETEXT LIKE SNODETEXT,
CASE P_COMMAND.
...
WHEN C_CMD-DELETE.
LOOP AT P_NODES.
IF P_NODES-TYPE EQ C_NODE_TYPE-ROOT.
L_ROOT = 'X'.
ELSE.
L_ROOT = SPACE.
ENDIF.
107
3.1 Tree-Views nach der »alten« Methode
NODE_ID = P_NODES-ID
WITHOUT_ROOT = L_ROOT
EXCEPTIONS
ID_NOT_FOUND = 1
OTHERS = 2.
ENDLOOP.
...
ENDCASE.
ENDFORM.
Teilbäume anzeigen/verstecken
Bleibt zuletzt noch die Realisierung der Funktionscodes EXPA sowie COMP. Mit
EXPA soll der Teilbaum unterhalb des selektierten Knotens um eine Ebene ausge-
klappt werden. Mit COMP soll der Teilbaum unterhalb des aktuellen Knotens voll-
ständig versteckt werden. Hierfür stehen die Funktionsbausteine RS_TREE_EXPAND
sowie RS_TREE_COMPRESS zur Verfügung. Die Implementierung erfolgt abermals
in Form von WHEN-Klauseln innerhalb der Routine COMMAND_HANDLER.
FORM COMMAND_HANDLER TABLES P_NODES STRUCTURE SEUCOMM
USING P_COMMAND
CHANGING P_EXIT
P_LIST_REFRESH.
...
CASE P_COMMAND.
...
WHEN C_CMD-EXPAND.
LOOP AT P_NODES.
CALL FUNCTION 'RS_TREE_EXPAND'
EXPORTING
NODE_ID = P_NODES-ID
* ALL = ' '
* LIST_SCROLL =
* DEPTH = 1
EXCEPTIONS
NOT_FOUND = 1
OTHERS = 2.
ENDLOOP.
108
WHEN C_CMD-COMPRESS.
LOOP AT P_NODES.
CALL FUNCTION 'RS_TREE_COMPRESS'
EXPORTING
NODE_ID = P_NODES-ID
EXCEPTIONS
NOT_FOUND = 1
OTHERS = 2.
ENDLOOP.
ENDCASE.
ENDFORM.
109
3.1 Tree-Views nach der »alten« Methode
Neben dem Knoten, für den das Menü angezeigt werden soll, bekommt diese
Routine als Parameter eine Referenz auf eine Instanz eines ABAP-Objekts vom
Typ CL_CTMENU übergeben. Die Aufgabe dieser Routine besteht darin, in diesem
Menü die gewünschten Menüeinträge anzulegen. Das so erzeugte Menü kann
neben normalen Menüeinträgen auch Untermenüs sowie horizontale Trennlini-
en enthalten. Einzelne Einträge des Menüs können deaktiviert werden, falls der
Menüpunkt im jeweiligen Kontext nicht möglich ist. Für diese Aufgaben stellt
die Klasse CL_CTMENU die Methoden ADD_FUNCTION, ADD_SEPARATOR sowie ADD_SUBMENU
zur Verfügung. Diese und die übrigen, hier nicht genannten Methoden der Klas-
se, geben dem Programmierer weitreichende Gestaltungsmöglichkeiten für
Kontextmenüs an die Hand.
Die hier beschriebene Funktionalität setzt voraus, dass die Funktionstaste (ª) +
(F10), welche für die Anzeige von Kontext-Menüs reserviert ist, im aktuellen
GUI-Status belegt ist. Wird der Standard-Status verwendet, ist dies der Fall, an-
dernfalls muss der Programmierer hierfür Sorge tragen.
110
boten werden, d.h. für alle Knoten soll die Möglichkeit bestehen, die darunter
liegende Ebene - sofern vorhanden - auszuklappen sowie die Knoten mit ihren
darunter liegenden Teilbäumen zu löschen. Für die Knoten der dritten Ebene
soll weiterhin die Möglichkeit bestehen, zusätzliche Informationen anzuzeigen
bzw. die Anzeige dieser Informationen zu unterdrücken.
Hierzu wird die FORM-Routine CONTEXT_MENU mit der oben dargestellten Schnitt-
stelle definiert.
FORM CONTEXT_MENU USING P_NODE LIKE SNODETEXT
P_MENU TYPE REF TO CL_CTMENU.
DATA: L_CUA_ACTIVE TYPE C.
* Knoten/Teilbaum löschen
CALL METHOD P_MENU->ADD_FUNCTION
EXPORTNG
FCODE = C_CMD-DELETE
TEXT = 'Löschen'.
* More-Info!
IF P_NODE-TYPE EQ C_NODETYPE-FLIGHTEVENT.
CALL METHOD P_MENU->ADD_FUNCTION
EXPORTING
FCODE = C_CMD_MORE_INFO
TEXT = 'Buchungen'
111
3.1 Tree-Views nach der »alten« Methode
CHECKED = P_NODE-MOREINFO.
ENDIF.
ENDFORM.
In dieser Routine wird zunächst ein Eintrag zum Aufklappen bzw. Komprimie-
ren des Knotens angelegt, soweit es sich bei dem Knoten nicht um ein Blatt (oh-
ne Unterknoten) handelt. Je nachdem, ob der unter dem gewählten Knoten lie-
gende Teilbaum bereits angezeigt wird oder nicht, wird der jeweils passende
Menüeintrag aktiviert bzw. deaktiviert dargestellt. Hierzu wird der Parameter
DISABLED der Methode ADD_FUNCTION verwendet.
Im zweiten Schritt wird ein Menüeintrag zum Löschen des Knotens bzw. Teil-
baums angelegt. Daran folgt für Knoten, die konkrete Flüge repräsentieren, ein
Eintrag, um weitere Informationen zum Flug (in diesem Fall die Buchungen) an-
zuzeigen. Dieser Menüeintrag ist je nach Inhalt des Feldes MOREINFO der Kno-
tenattribute markiert bzw. nicht markiert.
Die Auswertung der Funktionscodes erfolgt wie bei den Funktionscodes des
GUI-Status in der im Parameter CALLBACK_COMMAND an den Funktionsbaustein
RS_TREE_LIST_DISPLAY definierten FORM-Routine (siehe Abschnitt 3.1.3 bzw. Ab-
schnitt 3.1.6), im Beispiel der Routine COMMAND_HANDLER.
Untermenüs erzeugen
Wie bereits erwähnt, besteht bei Kontextmenüs die Möglichkeit, weitere Menü-
ebenen einzufügen. Hierzu wird die Methode ADD_SUBMENU der Klasse CL_CTMENU,
deren Schnittstelle wie dargestellt definiert ist, verwendet.
METHOD ADD_SUBMENU
IMPORTING
MENU
TEXT
112
ICON
DISABLED
HIDDEN
ACCELERATOR
Im Gegensatz zur Methode ADD_FUNCTION wird hier als erster Parameter eine Re-
ferenz auf eine Instanz der Klasse CL_CTMENU, d.h. ein anderes Kontextmenü, er-
wartet. Ansonsten gleichen sich die Schnittstellen der beiden Methoden bis auf
die Tatsache, dass der Parameter CHECKED bei Untermenüs keinen Sinn macht
und daher nicht definiert ist.
Zu bemerken ist hierbei, dass die Instanz des Untermenüs bei Aufruf der Me-
thode ADD_SUBMENU bereits existieren muss. Dies bedeutet, dass die Unterme-
nüstrukturen in Kontextmenüs nicht Top-Down (d.h. von oben nach unten),
sondern Bottom-Up (d.h. von der tiefsten Menüebene nach oben) angelegt wer-
den. Zum Zeitpunkt des Aufrufs muss jedoch lediglich die Instanz des Unter-
menüs selbst existieren. Die Menüeinträge in den Instanzen können hingegen
auch zu einem späteren Zeitpunkt angelegt werden.
RS_TREE_ADD_NODE
Mit der Funktion RS_TREE_ADD_NODE wird zum aktuellen Baum ein Knoten hinzu-
gefügt.
Import-Parameter
INSERT_ID ID des Knotens, zu dem der neue Knoten angelegt werden soll
Export-Parameter
Exceptions
113
3.1 Tree-Views nach der »alten« Methode
RS_TREE_COMPRESS
Verbergen der Unterknotenstrukturen zu einem Knoten.
Import-Parameter
Exceptions
RS_TREE_CONSTRUCT
Erzeugen von Knoten aus einer Tabelle von Knotenelementen. Wird keine
INSERT_ID übergeben, wird ein neuer Baum erzeugt, ansonsten werden die Kno-
ten aus der Tabelle NODETAB in den bestehenden Baum eingefügt.
Import-Parameter
RELATIONSHIP Beziehung, mit der die neuen Knoten angelegt werden sollen
Tabellen
Exceptions
RS_TREE_CREATE
Erzeugen eines neuen, leeren Baumes.
Import-Parameter
Export-Parameter
114
RS_TREE_DELETE_NODE
Löschen eines Knotens mit allen darunter liegenden Unterknoten.
Import-Parameter
Exceptions
RS_TREE_EXPAND
Ausklappen der Unterknoten eines gegebenen Knotens. Die darzustellende Tie-
fe der Unterstrukturen kann über Parameter gesteuert werden.
Import-Parameter
115
3.1 Tree-Views nach der »alten« Methode
RS_TREE_GET_NODE
Ermitteln der Knotenattribute zu einer Knoten-ID.
Import-Parameter
Export-Parameter
Exceptions
RS_TREE_LIST
Rückgabe der Knoten eines Baumes in Form einer internen Tabelle. Diese kann
erneut zur Erzeugung eines Baumes mit der Funktion RS_TREE_CONSTRUCT ver-
wendet werden.
Import-Parameter
Tabellen
Exceptions
116
RS_TREE_LIST_DISPLAY
Anzeige des aktuellen Baumes.
Import-Parameter
117
3.1 Tree-Views nach der »alten« Methode
118
USE_CONTROL
Export-Paramter
RS_TREE_POP
Laden des aktuellen Baumes vom Stack. Über die Funktion RS_TREE_PUSH kann
ein kompletter Baum auf einem Stack abgelegt werden. Die Funktion
RS_TREE_POP lädt diesen wieder vom Stack herunter und macht den geladenen
Baum zum aktiven Baum.
Exceptions
EMPTY_STACK Stack ist leer. Es wurde kein Baum auf dem Stack abgelegt.
RS_TREE_PUSH
Speichert den aktuellen Baum auf dem Stack.
Der Funktionsbaustein definiert keine Schnittstelle, d.h. weder Import- noch Ex-
port-Parameter. Auch Exceptions sind nicht definiert, d.h. der Funktionsbau-
stein liefert in keinem Fall ein Ergebnis.
RS_TREE_SET_NODE
Aktualisiert die Knotenattribute eines Knotens.
Import-Parameter
Exceptions
3.2 Tab-Strips
Seit dem Releasestand 4.0 besteht die Möglichkeit, bei der Programmierung von
Oberflächen in R/3-Systemen so genannte Tab-Strips zu verwenden. Dieses
Control, welches sich seit einigen Jahren in den grafischen Benutzeroberflächen
der Betriebssysteme bewährt hat, wird verwendet, um Informationen, die den
119
3.2 Tab-Strips
Rahmen einer Maske sprengen würden, jedoch inhaltlich strukturiert sind, dar-
zustellen. Anders als bisher, wo in solchen Fällen mehrere Masken, die über
nicht standardisierte Wege hintereinandergeschaltet werden mussten, bieten
Tab-Strips hier eine elegante und einheitliche Art der Darstellung. Bei der Pro-
grammierung von Tab-Strips wird ein Bereich auf der Maske definiert, in dem
die unterschiedlichen Teilbereiche (oder Sichten) auf eine Informationsmenge
angezeigt werden sollen. Diese Teilbereiche werden benannt. Dieser Name wird
oberhalb des Anzeigebereiches auf einer Schaltflächen (auch Reiter genannt) an-
gezeigt. Der Benutzer kann über diese Schaltflächen zwischen den einzelnen
Seiten umschalten. Das Control versucht über optische Mittel eine Stapelung
der einzelnen Reiter anzudeuten. Die aktuell dargestellte Seite wird dabei als
die vorne liegende Karte dargestellt. Technisch gesehen bildet ein Tab-Strip eine
Reihe von hintereinander angeordneten Subscreens. Jeder dieser Subscreens ist
mit einer darüberliegenen Schaltfläche verbunden, über die der Benutzer zwi-
schen den Ansichten wechseln kann. Abbildung 3.5 zeigt exemplarisch die Dar-
stellung eines Tab-Strips. Es handelt sich hierbei um einen Screen-Shot des in
diesem Abschnitt erstellten Beispielprogramms.
Abbildung 3.5
Beispiel für die Darstellung von Tab-Strips im R/3 (© SAP AG)
Über die Reiter kann der Benutzer die aktuell anzuzeigende Seite auswählen.
Falls die Fensterbreite nicht ausreicht, um die Reiter für alle Tab-Seiten darzu-
stellen, zeigt R/3 am rechten Rand der Reiterleiste Schaltflächen zum Blättern
innerhalb der Reiter an.
120
Es ist sehr wichtig, hervorzuheben, wann diese Art der Darstellung gewählt
werden kann. Da der Benutzer die Seiten des Tab-Strips in beliebiger Reihenfol-
ge anspringen kann, können so keine Seitenfolgen dargestellt werden, die auf-
einander aufbauend eine feste Reihenfolge der Darstellung erzwingen. Wäh-
rend sich Tab-Strips zum Beispiel für die Darstellung der verschiedenen Sichten
des Materialstamms, die voneinander jeweils unabhängig sind, sehr gut eignen,
ist deren Verwendung z.B. bei der Auftragseröffnung, wo aufeinander aufbau-
ende Informationen erfasst werden sollen, nicht sinnvoll. Ein weitere Eigen-
schaft von Tab-Strips, die Einfluss auf die Benutzbarkeit des Controls nehmen
können, besteht darin, dass alle Tab-Seiten den gleichen GUI-Status verwenden
müssen. Bei der Programmierung von Sequenzen voneinander unabhängiger
Bildschirme besteht diese Einschränkung nicht, es kann auf jedem Dynpro neu
festgelegt werden, welcher GUI-Status und Titel verwendet werden soll.
Das Konzept von R/3 bietet bei der Verwendung von Tab-Strips zwei Möglich-
keiten an, die den Wechsel der aktuell angezeigten Seite betreffen. Die eine
Möglichkeit besteht darin, den Tab-Wechsel ausschließlich im SAPGUI des Be-
nutzers vorzunehmen. Bei dieser Lösung müssen vor der Anzeige des Dynpros
die Informationen für alle Tab-Seiten – auch die verdeckten – vom Applikations-
server übertragen werden. Wechseln zwischen den Seiten bedeutet hier, dass
sich lediglich die Anzeige im SAPGUI des Benutzers verändert. Ein Wechsel der
aktuellen Seite löst nicht das Ereignis PAI aus, es besteht demnach keine Mög-
lichkeit, auf den Programmablauf Einfluss zu nehmen. Der andere von SAP an-
gebotene Lösungsweg sieht das Blättern auf dem Applikationsserver vor. Bei
dieser Lösung wird bei betätigen der Reiter das Ereignis PAI ausgelöst. In der
Ablauflogik des Dynpros muss das Blättern, als Reaktion auf den dem Reiter zu-
geordneten Funktionscode, programmgesteuert erfolgen (siehe Abschnitt 3.2.3).
Die Vorteile der letzt genannten Methode liegen auf der Hand. Beim Wechsel
der aktuellen Tab-Seite wird die vollständige Ablauflogik sowohl der darge-
stellten Seite als auch des Träger-Dynpros abgearbeitet. Plausibilisierungen und
Ableitungen von Feldwerten sind hierbei leicht möglich. Nachteilhaft wirkt sich
121
3.2 Tab-Strips
Abbildung 3.6
Träger-Dynpro mit Tab-Strip anlegen (© SAP AG)
122
Mit einem Doppelclick auf den Tab-Strip-Bereich können die Eigenschaften des
Tab-Strips angezeigt werden. Hier muss der Name des Controls definiert wer-
den. Im Beispiel wird der Name FLIGHTSTAB verwendet. Weiterhin kann hier die
Größe des Tab-Strips auf dem Dynpro sowie die Anzahl der Tab-Seiten festge-
legt werden. Das Tab-Strip im Beispiel soll den gesamten nutzbaren Bereich des
Dynpros einnehmen (siehe Abbildung 3.6).
Abbildung 3.7
Anlegen der Subscreens (© SAP AG)
123
3.2 Tab-Strips
eingefügt werden.
PROGNR Name des Modulpools, in dem das Dynpro, auf dem das
Tab-Strip liegt, definiert ist
Tabelle 3.7
Aufbau des Datenfeldes welches durch CONTROLS ... TYPE TABSTRIP angelegt wird.
Über diese Struktur kann zur Laufzeit Einfluss auf den Tab-Strip genommen
werden. Das wichigste Feld hierbei ist das Feld ACTIVETAB, welches den Funkti-
onscode des aktuellen Tab-Reiters enthält. Durch Setzten dieses Feldes wird der
Dynpro-Prozessor angewiesen, bei der nächsten Darstellung des Tab-Controlls,
die gewünschte Seite zuoberst darzustellen (siehe auch Abschnitt 3.2.3).
124
3.2.2 Tab-Strips mit Blätterfunktion im SAPGUI
Aktionen im Dynpro-Editor
Nachdem nun sowohl das Träger-Dynpro mit dem Tab-Strip als auch die ein-
zelnen Subscreens des Controls angelegt wurden, kann nun begonnen werden,
die Blätterfunktionalität zu implementieren.
Technisch gesehen ist das Blättern im SAPGUI realisiert, indem eine Reihe von
Subscreens übereinander auf dem Dynpro angeordnet werden. Für jede Tab-
Seite wird auf der jeweiligen Tab-Seite ein eigener Subscreen-Bereich im Dyn-
pro-Editor angelegt und benannt. Bei diesem Verfahren handelt es sich dem-
nach um eine Technik, um Subscreens, die bisher überlappungsfrei auf dem
Dynpro angeordnet sein mussten, quasi zu stapeln und übereinander auszuge-
ben, wobei aber immer alle Subscreenbereiche vorhanden sind.
Abbildung 3.8
Anlegen eines Subscreens auf der Tab-Seite (© SAP AG)
125
3.2 Tab-Strips
des Benutzers müssen diese Funktionscodes den Typ »P« (lokale Funktion des
SAPGUI) haben. Hierdurch wird festgelegt, dass beim Betätigen des Tab-Reiters
kein PAI-Ereignis ausgelöst wird, sondern die Funktion lokal vom GUI des Be-
nutzers verarbeitet wird.
Damit sind die Aufgaben, die im Dynpro-Editor durchgeführt werden müssen,
um die Blätterfunktion im SAPGUI zu realisieren, abgeschlossen. Es handelte
sich um
A Anlegen eines Subscreen-Bereiches auf jeder Tab-Seite.
B Definition der Funktionscodes der Tab-Reiter mit Typ P.
Ablauflogik beim Blättern im SAPGUI
Da beim Blättern im SAPGUI auf jeder Tab-Seite ein eigener Subscreen-Bereich
existiert, muss in der Ablauflogik auch jeder der definierten Subscreen-Bereiche
gesondert behandelt werden. Da im Beispiel die Zuordnung der Subscreens zu
den Subscreen-Bereichen statisch ist, beschränkt sich die Implementierung der
Ablauflogik des Dynpros 9000 auf die notwendigen CALL SUBSCREEN-Anweisun-
gen.
PROCESS BEFORE OUTPUT.
...
CALL SUBSCREEN TAB1 INCLUDING 'SAPMZFLIGHT' '9100'.
CALL SUBSCREEN TAB2 INCLUDING 'SAPMZFLIGHT' '9200'.
CALL SUBSCREEN TAB3 INCLUDING 'SAPMZFLIGHT' '9300'.
...
PROCESS AFTER INPUT.
...
CALL SUBSCREEN TAB1.
CALL SUBSCREEN TAB2.
CALL SUBSCREEN TAB3.
...
Hiermit ist das Tab-Strip vollständig realisiert. Wird jetzt noch ein Transaktions-
code erzeugt, der das Träger-Dynpro als Start-Screen hat, kann über diesen das
Träger-Dynpro mit den drei Tab-Seiten angezeigt werden. Das die Blätterfunk-
tion beim Wechsel der Tab-Seiten lokal ohne Zuhilfenahme des Applikations-
servers erfolgt, kann daran erkannt werden, dass im Fall des Tab-Wechsels kei-
ne Kommunikation mit dem Server erfolgt.
126
ner Subscreen-Bereich angelegt wird, erfolgt das Blättern im zweiten Fall durch
das Austauschen des Inhalts eines einzigen Subscreen-Bereiches, der über alle
Tab-Seiten identisch ist. Über die Tab-Reiter wird demnach nicht die Sichtbar-
keit der einzelnen Seiten gesteuert, sondern tatsächlich ein Wechsel des Inhaltes
des Subscreen-Bereiches vollzogen.
Realisierung im Dynpro-Editor
Die Aufgabe im Dynpro-Editor ist es, einen einzigen Subscreen-Bereich für alle
Tab-Seiten anzulegen. Hierzu werden, die (ª)-Taste gedrückt haltend, nachein-
ander alle Tab-Reiter angewählt und somit alle Seiten gleichzeitig selektiert (sie-
he Abbildung 3.9).
Abbildung 3.9
Selektieren aller Tab-Seiten für die Blätterfunktion auf dem Server (© SAP AG)
Im Anschluss daran wird auf dem Tab-Bereich ein einziger Subscreen angelegt,
der sich somit über alle Tab-Seiten erstreckt.
Schließlich muss – wie beim Blättern im SAPGUI – jedem Tab-Reiter ein Funk-
tionscode zugewiesen werden mit dem Unterschied, dass der Funktionstyp in
diesem Fall nicht »P« sein darf, sondern in der Regel leer, d.h. eine Standard-
Funktion, ist.
127
3.2 Tab-Strips
Die Variablen werden jeweils mit einem Initialwert versehen, damit auch beim
ersten Anzeigen des Dynpros ein korrekter Subscreen referenziert wird.
In der Ablauflogik des Träger-Dynpros werden diese beiden Variablen zur De-
finition des aktuellen Inhalts des Subscreens verwendet.
PROCESS BEFORE OUTPUT.
...
CALL SUBSCREEN TABSEITE INCLUDING G_PROGRAM G_DYNNR.
...
PROCESS AFTER INPUT.
...
CALL SUBSCREEN TABSEITE.
MODULE COMMAND_HANDLER.
...
Da das Blättern in diesem Fall auf dem Applikations-Server erfolgen soll, muss
außerdem in der Ablauflogik ein MODULE definiert werden, in dem die Funktions-
codes ausgewertet werden. Im dargestellten Quelltext erfolgt dies im MODULE
COMMAND_HANDLER.
Die Implementierung dieses Moduls muss – was die Funktionscodes des Tab-
Strips betrifft – die globalen Variablen korrekt setzen. Weiterhin muss in der
Datenstruktur des Tab-Strips die aktive Tab-Seite gesetzt werden, um die Tab-
Reiterleiste korrekt anzuzeigen. Im Gegensatz zum Blättern im SAPGUI des
Benutzers, wird beim Blättern auf dem Applikations-Server hierdurch der Tab-
Reiter definiert, der als aktiv dargestellt wird. Beim Blättern im SAPGUI entfällt
diese Kontrollmöglichkeit, da beim Blättern kein ABAP-Code ausgeführt wird.
Hier kann lediglich der bei der Anzeige zunächst aktive Tab-Reiter definiert und
der zuletzt aktive Tab-Reiter ausgelesen werden.
MODULE COMMAND_HANDLER
CASE OKCODE.
WHEN 'TAB1'.
G_PROGRAM = SY-CPROG.
128
G_DYNNR = 9100.
FLIGHTSTAB-ACTIVETAB = 'TAB1'.
WHEN 'TAB2'.
G_PROGRAM = SY-CPROG.
G_DYNNR = 9200.
FLIGHTSTAB-ACTIVETAB = 'TAB2'.
WHEN 'TAB3'.
G_PROGRAM = SY-CPROG.
G_DYNNR = 9300.
FLIGHTSTAB-ACTIVETAB = 'TAB3'.
ENDCASE.
CLEAR OKCODE.
ENDMODULE.
129
3.3 Nochmal Bäume: Die »neue« Baumdarstellung
men. Der hier erstellte Baum wird auf einem der Subscreens 9200 des Tab-Strips
angelegt. Abbildung 3.5 zeigt das in diesem Abschnitt erstellte Beispiel.
Abbildung 3.10
Baumdarstellung auf einer Seite eines Tab-Strips (© SAP AG)
130
züglich der Verwendung aus einem Web-Browser heraus optimiert. Mit Release
4.6C sollen ca. 98% der SAP-Transaktionen über Web-Browser und den Inter-
net-Transaction-Server aufrufbar sein. Optisch präsentieren sich die Masken da-
bei identisch mit denen im SAPGUI.
Aber auch inhaltlich beschritt SAP in diesem Zusammenhang neue Wege. Neu
eingeführt wurden Controls, die auf etablierten Komponenten-Modellen im
Frontend-Bereich basieren. Zum Zuge kommen hier die ActiveX-Technologie
von Microsoft auf den Windows-Plattformen sowie Suns JavaBeans-Technolo-
gie auf den übrigen Frontend-Plattformen. Diese werden in die herkömmliche
ABAP-Programmierumgebung durch so genannte Custom Controls, die im
Dynpro-Editor als Bereiche auf der Maske angelegt werden, integriert. Mit die-
sen Bereichen werden im ABAP-Code Instanzen des »Control Frameworks«
verknüpft.
Die Programmierung erfolgt herbei mehrstufig. Im ersten Schritt wird der Cus-
tom Control-Bereich auf dem Dynpro durch eine Instanz einer so genannten
Container-Klasse verwaltet. Wie der Name bereits ausdrückt, wird der Bereich
dadurch zu einem Behälter, in dem ein oder mehrere Elemente des Control
Frameworks eingefügt werden können. Der Container ist dabei für die Anord-
nung der in ihm enthaltenen Controls verantwortlich. Programmtechnisch han-
delt ses sich hierbei um eine Unterklasse der ABAP-Klasse CL_GUI_CONTAINER. In
diesen Container können – je nach Containertyp – wiederum ein oder mehrere
Controls, bei denen es sich auch um Container handeln kann, eingefügt werden.
In der Regel wird es sich hierbei jedoch um Instanzen der grafischen Controls
handeln.
Mit dem Stand von Release 4.6 existieren derartige Komponenten für:
◗ SAP Trees
◗ SAP TextEdit
◗ SAP Picture
131
3.3 Nochmal Bäume: Die »neue« Baumdarstellung
Die Programmierung mit dem Control Frameset von SAP basiert daher immer
auf den Schritten:
A Anlegen eines Custom Control-Bereiches auf dem Dynpro.
B Erzeugen eines Containers zur Verwaltung des Custom Controls.
C Füllen des Containers mit grafischen Controls (z.B. Tree).
In diesem Kapitel sollen die grundlegenden Techniken der Programmierung
mit dem Control Framework anhand des SAP Trees dargestellt werden. Im Ka-
pitel 4 dieses Buches wird auch vom SAP TextEdit Gebrauch gemacht. Kapitel
5 schließlich verwendet das mit Release 4.6 ebenfalls neue »graphical Frame-
work«, welches ebenfalls die hier vorgestellten Containern verwendet. Allen
Controls gemeinsam sind die Schritte 1 und 2. Erst im dritten Schritt wird fest-
gelegt, welches Control im Container verwendet wird.
Die Möglichkeiten des zugrunde liegenden Control Frameworks von SAP sind
wesentlich umfangreicher als das, was im Rahmen dieses Buches dargestellt
werden kann. Die Beschreibungen beschränken sich daher auf das für die ver-
wendeten Beispiele Nötige. Eine vollständige und detaillierte Darstellung der
Möglichkeiten des Control Frameworks im Buch »Control Technology«, wel-
ches bei SAP erschienen ist, nachgelesen werden. Dort werden auch die Con-
trols beschrieben, auf die in diesem Buch nicht näher eingegangen werden kann.
132
Abbildung 3.11
Grafischer Dynpro-Editor mit Custom-Control-Bereich (© SAP AG)
3.3.3 Container
Im ABAP-Programm wird der im Dynpro-Editor angelegte Bereich auf der
Maske von einem so genannten Container verwaltet. Container sind spezielle
Klassen im R/3-System, deren Aufgabe ausschließlich darin liegt, derartige
Bildschirmbereiche zu verwalten. Sämtliche Controls, die im System verwendet
Kapitel 3 – Spezielle Dialogelemente
werden können, müssen über Container verwaltet werden. Da Container selbst
auch Controls sind, ist es auch möglich, Container in Container einzufügen und
somit den Custom-Bereich abermals logisch zu unterteilen.
R/3 unterscheidet hierbei fünf verschiedene Typen von Containern, die
jeweils durch eigene ABAP-Klassen repräsentiert werden. Die Klasse
CL_GUI_CUSTOM_CONTAINER, welche im Folgenden Beispiel verwendet wird, ver-
waltet einen Custom-Control-Bereich auf einem Dynpro. Beim Container-Typ
CL_GUI_DIALOGBOX_CONTAINER hingegen entfällt diese Beziehung, da der Container
immer als eigenes amodales Dialogfenster angezeigt wird. Ebenfalls ohne Be-
zug zu einem Custom-Control-Bereich auf einem Dynpro existiert die Klasse
CL_GUI_DOCKING_CONTAINER, welche entweder an einem der vier Ränder des Dyn-
pro-Fensters oder als frei schwebende Dialogbox über dem Dynpro existieren
kann. Dieser Container hat immer Bezug zu einem R/3-Fenster, ohne jedoch Be-
133
3.3 Nochmal Bäume: Die »neue« Baumdarstellung
MODULE CREATE_CONTAINER.
IF G_CONTAINER IS INITIAL.
CREATE OBJECT G_CONTAINER
EXPORTING
CONTAINER_NAME = 'TREEAREA'
EXCEPTIONS
CNTL_ERROR = 1
CNTL_SYSTEM_ERROR = 2
CREATE_ERROR = 3
LIFETIME_ERROR = 4
LIFETIME_DYNPRO_DYNPRO_LINK = 5.
ENDIF.
ENDMODULE.
Beim Erzeugen der Instanz wird diese auch gleichzeitig mit dem Custom Con-
trol »TREEAREA« verknüpft. Auf ein Abfragen und Auswerten des Fehlercodes
wurde in diesem Beispiel zugunsten der Lesbarkeit des Programms verzichtet.
Der Konstruktor dieser Klasse bietet noch eine Reihe anderer Parameter an,
über die das Verhalten beeinflusst werden kann. Diese werden im Beispiel nicht
benötigt und sollen hier der Vollständigkeit halber nur kurz aufgelistet werden.
134
Über EXPORTING-Parameter PARENT kann ein übergeordneter Container, in den die
neue Instanz eingefügt werden soll, übergeben werden. Es handelt sich hierbei
in der Regel immer um eine Instanz der Klassen CL_GUI_SPLITTER_CONTAINER oder
CL_GUI_EASY_SPLITTER_CONTAINER, da nur diese beiden Container-Typen in der
Lage sind mehr als ein Control aufzunehmen. Mit den Parametern DYNNR sowie
REPID kann das Control fest mit einem Dynpro verknüpft werden. Werden diese
beiden Parameter versorgt, muss im Parameter NO_AUTODEF_PROGID_DYNNR der
Wert »X« (Defaultwert ist Space) übergeben werden, um diese Zuordnung nicht
automatisch durchzuführen. Über den Parameter STYLE kann unter Verwen-
dung der in der Klasse CL_GUI_CONTAINER definierten Konstanten die mit dem
Präfix WS_ beginnen, die visuelle Repräsentation des Containers beeinflusst wer-
den.
Zuletzt sei noch der Parameter LIFETIME erwähnt, der im Control Framework
eine wichtige Rolle einnimmt. Über ihn wird die Lebensdauer der Control-In-
stanz festgelegt. Die Klasse CL_GUI_CONTAINER definiert hierfür zwei Konstanten.
Der Wert der Konstante CNTL_LIFETIME_IMODE legt fest, dass die Instanz so lange
erhalten bleibt, wie der interne Modus, d.h. das Programm. Die Anweisungen
LEAVE PROGRAM bzw. LEAVE TO TRANSACTION beenden das aktuelle Programm und
zerstören im dem Fall auch die Instanzen des Controls. Demgegenüber steht der
Wert der Konstante CNTL_LIFETIME_DYNPRO. Wie der Name bereits vermuten lässt,
beschränkt sich hierbei die Lebensdauer der Control-Instanz auf die Lebens-
dauer des verknüpften Dynpros. Defaultwert dieses Parameters ist
CNTL_LIFETIME_IMODE. Dieser sollte nur in begründeten Einzelfällen verändert
werden.
Somit steht dem Programm nun eine initialisierte Instanz des Containers zur
Verfügung. Diese ist bereits mit dem Custom Control auf dem Dynpro ver-
knüpft. Was noch fehlt ist das grafische Control, welches eigentlich angezeigt
werden sollte. Die übrigen Container-Klassen haben entsprechend ihrer Aufga-
ben unterschiedliche Konstruktor-Schnittstellen.
135
3.3 Nochmal Bäume: Die »neue« Baumdarstellung
Abbildung 3.12
Vererbungshierarchie der SAP Tree-Klassen
Als Beispiel soll hier der gleiche Baum aufgebaut werden, wie in Abschnitt 3.1.
Da diese Art der Baumdarstellung ein Dialogprogramm voraussetzt, wird das
Beispielprogramm aus dem vorigen Abschnitt verwendet. Die Baumdarstel-
lung wird hierbei auf der zweiten Seite des Tab-Strip realisiert.
Wie im Abschnitt 3.1 wird der Baum auch in diesem Abschnitt in mehreren Stufen
mit wachsender Komplexität aufgebaut. Zunächst wird hierbei eine Instanz der
Klasse CL_GUI_SIMPLE_TREE verwendet. Bäume, die diesen Typ verwenden, sind
dadurch charakterisiert, dass ihre Knoten nur aus einem Icon und einem Textfeld
bestehen können. Sollen mehr Informationen zu einem Knoten angezeigt werden,
muss ein anderer Baumtyp verwendet werden. Mit dem Hinzufügen der zweiten
Darstellungsebene wird daher im Beispiel auf eine Instanz der Klasse CL_GUI_-
COLUMN_TREE gewechselt. Die Klasse CL_GUI_COLUMN_TREE ist – genauso wie die Klas-
se CL_GUI_LIST_TREE – von der Klasse CL_ITEM_TREE_CONTROL abgeleitet. Sie sind da-
durch charakterisiert, dass zu jedem Knoten ein Hierarchieteil, der die Position
des Knotens innerhalb des Baums beschreibt, weitere Informationen ausgegeben
werden können, um die Knoten ausführlicher darzustellen. Während diese bei In-
stanzen von CL_GUI_LIST_TREE einfach hintereinander ausgegeben werden, sind
sie bei Objekten vom Typ CL_GUI_COLUMN_TREE als benannte Spalten angelegt. Über
diesen Namen kann auf die Spalteninhalte eines Knotens zugegriffen werden.
Alle Spalten haben hierbei eine definierte Breite, werden also – unabhängig von
der Länge ihres Inhaltes – über alle Knoten hinweg gleich lang ausgegeben. Bei
Instanzen der Klasse CL_GUI_LIST_TREE werden die Teile eines Knotens einfach
hintereinanderweg ausgegeben.
136
Da bei Bäumen vom Typ CL_GUI_COLUMN_TREE jedoch alle Knoten des Baumes die
gleiche Spaltenstruktur verwenden, die zweite und dritte Ebene des Beispiels je-
doch verschiedene Datenstrukturen anzeigen soll, wird zur Demonstration der
Möglichkeiten der Klasse CL_GUI_LIST_TREE mit der dritten Darstellungsebene
auf diesen Baumtyp gewechselt.
Diese Variable muss ebenfalls vor der Anzeige des Dynpros, auf dem der Baum
erscheinen soll, initialisiert werden.
137
3.3 Nochmal Bäume: Die »neue« Baumdarstellung
CNTL_SYSTEM_ERROR = 2
CREATE_ERROR = 3
FAILED = 4
ILLEGAL_NODE_SELECTION_MODE = 5.
ENDMODULE.
Die Instanz des Baumes ist somit erzeugt, der Baum enthält allerdings zu die-
sem Zeitpunkt noch keine Knoten.
Hierzu wird am Ende des Moduls CREATE_TREE die neue FORM-Routine
CREATE_SIMPLE_TREE_NODES aufgerufen und die Referenz auf die Instanz des Bau-
mes übergeben.
...
PERFORM CREATE_SIMPLE_TREE_NODES USING G_TREE.
...
Die Knoten müssen zunächst in Form einer internen Tabelle im Programm er-
zeugt und anschließend mit einem Aufruf der Methode ADD_NODES in den Baum
eingefügt werden. Um die Kommunikation des Tree-Controls mit seiner Stell-
vertretetklasse im ABAP gering zu halten, empfielt SAP nach Möglichkeit, alle
Knoten des Baumes mit einem Aufruf von ADD_NODES einzufügen. Nur wenn die
Anzahl der Knoten größer als 500 im lokalen Netz bzw. 100 bei Verwendung
von Weitverkehrs-Netzen (WAN) ist, legt SAP ein mehrfaches Aufrufen der
Methode mit einer entsprechend geringeren Anzahl Knoten nahe. Diese
Betrachtungen werden in diesem Beispiel vernachlässigt, da die Anzahl der
Knoten diese Grenzen nicht erreicht.
Die Knoten des Baumes werden im Programm in einer internen Tabelle aufge-
baut und an die Methode ADD_NODES als Block übergeben. Die Struktur der Kno-
tentabelle ist hierbei nicht namentlich festgelegt. Es muss sich jedoch um eine im
Data Dictionary definierte Struktur handeln. Auch beim Aufbau dieser Struktur
gibt SAP wenig Spielraum. Zunächst muss sie die vordefinierte Struktur
TREEV_NODE enthalten. Im Anschluss an deren Felder muss ein Textfeld mit dem
Namen TEXT definiert werden. Erst die darauf folgenden Spalten können frei de-
finiert werden, haben aber auf die Darstellung des Knotens keinen Einfluss.
Für das Beispiel soll daher die Struktur ZFLIGHTSIMPLE mit folgendem Aufbau
angelegt werden:
138
Feldname Daten- Bedeutung
typ
N_IMAGE CHAR 6 Icon für Knoten, wenn Teilbaum nicht angezeigt wird
Tabelle 3.8
Aufbau der Struktur ZFLIGHTSIMPLE
Die Aufgabe der Routine CREATE_SIMPLE_TREE_NODES besteht also darin, eine inter-
ne Tabelle mit oben dargestellter Struktur zu erzeugen und durch einen Aufruf
der Methode ADD_NODES in die Instanz des Baumes einzufügen.
139
3.3 Nochmal Bäume: Die »neue« Baumdarstellung
SELECT CARRID
CARRNAM
INTO L_NODES-NODE_KEY
L_NODES-TEXT
FROM SCARR.
APPEND L_NODES.
ENDSELECT.
Zunächst wird der Wurzelknoten des Baums definiert. Diese besteht – analog
zum Beispiel in Abschnitt 3.1 lediglich aus dem Text »Flüge«. Anschließend
werden aus den Einträgen der Tabelle SCARR die Knoten für die Fluggesellschaf-
ten erzeugt. Alle diese Knoten werden mit Bezug zum Wurzelknoten als dessen
jeweils letztes Kind angelegt. Eine Umsortierung wie im Abschnitt 3.1 erübrigt
sich somit. Als Knoten-ID wird der Primärschlüssel der Tabelle SCARR, die Air-
line-ID (CARRID) verwendet. Die Anzeige des Knotens hingegen verwendet die
Bezeichnung der Fluggesellschaft im Klartext.
Zuletzt werden die erzeugten Knoten mit einem Aufruf von ADD_NODES in die In-
stanz des Baumes eingefügt.Abbildung 3.15 zeigt den bisher erzeugten Baum.
140
Abbildung 3.13
Baum vom Typ CL_GUI_SIMPLE_TREE mit Fluggesellschaften (© SAP AG)
141
3.3 Nochmal Bäume: Die »neue« Baumdarstellung
In der zweiten Ebene des Beispiels sollen die jeweiligen Flugverbindungen der
Fluggesellschaften angzeigt werden. Analog zum Beispiel in Abschnitt 3.1 wer-
den diese aus der Tabelle SPFLI, die in jedem R/3 Basissystem vorhanden ist,
ausgelesen und in Form von Spalten innerhalb der Baumdarstellung eingefügt.
Dabei bildet in der zweiten Ebene die Flugnummer den Hierarchieteil. Die üb-
rigen Informationen werden im zweiten Bereich des Baumes in Spalten darge-
stellt. Hierzu wird das Beispiel des vorigen Abschnittes dahingehend verändert,
dass der Baum statt mit einer Instanz der Klasse CL_GUI_SIMPLE_TREE durch ein
Instanz der Klasse CL_GUI_COLUMN_TREE repräsentiert wird.
Zunächst muss hierzu der Typ der globalen Variable G_TREE geändert werden.
Statt die Klasse CL_GUI_SIMPLE_TREE muss die Variable jetzt die Klasse
CL_GUI_COLUMN_TREE referenzieren.
Weiterhin muss das Module CREATE_TREE, in dem die Instanz dieser Klasse er-
zeugt wird, angepasst werden, um den Konstruktor dieser Klasse zu bedienen.
Da hier eine Struktur für den Aufbau der Überschrift des Hierarchieteils über-
geben werden muss, wird der eigentliche Konstruktoraufruf in die FORM-Routine
CREATE_TREE_INSTANCE ausgelagert.
MODULE CREATE_TREE.
* Der Tree soll nur erzeugt werden, wenn das Anlegen des
* Containers erfolgreich war.
CHECK NOT G_CONTAINER IS INITIAL.
FORM CREATE_TREE_INSTANCE
CHANGING P_TREE TYPE REF TO CL_GUI_COLUMN_TREE.
DATA L_HEADER TYPE TREEV_HHDR.
* Hierarchie-Überschrift definieren
L_HEADER-HEADING = 'Hierarchie'(002).
L_HEADER-WIDTH = 50.
142
HIERARCHY_HEADER = L_HEADER
EXCEPTIONS
LIFETIME_ERROR = 1
CNTL_SYSTEM_ERROR = 2
CREATE_ERROR = 3
FAILED = 4
ILLEGAL_NODE_SELECTION_MODE = 5.
ENDFORM.
Tabelle 3.9
Im Anschluss daran müssen die Spalten, mit denen der Baum angezeigt
wird, erzeugt werden. Hierzu wird die Methode ADD_COLUMN der Klasse
CL_GUI_COLUMN_TREE verwendet. Der Aufruf dieser Methode wird ebenfalls in ei-
ner eigenen FORM-Routine namens CREATE_TREE_COLUMNS implementiert. Der Auf-
ruf dieser Routine erfolgt im oben dargestellten MODULE unmittelbar nach der Er-
zeugung der Bauminstanz, aber vor dem Erstellen der Knoten.
MODULE CREATE_TREE
...
CHECK NOT G_TREE IS INITIAL.
PERFORM CREATE_TREE_COLUMNS USING G_TREE.
...
143
3.3 Nochmal Bäume: Die »neue« Baumdarstellung
ENDMODULE.
In dieser FORM-Routine wird für jede der Spalten, ein Aufruf der Methode
ADD_COLUMN eingefügt. Auf eine Darstellung der vollständigen Routine wurde
hier verzichtet.
Zuletzt müssen auch in diesen Baum die Knoten eingefügt werden. Sowohl beim
Column-Tree als auch beim anschließend gezeigten List-Tree müssen hierzu
zwei interne Tabellen erzeugt werden. In der ersten Tabelle, die auf der Dictio-
nary-Struktur TREEV_NODE basieren muss (siehe Tabelle 3.10), werden die Knoten
selbst definiert. In der zweiten Tabelle, deren Struktur die Dictionary-Tabelle
TREEV_ITEM (siehe Tabelle 3.12) gefolgt von einem Textfeld mit dem Namen TEXT
enthalten muss, werden die Items, in diesem Fall die Spalten, aus denen der Kno-
ten aufgebaut ist, abgelegt. Die Struktur, die der Item-Tabelle zugrunde liegt,
muss auf jeden Fall als Dictionary-Struktur angelegt werden. Im Beispiel wird
diese unter dem Namen ZFLIGHTITEM erzeugt. Für jeden Knoten existiert demnach
in der Node-Tabelle genau ein Satz während die Item-Tabelle für jede gefüllte
Spalte jedes Knotens einen Satz enthält.
144
Feldname Datentyp Bedeutung
N_IMAGE CHAR 6 Icon für Knoten, wenn Teilbaum nicht angezeigt wird
LAST_HITEM CHAR 12 Name des letzten Items, das zum Hierarchieteil des Bau-
mes gehört (nur bei CL_GUI_LIST_TREE)
Tabelle 3.10
Aufbau der Struktur TREEV_NTAB
CLASS INT 4 Legt fest, ob es sich bei dem Item um einen Text
FONT INT 4 Legt die Schriftart des Items Fest. Mögliche Werte:
ITEM_FONT_DEFAULT
ITEM_FONT_PROP
ITEM_FONT_FIXED
145
3.3 Nochmal Bäume: Die »neue« Baumdarstellung
Tabelle 3.11
Aufbau der Struktur TREEV_ITEM
FORM CREATE_COLUMN_TREE_NODES
USING P_TREE TYPE REF TO CL_GUI_COLUMN_TREE.
DATA: L_NODE_TAB TABLE OF TYPE TREEV_NTAB,
L_ITEM_TAB TABLE OF TYPE ZFLIGHTITEM.
DATA: L_SPFLI TABLE OF TYPE SPFLI,
L_NODE_KEY LIKE L_NODE_TAB-NODE_KEY,
L_HAS_SUBNODES TYPE C.
146
L_NODE_TAB-EXPANDER = 'X'.
L_ITEM_TAB-NODE_KEY = 'ROOT'.
L_ITEM_TAB-ITEM_NAME = 'HIERARCHY'.
L_ITEM_TAB-CLASS = P_TREE->ITEM_CLASS_TEXT.
L_ITEM_TAB-FONT = P_TREE->ITEM_FONT_DEFAULT.
L_ITEM_TAB-TEXT = 'Flüge'.
APPEND: L_NODE_TAB,
L_ITEM_TAB.
IF SY-SUBRC EQ 0.
L_HAS_SUBNODES = 'X'.
ELSE.
CLEAR L_HAS_SUBNODES.
ENDIF.
147
3.3 Nochmal Bäume: Die »neue« Baumdarstellung
ITEM_TABLE = L_ITEM_TAB
ITEM_TABLE_STRUCTURE_NAME = 'ZFLIGHTITEM'
EXCEPTIONS
FAILED = 1
CNTL_SYSTEM_ERROR = 2
ERROR_IN_TABLES = 3
DP_ERROR = 4
TABLE_STRUCTURE_NAME_NOT_FOUND = 5.
ENDFORM.
P_ITEM_TAB-NODE_KEY = P_NKEY.
148
P_ITEM_TAB-ITEM_NAME = 'HIERARCHY'.
P_ITEM_TAB-CLASS = P_TREE->ITEM_CLASS_TEXT.
P_ITEM_TAB-FONT = P_TREE->ITEM_FONT_DEFAULT.
P_ITEM_TAB-TEXT = P_SCARR-CARRNAME.
APPEND P_ITEM_TAB.
ENDFORM.
Anders verhält es sich für die Knoten der Flugverbindungen. Jeder Knoten des
Baumes wird auf dieser Ebene durch die Flugnummer im Hierarchieteil sowie
die Felder
◗ Abflugort (CITYFROM)
◗ Abflughafen (AIRPFROM)
◗ Zielort (CITYTO)
◗ Zielflughafen (AIRPTO) sowie die
◗ Abflugzeit (DEPTIME)
repräsentiert.
Der Key der erzeugten Knoten besteht hier nicht nur aus der ID der Fluggesell-
schaft (CARRID), wie bei den übergeordneten Knoten, sondern zusätzlich noch
über die Flugnummer (CONNID) der Tabelle SPFLI. Um das Bilden des Schlüssels
zu vereinfachen, wird im TOP-Include ein Struktur-Typ erzeugt, die die Zuwei-
sung entsprechend der Implementierung der Routine CREATE_SPFLI_NODE verein-
facht.
TYPES: BEGIN OF T_NODE_KEY,
CARRID LIKE SCARR-CARRID,
CONNID LIKE SPFLI-CONNID,
FLDATE LIKE SFLIGHT-FLDATE,
END OF T_NODE_KEY.
Die Struktur enthält bereits das für die dritte Baumebene benötigte Flugdatum
Kapitel 3 – Spezielle Dialogelemente
(FLDATE). Die Zuweisung des Schlüssels an das entsprechende Strukturfeld er-
folgt hierbei über eine Hilfsvariable mit dem neu definierten Typ. Der Schlüssel
des neuen Knotens wird dabei elegant über die MOVE-CORRESPONDING-Anweisung
erstellt. Diese Möglichkeit hätte ebenso bei der Erzeugung der Airline-Knoten
verwendet werden können. Dann allerdings unter Verwendung der Feldleiste
SCARR.
149
3.3 Nochmal Bäume: Die »neue« Baumdarstellung
* Knoten-Key bilden
MOVE-CORRESPONDING SPFLI TO L_NKEY.
P_ITEM_TAB-NODE_KEY = L_NKEY.
P_ITEM_TAB-ITEM_NAME = 'CITYFROM'.
P_ITEM_TAB-CLASS = P_TREE->ITEM_CLASS_TEXT.
P_ITEM_TAB-FONT = P_TREE->ITEM_FONT_DEFAULT.
WRITE P_SPFLI-CITYFROM TO P_ITEM_TAB-TEXT.
APPEND P_ITEM_TAB.
...
ENDFORM.
Mit diesem Schlüssel wird zunächst der Knotensatz in der Tabelle P_NODE_TAB
erzeugt Hierbei wird der neue Knoten immer als letzter Kind-Knoten an den
übergeordneten Knoten (Parent), im Beispiel die Fluggesellschaft, angehangen
(RELAT_LAST_CHILD). Optional könnte ein neuer Knoten auch als erster Kind-Kno-
ten (RELAT_FIRST_CHILD), sowie als erster (RELAT_FIRST_SIBLING), letzter (RELAT_
LAST_SIBLING), nächster (RELAT_NEXT_SIBLNG) oder vorheriger (RELAT_PREVIOUS_
SIBLING) Knoten auf der gleichen Ebene wie der Referenzknoten angelegt wer-
den.
Im Anschluss daran wird für jedes Feld, mit dem der Knoten angezeigt werden
soll, ein Satz in der Item-Tabelle angelegt. Die erste Spalte, die die Flugnummer
enthält, wird im Hierarchieteil des Baumes in der Spalte »HIERARCHY« dargestellt.
Die übrigen Spalten, die im Quelltext lediglich angedeutet wurden, werden im
hinteren Bereich der Baumdarstellung in den zuvor angelegten Spalten ange-
zeigt. Um den Knoten vollständig zu füllen, müsste ein entsprechender Code-
Block für jede der übrigen Spalten in die Routine aufgenommen werden. Die
Spalteninhalte werden in der Tabelle P_ITEM_TAB abgelegt.
150
.
Abbildung 3.14
Darstellung eines Baumes vom Typ CL_GUI_COLUMN_TREE (© SAP AG)
Nachdem dies alles ausgeführt wurde, kann die Transaktion gestartet werden.
Es spielt hierbei keine Rolle, ob die Transaktionsvariante zum Blättern des Tab-
Strip im SAPGUI oder auf dem Applikationsserver verwendet wird. Die Baum-
darstellung entspricht immer der in Abbildung 3.17 gezeigten Maske.
Deutlich erkennbar ist hier die Trennung des Hierarchieteils in der Spalte mit
dem Titel »Hierarchie«, sowie der übrigen Spalten beginnend mit der Spalte
151
3.3 Nochmal Bäume: Die »neue« Baumdarstellung
für sich gesehen eine eigene visuelle Repräsentation im Baum annehmen kann.
Um dieses Manko der spaltenorientierten Bäume zu umgehen, wurde von SAP
ein dritter Typ von Bäumen, die List-Trees, definiert.
Bei dieser Baumart wird die mit den Column-Trees eingeführte Teilung der
Knoten von deren visuellen Darstellungeigenschaften auf dem Ausgabegerät
beibehalten. Auch hier wird, wie bei den Column-Trees auch, der Baum in einen
Teil, der die Struktur des Baumes definiert und einen Teil, der die Zusatzinfor-
mationen der Knoten enthält, unterteilt. Anders als bei den Column-Trees wer-
den beim List-Tree die Spalten jedoch nicht bei der Erzeugung des Baumes an-
gelegt. Die Spalten eines List-Trees haben keinen Namen, sondern werden
entsprechend ihrer Position in einem Knoten durchnummeriert. In dieser Eigen-
schaft sind die Spalten des List-Trees mit den Textfeldern der in Abschnitt 3.1
dargestellen Bäume vergleichbar, wobei die Anzahl der Felder, die einen Kno-
ten ausmachen, nicht beschränkt ist. Zusätzlich dazu wurde die Beschränkung,
dass der Hierarchieteil des Baumes nur aus einer Spalte bestehen kann, aufge-
hoben.
Vom Programmiermodell unterscheiden sich die List-Trees von den zuvor ge-
zeigten Column-Trees nur in zwei Punkten. Zum einen müssen die Spalten des
List-Trees nicht vor deren Verwendung angelegt werden und zum anderen
können die einzelnen Spalten nicht mit einem Namen versehen werden, son-
dern werden – von links beginnend – durchnummeriert. Die Breite jeder Spalte
kann dabei für jede Spalte jedes Knotens individuell festgelegt wrden. Dadurch
können unterschiedliche Knotentypen leicht mit verschiedenen Spalteninfor-
mationen angezeigt werden.
Doch nun zur Praxis. In der dritten Ebene des Baumes der Flugbewegungen sol-
len zu den Flugverbindungen die Flüge angezeigt werden. Ein Flug ist dadurch
gekennzeichnet, dass er eine Flugverbindung an einem bestimmten Datum ist.
Dementsprechend wird der Schlüssel der Tabelle SFLIGHT, in der die Flüge abge-
legt sind, im Vergleich zur Tabelle SPFLI, welche die Flugverbindungen enthält,
um das Feld FLDATE, welches das Flugdatum enthält, erweitert.
Wie im Abschnitt 3.1 dieses Kapitels, soll die Anzeige eines Fluges aus den Fel-
dern
◗ Flugdatum
◗ Preis
◗ Währung
◗ Flugzeugtyp
◗ Anzahl Plätze
◗ Anzahl gebuchter Plätze
bestehen.
152
Zunächst muss hierzu im Deklarationsteil des Beispielprogramms erneut der
Typ der Variablen G_TREE verändert werden. Für den List-Tree kommt hier die
Klasse CL_GUI_LIST_TREE zum Einsatz.
DATA G_TREE TYPE REF TO CL_GUI_LIST_TREE.
FORM CREATE_TREE_INSTANCE
CHANGING P_TREE TYPE REF TO CL_GUI_COLUMN_TREE.
DATA: L_HHEADER TYPE TREEV_HHDR,
L_LHEADER TYPE TREEV_LHDR.
* Hierarchie-Überschrift definieren
L_HHEADER-HEADING = 'Hierarchie'.
L_HHEADER-WIDTH = 50.
* Listen-Überschrift definieren
L_LHEADER-HEADING = 'Liste'.
Da beim List-Tree die Spalten nicht benannt werden, entfällt hier der Parameter
HIERARCHY_COLUMN_NAME der Klasse CL_GUI_COLUMN_HEADER. Gleichwohl kann die
Überschrift für den Hierarchieteil in Form einer Struktur vom Typ TREEV_HHDR
(siehe Tabelle 3.9) definiert werden. Zusätzlich dazu kann eine Struktur mit der
Überschrift des Listenteils des Baumes mit einer Variable vom Typ TREEV_LHDR
definiert werden. Da der Listenteil immer den Rest des Raumes im Container
einnimmt, entfällt bei dieser Struktur im Vergleich zur Struktur TREEV_HHDR das
Feld WIDTH sowie das Feld WIDTH_PIX (siehe Tabelle 3.14).
153
3.3 Nochmal Bäume: Die »neue« Baumdarstellung
Tabelle 3.12
Aufbau der Struktur TREEV_LHDR
* Knoten-Key bilden
MOVE-CORRESPONDING P_SPFLI TO L_NKEY.
P_NKEY = L_NKEY.
154
P_NODE_TAB-EXPANDER = P_FOLDER.
P_NODE_TAB-LAST_HITEM = 1.
APPEND P_NODE_TAB.
P_ITEM_TAB-NODE_KEY = L_NKEY.
P_ITEM_TAB-ITEM_NAME = 1.
P_ITEM_TAB-CLASS = P_TREE->ITEM_CLASS_TEXT.
P_ITEM_TAB-FONT = P_TREE->ITEM_FONT_DEFAULT.
P_ITEM_TAB-LENGTH = 5.
WRITE P_SPFLI-CONNID TO P_ITEM_TAB-TEXT.
APPEND P_ITEM_TAB.
P_ITEM_TAB-NODE_KEY = L_NKEY.
P_ITEM_TAB-ITEM_NAME = 2.
P_ITEM_TAB-CLASS = P_TREE->ITEM_CLASS_TEXT.
P_ITEM_TAB-FONT = P_TREE->ITEM_FONT_PROP.
P_ITEM_TAB-LENGTH = 20.
WRITE P_SPFLI-CITYFROM TO P_ITEM_TAB-TEXT.
APPEND P_ITEM_TAB.
...
ENDFORM.
Das Beispielprogramm demonstriert ebenfalls, dass die Breite jeder Spalte für
jeden Knoten unterschiedlich festgelegt werden kann. Hierfür existieren in
der Item-Tabelle die Felder LENGTH sowie LENGTH_PIX um festzulegen, ob der Wert
in LENGTH als Zeichenbreite oder Pixelbreite interpretiert werden soll.
Um die dritte Ebene des Baumes in die Anzeige zu integrieren wird die Routine
CREATE_LIST_TREE_NODES definiert. Die Routine ähnelt in weiten Teilen der Routi-
ne CREATE_COLUMN_TREE_NODES aus dem vorigen Abschnitt. Zunächst wird der
Wurzelknoten des Baumes erzeugt. Auch hier wird der Spaltenname
»HIERARCHY« aus dem vorigen Abschnitt durch den Wert »1« ersetzt. Anschlie-
ßend werden analog zum Column-Tree die Knoten der Fluggesellschaften auf-
155
3.3 Nochmal Bäume: Die »neue« Baumdarstellung
per Default mit einer nichtproportionalen Schrift dargestellt. Aus diesem Grund
wird im Beispiel nicht der Defaultfont (P_TREE->ITEM_FONT_DEFAULT), sondern
explizit die proportionale Schrift (P_TREE->ITEM_FONT_PROP) gewählt.
FORM CREATE_LIST_TREE_NODES
USING P_TREE TYPE REF TO CL_GUI_LIST_TREE.
DATA: L_NODE_TAB TYPE STANDARD TABLE OF TREEV_NODE WITH DEFAULT KEY,
L_ITEM_TAB TYPE STANDARD TABLE OF ZFLIGHTITEM WITH DEFAULT KEY.
DATA: L_NODE LIKE TREEV_NODE,
L_ITEM LIKE ZFLIGHTITEM.
DATA: L_SCARR LIKE SCARR OCCURS 0 WITH HEADER LINE,
L_SPFLI LIKE SPFLI OCCURS 0 WITH HEADER LINE,
L_SFLIGHT LIKE SFLIGHT OCCURS 0 WITH HEADER LINE.
DATA: L_SCARR_KEY TYPE TREEV_NODE-NODE_KEY,
L_SPFLI_KEY TYPE TREEV_NODE-NODE_KEY,
L_SFLIGHT_KEY TYPE TREEV_NODE-NODE_KEY,
L_HAS_SUBNODES TYPE C.
LOOP AT L_SCARR.
* Einlesen der Flugverbindungen zur Airline
SELECT *
INTO TABLE L_SPFLI
FROM SPFLI
WHERE CARRID = L_SCARR-CARRID.
IF SY-SUBRC EQ 0.
L_HAS_SUBNODES = 'X'.
ELSE.
156
CLEAR L_HAS_SUBNODES.
ENDIF.
IF SY-SUBRC EQ 0.
L_HAS_SUBNODES = 'X'.
ELSE.
CLEAR L_HAS_SUBNODES.
ENDIF.
LOOP AT L_SFLIGHT.
PERFORM CREATE_SFLIGHT_NODE TABLES L_NODE_TAB
L_ITEM_TAB
USING P_TREE
L_SPFLI_KEY
L_SFLIGHT.
ENDLOOP.
ENDLOOP.
ENDLOOP.
157
3.3 Nochmal Bäume: Die »neue« Baumdarstellung
NODE_TABLE = L_NODE_TAB
ITEM_TABLE = L_ITEM_TAB
ITEM_TABLE_STRUCTURE_NAME = 'ZFLIGHTITEM'
EXCEPTIONS
FAILED = 1
CNTL_SYSTEM_ERROR = 2
ERROR_IN_TABLES = 3
DP_ERROR = 4
TABLE_STRUCTURE_NAME_NOT_FOUND = 5.
ENDFORM. " CREATE_LIST_TREE_NODES
2. Bislang wurde hierzu empfohlen, das Include <ICON> ins Programm zu integrieren. In
Release 4.6 weist ein Kommentar in diesem Include explizit darauf hin, dass dies in
Zukunft nicht empfohlen ist und stattdessen die dargestelle TYPE-POOLS-Anweisung ver-
wendet werden soll.
158
Feld T_IMAGE definieren. Diese wird im Feld des Hierarchie-Knotens zusätzlich
zum in TREEV_NODE definierten Icon ausgegeben.
SAP hat für die Knoten Standard-Ikonen definiert, die verwendet werden, wenn
die genannten Felder der Tabellen leer bleiben. Hierarchieknoten mit Unter-
struktur haben standardmäßig die vom Windows-Explorer bekannten Ordner-
Symbole.
Soll explizit definiert werden, dass ein Knoten kein Icon hat, muss das entspre-
chende Feld mit dem Wert »BNONE« belegt werden. Soll ein Icon über dessen
numerischen Wert und nicht über die Konstante angesprochen werden, muss
der Wert in der Form »@<Wert>@« angegeben werden, wobei <Wert> die Nummer
des Icons ist.
Der Baum aus dem vorigen Abschnitt soll hier noch um die Ampeldarstellung
zur Anzeige der Buchungslage ergänzt werden. Hierzu muss in der FORM-Routi-
ne CREATE_SFLIGHT_NODE eine Erweiterung dergestalt vorgenommen werden, dass
zunächst über die Felder SEATSMAX und SEATSOCC der Struktur SFLIGHT die Bele-
gungsquote berechnet wird und abhängig von im TOP-Include zu definieren-
der konstanter Schwellwerte das passende Icon ausgewählt wird.
Die Berechnung der Belegungsquote geschieht in der Routine
CREATE_SFLIGHT_NODE, wie in Abschnitt 3.1.2 gezeigt, über das Hilfsfeld L_BELEGUNG
nach folgendem Muster.
DATA: L_BELEGUNG TYPE F.
...
IF P_SFLIGHT-SEATSMAX NE 0.
L_BELEGUNG = ( ( P_SFLIGHT-SEATSOCC / P_SFLIGHT-SEATSMAX ) * 100 ).
ELSE.
L_BELEGUNG = 0.
ENDIF.
...
Schließlich bleibt noch, abhängig von der Belegungsquote ein Feld mit dem
gewünschten Icon in die Item-Tabelle einzufügen.
...
CLEAR P_ITEM_TAB.
P_ITEM_TAB-NODE_KEY = L_NKEY.
159
3.3 Nochmal Bäume: Die »neue« Baumdarstellung
P_ITEM_TAB-ITEM_NAME = 7.
P_ITEM_TAB-CLASS = P_TREE->ITEM_CLASS_TEXT.
* Defaultwert setzen
P_ITEM_TAB-T_IMAGE = ICON_GREEN_LIGHT.
APPEND P_ITEM_TAB.
...
Abbildung 3.15
Baumdarstellung eines List-Trees mit Ikonen (© SAP AG)
160
Interaktion mit dem Baum
Bisher wurde lediglich gezeigt, wie aus einem Datenmodell die drei Baumvari-
anten erzeugt werden konnten und wie die Darstellung der Knoten des Baums be-
einflusst werden kann. Andersherum besteht auch innerhalb des Control Frame-
works, zu dem die Baumdarstellungen gehören, die Möglichkeit, auf Be-
nutzereingaben zu reagieren. Hierzu wurde seitens SAP ein Eventmodell defi-
niert, welches es den Controls ermöglicht, Ereignisse, die im GUI des Benutzers
auftreten, an den Applikationsserver und das darauf ablaufende ABAP-Pro-
gramm weiterzuleiten. Hierzu definiert jedes Custom Control eine Reihe von
Ereignissen, die auftreten können und zu denen die Kontrolle wieder an das
ABAP-Programm übergeben werden soll.
Da nicht alle Events für ein Programm interessant sind, existiert ein Mechanis-
mus, bei dem sich das ABAP-Programm beim Control mit den Events, für die
eine Benachrichtigung erfolgen soll, registrieren muss. Da die Controls des Con-
trol Frameworks entweder als Javabean oder als ActiveX auf dem GUI des Be-
nutzers ablaufen, kann hier gefiltert werden und eine Kommunikation mit dem
Applikationsserver nur vollzogen werden, wenn sich das ABAP-Programm für
den aufgetretenen Event interessiert. Somit wird die Netzwerk- und Serverbe-
lastung gering gehalten und das Programm muss nur auf die Events reagieren,
die auch behandelt werden sollen. Diese Art der Rückmeldung war bereits bei
der auf Funktionsbausteinen basierenden Baumdarstellung möglich (siehe Ab-
schnitt 3.1.3). Der Unterschied war jedoch, dass bei der alten Baumdarstellung
die Kontrolle auf jeden Fall an den Applikationsserver übergeben wurde und
dieser lediglich bei Bedarf eine definierte FORM-Routine aufgerufen hat. Die Kon-
trolle liegt bei diesem Verfahren also auf jeden Fall auf dem Server und inner-
halb der ABAP-Laufzeitumgebung. Bei den Custom Controls, bei denen Pro-
grammcode auf dem Client abläuft, der nicht zur ABAP-Laufzeitumgebung
gehört, musste – auch aufgrund der Vielzahl der möglichen Events - ein anderes
Verfahren gefunden werden, um effizient auf Ereignisse reagieren zu können.
Um auf einen in der Baumdarstellung auftretenden Event reagieren zu können,
müssen die folgenden Schritte durchlaufen werden: Exemplarisch soll hier auf Kapitel 3 – Spezielle Dialogelemente
den Event NODE_DOUBLE_CLICK reagiert werden, der von der Baumdarstellung aus-
gelöst wird, wenn der Benutzer einen Doppelclick auf einen Knoten durchführt.
Zunächst muss im ABAP-Programm eine Tabelle der Events, auf die das
Programm reagieren soll, angelegt werden. Basierend auf der Struktur
CNTL_SIMPLE_EVENT (siehe Tabelle 3.13), welche in der Typgruppe CNTL definiert
ist, steht ein Tabellentyp mit dem Namen CNTL_SIMPLE_EVENTS zur Verfügung.
161
3.3 Nochmal Bäume: Die »neue« Baumdarstellung
Tabelle 3.13
Aufbau der Struktur CNTL_SIMPLE_EVENT
erzwingen. Diese kann an beliebiger Stelle während der Verarbeitung des PAI
stehen. Es handelt sich hierbei nicht um eine Anweisung der Ablauflogik, daher
muss dieser Aufruf innerhalb eines MODULs oder einer FORM-Routine erfolgen.
Im Beispiel soll lediglich auf den Event NODE_DOUBLE_CLICK reagiert werden. Hier-
zu wird in der FORM-Routine CREATE_TREE_INSTANCE zunächst die Eventtabelle
deklariert und mit dem entsprechenden Satz gefüllt.
...
DATA: L_EVENTS TYPE CNTL_SIMPLE_EVENTS,
L_EVENT TYPE CNTL_SIMPLE_EVENT.
...
L_EVENT-EVENTID = CL_ITEM_TREE_CONTROL=>EVENTID_NODE_DOUBLE_CLICK.
L_EVENT-APPL_EVENT = 'X'.
APPEND L_EVENT TO L_EVENTS.
...
Im Anschluss daran muss die Eventtabelle an die neu erzeugte Instanz des SAP
Trees übergeben werden. Hierfür steht die Methode SET_REGISTERED_EVENTS der
Klassse CL_GUI_CONTROL, von der alle Custom Controls abgeleitet sind, zur Verfü-
gung. Für die neu erzeugte Bauminstanz wird die Methode wie folgt aufgeru-
fen:
CALL METHOD P_TREE->SET_REGISTERED_EVENTS
EXPORTING
162
EVENTS = L_EVENTS
EXCEPTIONS
CNTL_ERROR = 1
CNTL_SYSTEM_ERROR = 2
ILLEGAL_EVENT_COMBINATION = 3.
Somit sind die Maßnahmen abgeschlossen, die notwendig sind, um dem, auf
dem Präsentationsrechner laufenden, Control mitzuteilen, welche Ereignisse in
welcher Art zur Kommunikation mit dem Applikationsserver führen sollen.
Was noch fehlt, um tatsächlich auf den Event zu reagieren, ist der Code, der auf-
gerufen wird, wenn das Ereignis im entsprechenden Control ausgelöst wird.
Bei den Routinen, die Events aus dem Control Framework behandeln, muss es
sich immer um Methoden einer ABAP-Klasse handeln. Normalerweise wird
hierfür innerhalb des ABAP-Programms eine Klasse mit lokaler Gültigkeit de-
klariert und implementiert, die für jeden registrierten Event eine Methode mit
der entsprechenden Schnittstelle zur Verfügung stellt. Bei diesen Methoden
spielt es keine Rolle, ob es sich um Klassen-Methoden oder Instanz-Methoden
der Klasse handelt. Einleuchtenderweise muss bei Verwendung von Instanzme-
thoden allerdings eine globale Variable für die Klasse definiert und eine Instanz
der Klasse erzeugt werden. Da das grundlegende Verhalten beider Varianten
identisch ist, wird an dieser Stelle lediglich auf die Verwendung von Klassen-
Methoden zur Ereignisbehandlung eingegangen.
Die Definition der Klasse – ihr Name kann beliebig gewählt werden – enthält
hier nur eine Klassenmethode, die aufgerufen werden soll, sobald der Benutzer
im Baum einen Knoten doppelt mit der Maus anklickt. Der Event, der dabei aus-
gelöst wird, hat den Namen NODE_DOUBLE_CLICK.
CLASS LCL_EVENT_HANDLER DEFINITION.
PUBLIC SECTION.
CLASS-METHODS NODE_DBL_CLICK_HANDLER
FOR EVENT NODE_DOUBLE_CLICK
OF CL_GUI_LIST_CONTROL
IMPORTING NODE_KEY Kapitel 3 – Spezielle Dialogelemente
SENDER.
ENDCLASS.
163
3.3 Nochmal Bäume: Die »neue« Baumdarstellung
lokalen Klasse zu vereinen. Auf diese Weise kann der Programmcode kompak-
ter gestaltet werden, insbesondere, wenn im Programm viele Custom Controls
verwendet werden.
Die Implementierung der Klasse ist an dieser Stelle nicht von Bedeutung. Im
Beispiel enthält die Methode NODE_DBL_CLICK_HANDLER lediglich einen Aufruf des
Funktionsbausteins POPUP_TO_DISPLAY_TEXT zur Anzeige der angewählten Kno-
ten-ID. Auf eine Darstellung des Programmcodes wird an dieser Stelle verzich-
tet.
Zuletzt muss die noch fehlende Verbindung zwischen der Instanz des Baumes
und der Klasse, die auf die registrierten Events reagieren soll, hergestellt wer-
den. Hierzu steht die ABAP-Anweisung SET HANDLER zur Verfügung. Im konkre-
ten Fall wird der Aufruf
SET HANDLER LCL_EVENT_HANDLER DEFINITION=>NODE_DBL_CLICK_HANDLER
FOR P_TREE.
Abbildung 3.16
Darstellung des Dynpros nach Auslösen des Events (© SAP AG)
164
3.4 DropDown-Listen
In bisherigen R/3-Releaseständen bestand die Möglichkeit, in Eingabefeldern
dem Benutzer mögliche Eingabewerte in Form der so genannten Werthilfe oder
auch (F4)-Hilfe anzubieten. Die angebotenen Werte konnten entweder explizit
vom Programmierer innerhalb der Verarbeitungsroutinen des PROCESS ON VALUE-
REQUEST-Blocks(POV), oder über die Definitionen im Data Dictionary festgelegt
werden. Bei letzterer Möglichkeit, ziehen sowohl Prüftabellen als auch Festwer-
te an der jeweiligen Domäne des Dynpro-Feldes. Der Benutzer musste diese
Werthilfe jedoch nicht verwenden, sondern konnte auch einen gültigen Wert di-
rekt in das Eingabefeld schreiben.
Seit Release 4.0 bietet SAP ein weitere Möglichkeit an, dem Benutzer mögliche
Eingabewerte in ein Feld anzubieten. Es handelt sich hierbei um die so genann-
ten DropDown-Listen. Optisch erkennt man diese neue Variante der Darstel-
lung daran, dass es nicht möglich ist, direkt in das Eingabefeld auf der Maske
zu schreiben. Stattdessen befindet sich rechts neben dem Eingabefeld eine
Schaltfläche mit einem Pfeil, über den der Benutzer ein Listenfeld der möglichen
Eingabewerte des Feldes angezeigt bekommt und daraus auswählen kann. Ein
Beispiel für ein solches DropDown-Listenfeld ist in Abbildung 3.17 dargestellt.
Abbildung 3.17
Maske mit Drop-Down-Listenfeld (© SAP AG)
165
3.4 DropDown-Listen
Abbildung 3.18
Dynpro-Editor mit Eigenschaften eines DropDown-Feldes (© SAP AG)
Weiterhin muss die sichtbare Länge des Feldes ggf. angepasst werden, da im
DropDown-Feld nicht unbedingt der Feldwert selbst, sondern eine Beschrei-
bung des Schlüsselwerts im Klartext angezeigt werden kann. Im Beispiel dieses
Abschnitts ist das DropDown-Feld zwar für das Feld SCARR-CARRID definiert, in
der Liste und auch im Feld selbst wird jedoch der Name der Fluggesellschaft im
Klartext angezeigt. Die sichbare Länge des Feldes auf dem Dynpro muss dem-
166
entsprechend auf die Länge des Feldes CARRNAME gesetzt werden, obwohl das
Dictionary-Feld, welches dem Eingabefeld zugrunde liegt, das Feld CARRID ist.
eingebunden werden. Weiterhin wird davon ausgegangen, dass von einem Mo-
dul des PBO aus die folgende FORM-Routine aufgerufen wird, welche dem Listen-
feld die möglichen Alternativen zuweist.
167
3.4 DropDown-Listen
FORM INIT_DropDown_CARRID.
DATA LISTVALUES TABLE OF TYPE VRM_VALUE.
* Alternativen ermitteln
SELECT CARRID
CARRNAME
INTO LISTVALUES-KEY
LISTVALUES-TEXT
FROM SCARR.
APPEND LISTVALUES.
ENDSELECT.
168
Wird auch für diesen Fall eine FORM-Routine zum Füllen der Werteliste definiert,
könnte diese folgende Implementierung besitzen.
FORM DropDown_CARRID_POV.
DATA: BEGIN OF LISTVALUES OCCURS 0,
CARRID LIKE SCARR-CARRID,
CARRNAME LIKE SCARR-CARRNAME,
END OF LISTVALUES.
* Wertetabelle einlesen
SELECT *
INTO CORRESPONDING FIELDS OF TABLE LISTVALUES
FROM SCARR.
Nachdem auch hier zunächst die Alternativen aus der Tabelle SCARR ermittelt
und in der internen Tabelle LISTVALUES abgelegt wurden, wird hier der Funkti-
onsbaustein F4IF_INT_VALUE_REQUEST aufgerufen, wobei definiert wird, dass die
Einträge des Listenfeldes sortiert ausgegeben werden sollen.
169
3.5 Table-Views
Referenz auf die Tabelle SCARR. Wird auf dem Dynpro demnach statt des Feldes
SCARR-CARRID das Feld SPFLI-CARRID verwendet, werden die möglichen Alternati-
ven der DropDown-Liste automatisch ermittelt und die Programmteile der vo-
rigen Abschnitte obsolet. Aus diesem Grund ist im Data Dictionary häufig die
Konstellation anzutreffen, dass eine Tabelle sich selbst als Prüftabelle referen-
ziert. Dies mag auf den ersten Blick unnötig und verwirrend aussehen, hilft aber
im vorliegenden Beispiel Code zu sparen.
Ebenso könnte zur Eingrenzung der Eingabemöglichkeiten ein Matchcode-Ob-
jekt definiert werden. Es wäre auch möglich, die Optionen durch Festwerte an
der Domäne des Feldes zu definieren. Im vorliegenden Fall ist dieser Weg aller-
dings aufgrund der Anwendungssituation nicht möglich.
3.5 Table-Views
Mit Release 3.0 hat SAP das Table-View-Control eingeführt. Es handelt sich
hierbei um eine moderne Variante des Step-Loops. Mit Release 4.6 empfiehlt
SAP die Table-Views anstatt der bekannten Step-Loops einzusetzen und hat
selbst in den meisten Standard-Transaktionen von Step-Loops auf Table-Views
umgestellt. Bei den Table-Views handelt es sich um komplexe Dynpro-Elemen-
te, die weitaus mehr Möglichkeiten zulassen, als Step-Loops bisher. So kann z.B.
die Breite einzelner Spalten vom Benutzer nach Belieben verändert werden. Bei
Bedarf können die aktuellen Darstellungsoptionen eines Table-Views je Benut-
zer abgespeichert werden und ermöglichen so eine personalisierte Darstellung.
Weiterhin kann in Table-Views bei Bedarf horizontal über die Spalten gerollt
werden, wobei die Möglichkeit besteht, einzelne Führungsspalten als feste,
nicht scrollbare Spalten anzulegen. Horziontal kann dann nur über die nicht-fi-
xen Spalten gerollt werden. Außerdem bieten Table-Views die Möglichkeit,
Selektionen sowohl auf Zeilen- als auch auf Spaltenebene durchzuführen.
Die Zeilen einer Table-View können neben statischen Texten und Eingabefel-
dern auch andere Dialog-Elemente wie z.B. Ankreuzfelder, Auswahlfelder oder
auch Schaltflächen enthalten. Einen Nachteil, den Table Views gegenüber Step
Loops in der bisherigen Implementierung haben, ist allerdings, dass die Zeilen
einer Table-View lediglich eine Bildschirmzeile hoch sein können. Mehrzeilige
Listendarstellungen, wie sie mit der Step Loop-Technik möglich sind, können
mit Table Views derzeit nicht realisiert werden.
Auch in diesem Abschnitt sollen die Möglichkeiten des neuen Controls anhand
der Daten aus dem Beispiel des Abschnitt 3.1 demonstriert werden. Im Table-
Control sollen die Flüge einer Fluggesellschaft angezeigt werden. Als Rahmen-
programm soll das in Abschnitt 3.2 begonnene Programm verwendet werden.
Das programmierte Table-Control wird auf dem Subscreen 9100 des dort defi-
nierten Tab-Strips unterhalb der in Abschnitt 3.4 definierten Drop Down-Liste,
über die die gewünschte Fluggesellschaft ausgewählt werden kann, angelegt.
170
3.5.1 Deklaration einer Table-View
Anders als die bisherigen Dynpro-Elemente in der Dialogprogrammierung, ge-
nügt es bei Table Views nicht im Dialogeditor ein entsprechendes Control anzu-
legen. So wie die Elemente eines Report-Selektionsbildes muss ein Table-View
zusätzlich als Datenfeld im Datendeklarationsteil des Modulpools angelegt
werden.
Dies geschieht mittels der CONTROLS-Anweisung der ABAP-Sprache in der fol-
genden Form:
CONTROLS <Table-Name> TYPE TABLE-VIEW USING SCREEN <Dynpronr>.
Durch diese Anweisung wird – wie z.B. bei der PARAMETERS-Anweisung in Re-
ports – ein Datenbereich deklariert, der den Aufbau der von SAP definierten
Struktur CXTAB_CONTROL besitzt (siehe Tabelle 3.14). Die Definition dieser Struktur
befindet sich in der Typgruppe CXTAB. Sie beschreibt programmintern die Struk-
tur und die Eigenschaften des Table-Views. Wie in späteren Abschnitten gezeigt
wird, können diese Eigenschaften durch das Programm zur Laufzeit verändert
werden.
171
3.5 Table-Views
V_SCROLL C(1)
Tabelle 3.14
Struktur CXTAB_CONTROL für allgemeine Attribute einer Table-View
Die Struktur enthält im Wesentlichen die Felder für die Eigenschaften, die im
unteren Bereich des Attributefensters für das Control im Screen-Editor abgelegt
sind (siehe Abbildung 3.26). Weiterhin enthält die Struktur eine Tabelle mit den
Spalteninformationen des Table-Views. Diese Tabelle, deren Sätze den in Tabel-
le 3.15 dargestellten Aufbau haben, enthält für jede im Screen-Editor angelegte
Spalte des Table-Controls einen Eintrag. Die Struktur der Tabelle 3.15 ist unter
dem Namen CXTAB_COLUMN ebenfalls in der Typgruppe CXTAB definiert.
SCREEN SCREEN Enthält die Felder der Systemstruktur SCREEN, welche die
Attribute der Spalten zur Laufzeit darstellen.
Tabelle 3.15
Struktur CXTAB_COLUMN für Spaltenattribute einer Table-View
Zu beachten ist, dass die in der Struktur CXTAB_CONTROL enthaltene Tabelle COLS
mit den beschriebenen Spalteninformationen ohne Kopfzeile deklariert wurde.
Ein Zugriff auf diese Tabelle muss demnach immer über eine separat definierte
Feldleiste erfolgen. Dies wird nochmals im Abschnitt 3.5.5 dargestellt.
172
3.5.2 Table-Views auf dem Dynpro anlegen
Ein Table-View wird zunächst im Dynpro-Editor angelegt. Hier werden neben
seiner Größe auch die darin enthaltenen Spalten und deren Attribute definiert.
Um das Table-View für das Beispiel anzulegen, wird das Dynpro 9100 des Pro-
gramms SAPMZFLIGHT im Dynpro-Editor bearbeitet. Dort befindet sich bereits das
in Abschnitt 3.3 definierte Listenfeld mit den Fluggesellschaften. Unterhalb die-
ses Listenfeldes soll ein Table-Control angelegt werden.
Im grafischen Screen-Editor wird hierzu aus der Werkzeugspalte am linken
Fensterrand das »Table-View«-Tool ausgewählt (4. von unten). Im Anschluss
daran wird im Dynpro-Bereich des Editors der Table-View mit der Maus in der
gewünschten Größe aufgezogen. Die Veränderung der Größe des Controls ist
auch im Nachhinein jederzeit über die Markierungen am Rand des Table-Views
möglich. Mit einem doppelten Mausklick auf das Element können die Eigen-
schaften des Controls angezeigt und geändert werden (siehe Abbildung 3.19).
Im Beispiel erhält der Table-View den Namen FLIGHTSVIEW.
Abbildung 3.19
Anlegen eines Table-Views (© SAP AG)
173
3.5 Table-Views
Abbildung 3.20
Auswahl der Dictionary-Felder für den Table-View (© SAP AG)
Erfolgt der Click jedoch auf dem Table-View, wird für jedes ausgewählte Feld
eine Spalte im Table-View angelegt. Außerdem wird am Anfang der Spalte eine
Spaltenüberschrift, analog zum Beschriftungsfeld bei normalen Ein-/Ausgabe-
feldern, angelegt (siehe Abbildung 3.21). Jetzt sind alle Spalten als Eingabefelder
angelegt. Die Spaltenüberschriften entsprechen den Beschriftungen der Felder,
wenn kein Table-View verwendet würde. Die standardmässige Breite der Spal-
174
ten im Table-View entspricht der definierten Breite der Spalten im Data Dictio-
nary.
Über die Feldattribute der Spalten werden nacheinander alle Spalten als nicht
eingabebereit definiert und weiterhin die erste Bildschirm-Gruppe auf den Wert
»TAB« gesetzt. Letzteres wird später in diesem Kapitel von Bedeutung sein.
Somit ist das Table-View im Dynpro-Editor vollständig angelegt. Der grafische
Editor kann nun verlassen werden. Als nächster Schritt folgt, den Table-View in
der Ablauflogik des Dynpros zu verankern und dafür zu sorgen, dass die ent-
sprechenden Informationen zur Laufzeit im Dynpro erscheinen.
175
3.5 Table-Views
Im Module SHOW_FLIGHT_9100 werden lediglich die aktuellen Daten aus der Feld-
leiste der Tabelle SPFLI_TAB in die Feldleiste der Tabelle SPFLI, deren Felder als
Spalten im Table-View definiert sind, übertragen.
MODULE SHOW_FLIGHT_9100 OUTPUT.
MOVE-CORRESPONDING SPFLI_TAB TO SPFLI.
ENDMODULE. " SHOW_FLIGHT_9100 OUTPUT
176
den PBO des Dynpros wird der aktuelle Inhalt der Tabelle SPFLI_TAB in die Zei-
len des Table-Views übertragen.
Wie gewünscht sind die einzelnen Spalten des Table-Views nicht eingabebereit.
Allerdings enthalten die Spalten Abflugzeit sowie Ankunftszeit auch in den Zei-
len einen Wert, in denen kein Flug angezeigt wird. Wie dies zu verhindern ist,
wird in Abschnitt 3.5.5 beschrieben.
Abbildung 3.22
Darstellung der Table-View ohne dynamische Veränderungen (© SAP AG)
177
3.5 Table-Views
178
Abbildung 3.24
Tabelleneinstellungen für Table-Views (© SAP AG)
179
3.5 Table-Views
Abbildung 3.25
Administrationseinstellungen zu einem Table-View (© SAP AG)
Zellenattribute ändern
Zunächst soll auf den am Ende von Abschnitt 3.5.3 festgestellten Missstand,
dass an sich leere Zeilen mit den Initialwerten der verwendeten Datentypen
dargestellt werden, eingegangen werden. Während sich dies bei Zeichenfeldern
nicht auswirkt, da der Initialwert für diese leer ist, hat dieser Umstand bei nu-
merischen, Datums- oder – wie im Beispiel – Zeitfeldern sehr störende Auswir-
kungen. Die einfachste Möglichkeit, diesem Umstand zu begegnen ist, die Zel-
len, die keine Werte enthalten, auszublenden.
Die Elementeliste des Dynpros enthält sowohl für den Table-View an sich, als
auch sämtliche darin enthaltene Spalten Einträge. Wie bei Step-Loops können
180
die Attribute der Spalten aber nur innerhalb der LOOP-Schleife in der Ablauflogik
des Dynpros verändert werden, wobei die getätigten Einstellungen nur für die
jeweilige Zelle, adressiert durch die aktuelle LOOP-Zeile und den eindeutigen
Spaltennamen, verändert werden. Im Beispiel bedeutet dies, dass die Ausgabe
sämtlicher Spalten einer leeren LOOP-Zeile unterdrückt werden soll.
Hierzu wird in der Ablauflogik des Dynpros 9100 innerhalb der LOOP-Schleife
des PBO das neue Module CLOSE_FIELDS aufgerufen.
...
LOOP AT SPFLI_TAB WITH CONTROL FLIGHTSVIEW CURSOR SPFLI_CURSOR.
MODULE SHOW_FLIGHT_9100.
MODULE CLOSE_FIELDS.
ENDLOOP.
...
Die Reihenfolge der Modul-Aufrufe spielt hierbei keine Rolle. Die Implementie-
rung des Moduls besteht aus einer LOOP-Schleife über die Systemtabelle SCREEN.
Hierbei kommt die Tatsache, dass die Spalten der Table-View allesamt in der
Bildgruppe 1 den Wert »TAB« enthalten, sehr gelegen. Dadurch kann auf die
Auswertung von Spaltennamen verzichtet werden. Ein Anfügen von Spalten in
der Table-View ist weniger fehleranfällig, da kein Programmcode angepasst
werden muss, um das Verhalten der neuen Spalten dem der bisherigen Spalten
anzupassen, sondern lediglich eine Eigenschaft der neuen Spalte gesetzt wer-
den muss.
MODULE CLOSE_FIELDS OUTPUT.
LOOP AT SCREEN.
IF SCREEN-GROUP1 = 'TAB'.
IF SPFLI_TAB IS INITIAL.
SCREEN-INPUT = 0.
SCREEN-ACTIVE = 0.
SCREEN-INVISIBLE = 1.
ELSE.
SCREEN-INPUT = 0. Kapitel 3 – Spezielle Dialogelemente
ENDIF.
MODIFY SCREEN.
ENDIF.
ENDLOOP.
ENDMODULE. " close_fields OUTPUT
In der Schleife wird geprüft, ob der aktuelle Tabellensatz initial ist, und – falls ja
– werden alle Felder, die den entsprechenden Wert im Attributfeld »SCREEN-
GROUP1« enthalten, unsichtbar gesetzt (SCREEN-INVISIBLE).
Durch diese Veränderung entspricht die Anzeige des Table-Views (siehe Abbil-
dung 3.26) wesentlich besser den Erwartungen, die man an dieses Control stellt.
181
3.5 Table-Views
Es ist wichtig, nochmals darauf hinzuweisen, dass durch dieses Verfahren le-
diglich Zellen der Table-View ausgeblendet werden. Es können hiermit keine
ganzen Spalten versteckt werden.
182
verändert werden. Steht die Anzahl der anzuzeigenden Spalten zum Zeitpunkt
der Programmierung nicht endgültig fest, bleibt demnach keine andere Wahl,
als die maximale Anzahl Spalten im Control anzulegen und dynamisch die
nicht benötigten Spalten unsichtbar zu machen.
Zur Demonstration dieser Möglichkeit soll im Beispielprogramm die Spalte
CARRID in der Ablauflogik des Dynpros auf unsichtbar gesetzt werden. Hierzu
wird im PBO an beliebiger Stelle außerhalb der LOOP-Schleife der Aufruf für das
Module HIDE_CARRID eingefügt.
...
MODULE HIDE_CARRID.
...
Die Implementierung dieser FORM-Routine besteht lediglich darin, aus der Tabelle
COLS der Struktur FLIGHTSVIEW den Eintrag für die Spalte SPFLI-CARRID zu suchen
und das INVISIBLE-Attribut dieses Eintrags zu setzen. Dementsprechend einfach
ist der Code dieser Routine aufgebaut.
FORM HIDE_CARRID CHANGING P_TABLE TYPE CXTAB_CONTROL.
DATA: L_COL TYPE CXTAB_COLUMN.
Manipulationen, die den Table-View an sich oder die darin enthaltenen Spalten
insgesamt betreffen, müssen immer über diese Struktur erfolgen, während
dynamische Veränderungen an einzelnen Zellen über die Systemtabelle SCREEN
innerhalb der LOOP-Schleife in der Ablauflogik erfolgen müssen.
183
3.5 Table-Views
Spaltenüberschriften ändern
In Fällen, in denen die Anzahl der Spalten des Table-Views nicht von vornher-
ein bestimmt werden können, steht häufig zum Zeitpunkt der Programmerstel-
lung auch noch nicht endgültig fest, welche Daten in den variablen Spalten an-
gezeigt werden sollen und welche Überschriften die jeweiligen Spalten haben.
Wenn die Spalten des Table-Views mit der in Abschnitt 3.5.2 beschriebenen Me-
thode aus Data Dictionary-Feldern angelegt werden, sind die Spaltenüberschrif-
ten als statische Texte angelegt. Der Text dieser Elemente kann zur Laufzeit
nicht verändert werden. Besteht die Anforderung, zur Laufzeit die Spaltenüber-
schrift zu ändern, muss die standardmäßig angelegte Spaltenüberschrift durch
ein vom Programmierer selbst definiertes Feld ersetzt werden. Hierzu muss ein
globales Datenfeld angelegt werden, welches die gewünschte Überschrift ent-
hält.
DATA: G_TITLE(20) TYPE C.
184
Abbildung 3.27
Table-View mit zusätzlicher Spalte mit Referenz auf eine Programmvariable (© SAP AG)
185
Arbeiten mit Texten
4
Texte spielen innerhalb von R/3 eine große Rolle. Neben den reinen betriebs-
wirtschaftlichen Informationen können an den verschiedensten Anwendungs-
objekten zusätzliche Texte für den Benutzer oder den Ausdruck abgelegt wer-
den. Diese Informationen werden in einem gesonderten Bereich der SAP-
Datenbank in Form so genannter Textobjekte abgelegt. Zur Verwaltung dieser
Textobjekte sind im Data Dictionary mehrere Strukturen definiert, über die der
Zugriff auf die Textobjekte innerhalb des Systems möglich sind.
Diese Textobjekte bieten die Möglichkeit, formatierten Text zu speichern. Man
spricht hierbei auch von Textobjekten aus dem Bereich von SAPScript, der Text-
verarbeitungskomponente des R/3-Systems. SAPScript-Textobjekte, die nicht
mit Bezug zu einem Anwendungsobjekt abgelegt werden, werden Standard-
Texte genannt. SAP bietet für diese Texte eine ganze Reihe Funktionen, um Text-
objekte zu speichern, lesen oder zu bearbeiten. Diese und noch mehr Funktio-
nen zur Manipulation von Textobjekten sind in der Funktionsgruppe STXD unter
dem Namen »SAPScript Program Interface 1« zusammengefasst. Hier finden
sich weitere Funktionsbausteine, um Textobjekte als ganzes bearbeiten (z.B. lö-
schen, umbenennen usw.). Die Funktionsgruppe STXE hat den Namen
»SAPScript Program Interface 2« und beinhaltet Funktionen, um Symbole in-
nerhalb des Textes des Textobjekts durch Werte zu ersetzten. Eine ausführliche
Beschreibung aller Funktionen von SAPScript würde den Rahmen dieses Bu-
ches jedoch sprengen. Lediglich die Grundfunktionen, die notwendig sind, um
Texte zu lesen, zu speichern und zu bearbeiten, werden hier vorgestellt.
Auf der anderen Seite existieren Texte, die keine Formatierungen beinhalten. Es
handelt sich hierbei um eine Aneinanderreihung von einfachen Textzeilen ohne
jede Formatierungsmöglichkeit. SAP bietet für diese Art Texte keine standardi-
sierte Ablagemöglichkeit, wie für Standard-Texte oder Textobjekte, gleichwohl
existieren Werkzeuge, um diese Texte zu bearbeiten. ABAP-Programme selbst
187
4.1 Textobjekte mit Formatierungen
sind ein Beispiel für diese Texte. Formatierungen gleich welcher Art sind in Pro-
grammtexten unüblich und werden auch nicht vorgenommen.
Der Schwerpunkt dieses Kapitels liegt auf der Arbeit mit Textobjekten. Es wird
gezeigt, wie vom Benutzer Textobjekte im Dialog bearbeitet werden können.
Weiterhin wird dargestellt, wie Textobjekte in der Datenbank gespeichert oder
aus der Datenbank gelesen werden können. Eine Zusammenfassung der Funk-
tionsbausteine, die hierfür verwendet werden, findet sich am Ende dieses
Kapitels. Für die Speicherung nicht-formatierter Texte stehen in R/3 keine
derartigen Strukturen bereit, wohl aber zum Bearbeiten der Texte in Dialog-
transaktionen. Der Programmierer ist in der Regel selbst für die Datenhaltung
und –speicherung verantwortlich.
Tabelle 4.1
Aufbau der Struktur TLINE
In der Spalte TDLINE der Struktur ist die Textinformation der Zeile abgelegt.
Hierfür stehen maximal 132 Zeichen zur Verfügung. Die Textzeile kann – neben
dem eigentlichen Text – auch Zeichenformatierungen, wie im – dem Textobjekt
zugeordneten - Textstil definiert, enthalten. Absatzformatierungen hingegen
werden nicht im Feld TDLINE abgelegt sondern in der eigens hierfür vorhande-
nen Spalte TDFORMAT. Auch die in dieser Spalte verwendeten Formatierungen
müssen zuvor im verwendeten Textstil definiert werden. Der Textstil in SAP-
Textobjekten ist vergleichbar mit den Formatierungen in der Formatvorlage von
Office-Anwendungen. Während diese jedoch in der Regel auch die Seitenfor-
matierungen beinhalten, werden diese innerhalb von SAPScript in den Formu-
laren definiert. Einem Textobjekt liegt neben dem Stil also immer auch ein For-
mular zugrunde.
188
Neben den eigentlichen Textzeilen gehört zu jedem Textobjekt eine Kopfstruk-
tur, in der die Verwaltungsinformationen zum Textobjekt abgelegt sind. Diese
Struktur ist ebenfalls im Data Dictionary definiert und unter dem Namen THEAD
abgelegt (siehe Tabelle 4.2).
189
4.1 Textobjekte mit Formatierungen
Tabelle 4.2
Aufbau der Struktur THEAD
Über die ersten vier Felder dieser Struktur werden Textobjekte in R/3 eindeutig
identifiziert. Im Feld TDOBJECT wird das Anwendungsobjekt zu dem das Textob-
jekt gehört abgelegt. Standardtexte enthalten hier beispielsweise den Wert
»TEXT«, Langtexte zu Aufträgen den Wert »AUFK«. Die möglichen Werte für
das Feld TDOBJECT sind in der Tabelle TTXOB im R/3-System hinterlegt.
Das Feld TDNAME enthält den Namen des Textobjektes. Bei Standardtexten kann
dieser vom Benutzer selbst definiert werden. Bei Texten, die zu anderen An-
wendungsobjekten gehören, wird dieser Name vom System generiert und ent-
hält in der Regel den Primärschlüssel des Anwendungsobjektes.
Das dritte Feld, über das Textobjekte unterschieden werden, ist das Feld TDID. Es
ermöglicht eine weitere Kategorisierung. Die möglichen Werte für dieses Feld
sind – abhängig vom Inhalt des Feldes TDOBJECT – in der Tabelle TTXID definiert.
Textobjekte werden im System sprachabhängig definiert. Hierzu wird das vier-
te Schlüsselfeld der Header-Struktur verwendet. Im Feld TDSPRAS wird hierzu
der Sprachschlüssel des Textobjektes abgelegt.
Die weiteren Felder der Struktur sind die Verwaltungsfelder zum Textobjekt.
Dem Feld TDTITLE, in dem der Titel des Textes abgelegt wird, folgen die Felder
TDFORM und TDSTYLE, die den Namen des SAPScript-Formulars und des
SAPScript-Textstils enthalten. Im Textstil werden sowohl die Absatz- als auch
die Zeichenformate, die im Textobjekt verwendet werden können, definiert. Im
Formular wird weiterhin der Seitenaufbau, mit dem das Textobjekt dargestellt
werden soll, festgelegt. Genauere Informationen zu den Konzepten von
SAPScript kann der Dokumentation zum System R/3 entnommen werden.
Im Feld TDVERSION wird die Versionsnummer des Textobjektes abgelegt. Nach ih-
rer Erzeugung ist in diesem Feld der Wert 1 enthalten. Mit jeder Änderung des
Textobjektes wird der Inhalt dieses Feldes um eins erhöht. Daran schließen sich
190
vier Felder an, um den Benutzer sowie das Datum und die Uhrzeit der Texter-
stellung festzuhalten (TDFUSER, TDFDATE, TDFTIME). Weiterhin wird der R/3-Relea-
sestand der Texterstellung im Feld TDFRELES abgelegt (die R/3-Version 4.6C wür-
de durch die Zeichenkette »46C« dargestellt). Die gleichen vier Felder, mit dem
einzigen Unterschied, dass das »F« im Feldnamen durch ein »L« ersetzt wurde,
folgen im Anschluss, um die entsprechenden Informationen für die letzte Ände-
rung des Textobjektes festzuhalten.
Zuletzt von Bedeutung für den Programmierer sind die Felder TDLINESIZE sowie
TDTXTLINES. Im ersteren ist die Zeilenbreite im Editor für jede Zeile des Textes ab-
gelegt. Das Feld TDLINE der Struktur TLINE ist immer 132 Stellen breit. In vielen
Fällen erlaubt die Anwendung allerdings nicht so viele Stellen. Aus diesem
Grund kann die Zeilenbreite über das Feld TDLINESIZE auf die – aus Anwen-
dungssicht gewünschte – Breite gesetzt werden. Beim Speichern des Textobjek-
tes wird vom System im Feld TDTXTLINES die aktuelle Anzahl Zeilen im Textob-
jekt abgelegt.
Im Feld TDHYPHENAT wird ein Kennzeichen für den Editor geführt, ob die Silben-
trennung im Textobjekt aktiv sein soll (»X«) oder nicht (Space).
Das Feld TDOSPRAS enthält das Sprachkürzel der Sprache, in der das Textobjekt
ursprünglich angelegt wurde. Falls es sich bei dem Textobjekt um eine Überset-
zung eines bestehenden Textes handelt, enthält dieses Feld das Sprachkennzei-
chen der Originalsprache und das Feld TDSPRAS das Sprachkürzel für die aktuelle
Sprache des Textobjekts. Der Status der Übersetzung ist im Feld TDTRANSTAT ab-
gelegt.
Die Felder TDMACODE1 sowie TDMACODE2 enthalten weitere Kurztitel, die zum jewei-
ligen Textobjekt abgelegt bzw. angezeigt werden sollen.
Ein Textobjekt in R/3 kann ein anderes Textobjekt referenzieren. Diese Referenz
wird in den Feldern TDREFOBJ, TDREFNAME, TDREFID der Kopfstruktur abgelegt. Die
Sprache des referenzierten Textobjektes ist immer die Sprache des referierenden
Objektes, d.h. der Inhalt des Feldes TDSPRAS.
Schließlich befinden sich in der Struktur THEAD noch der Mandant, in dem das Kapitel 4 – Arbeiten mit Texten
Textobjekt existiert sowie drei weitere Felder, die für die Verarbeitung des Text-
objektes in SAPScript verwendet werden.
Im SAPScript-Editor können die Kopfinformationen zum jeweiligen Textobjekt
angezeigt werden (siehe Abbildung 4.1). Das dargestellte Dynpro enthält die
meisten Felder der Struktur THEAD. Dem Dynpro kann auch entnommen werden,
dass nicht alle Felder zwangsweise Eingaben enthalten müssen. Im dargestell-
ten Beispiel wird lediglich ein Formular zum Textobjekt definiert, nicht jedoch
ein expliziter Textstil.
191
4.1 Textobjekte mit Formatierungen
Abbildung 4.1
Textkopf eines SAP-Standardtextes (© SAP AG)
READ_TEXT
Der Funktionsbaustein READ_TEXT ist der allgemeine Baustein, um Textobjekte
aus der Datenbank zu lesen. Die Schnittstelle des Funktionsbausteins enthält
alle Felder, um einen beliebigen Textbaustein im System eindeutig zu identifi-
zieren. Falls der spezifizierte Textbaustein nicht vorhanden ist, bricht der Funk-
tionsbaustein mit einer Exception ab.
FUNCTION READ_TEXT
IMPORT
CLIENT
ID
LANGUAGE
NAME
OBJECT
192
ARCHIVE_HANDLE
LOCAL_CAT
EXPORT
HEADER
TABLES
LINES
EXCEPTIONS
ID
LANGUAGE
NAME
NOT_FOUND
OBJECT
REFERENCE_CHECK
WRONG_ACCESS_TO_ARCHIVE.
Im Parameter CLIENT wird dem Funktionsbaustein der Mandant, aus dem der
Text gelesen werden soll, übergeben. Mit dem Funktionsbaustein können Text-
objekte also auch mandantenübergreifend gelesen werden. Wird dieser Para-
meter nicht versorgt, wird als Defaultwert der aktuelle Mandant angenommen.
Die folgenden vier Parameter ID, LANGUAGE, NAME sowie OBJECT sind die Felder, die
das Textobjekt innerhalb des Mandanten eindeutig beschreiben. Hier werden
keine Standard-Werte vom Funktionsbaustein angenommen, so dass alle vier
Felder explizit beim Aufruf des Funktionsbausteins übergeben werden müssen.
Im Rahmen der Archivierung können Textobjekte bereits aus dem R/3-System
gelöscht und lediglich im Archiv-System vorhanden sein. Der Funktionsbau-
stein bietet auch die Möglichkeit, Textobjekte aus dem Archiv zu lesen, indem
im Parameter ARCHIVE_HANDLE eine aktuelle Zugriffsnummer für das Archiv
übergeben wird. Diese Zugriffsnummer liefert der Funktionsbaustein
ARCHIVE_OPEN_FOR_READ zurück. Er öffnet eine bestimmte Archiv-Datei und liefert
eine Zugriffsnummer, die bei jedem Lesevorgang aus dem Archiv mitgegeben
werden muss, zurück. Wird an READ_TEXT eine Zugriffsnummer übergeben, die
nicht zu einer aktuell geöffneten Archiv-Datei gehört, wird die Ausnahme
WRONG_ACCESS_TO_ARCHIVE ausgelöst.
Kapitel 4 – Arbeiten mit Texten
Neu hinzugekommen bei fast allen Funktionsbausteinen der Funktionsgruppe
STXD ist der Parameter LOCAL_CAT. Wird hier ein »X« an den jeweiligen Funktions-
baustein übergeben, werden lokale Kataloge für den Zugriff auf die Textobjekte
verwendet. Ein lokaler Katalog wird innerhalb der Grenzen des aktuellen inter-
nen Modus angelegt. In einem internen Modus kann jedoch nur einen lokalen
Katalog existieren. Wird versucht, einen weiteren internen Katalog anzulegen,
lehnt der Funktionsbaustein die Verarbeitung ab. Weiterhin gilt, dass alle Zu-
griffe auf Funktionen der Funktionsgruppe STXD den gleichen Wert im Parame-
ter LOCAL_CAT verwenden müssen. Wird ein Funktionsbaustein mit dem Wert
»X« in LOCAL_CAT aufgerufen, obwohl zuvor ein Funktionsbaustein ohne diesen
Wert aufgerufen wurde, bricht die Transaktion mit der Abbruchmeldung A239
ab.
193
4.1 Textobjekte mit Formatierungen
Die Dokumentation dieses Konzeptes in R/3 ist allerdings sehr verwirrend, von
daher sollte vorher genau überlegt werden, ob in eigenen Programmen auf diese
Funktionalität zurückgriffen werden soll.
Die Rückgabewerte des Funktionsbausteins sind die Kopfstruktur des Text-
objekts im Parameter HEADER sowie die Zeilen des Textobjekts in Form einer
internen Tabelle im Parameter LINES.
READ_STDTEXT
Der Funktionsbaustein READ_STDTEXT bietet ein vereinfachtes Interface, um Stan-
dardtextobjekte zu lesen. Standardtexte sind dadurch gekennzeichnet, dass sie
keinem Anwendungsobjekt des R/3-Systems zugeordnet sind, und sie enthal-
ten im Feld TDOBJECT der Kopfstruktur immer den Wert »TEXT«. Da der Name
Standard-Text bereits nahe legt, dass es sich hierbei um in der Regel unverän-
derliche Texte handelt, bietet der Funktionsbaustein READ_STDTEXT einen Durch-
griff auf den Mandanten 000 des Systems, in dem die allgemeine Version des
Textobjekts definiert werden kann.
FUNCTION READ_STDTEXT
IMPORT
ID
LANGUAGE
NAME
USE_AUX_LANGUAGE
USE_THRUCLIENT
LOCAL_CAT
EXPORT
HEADER
TABLES
LINES
EXCEPTIONS
ID
LANGUAGE
NAME
NOT_FOUND
REFERENCE_CHECK.
194
nativsprachen, die für diesen Zugriff in Frage kommen, werden in der Tabelle
T002C definiert.
Für den Parameter LOCAL_CAT gelten die gleichen Aussagen, wie beim Funktions-
baustein READ_TEXT.
Auch der Funktionsbaustein READ_STDTEXT liefert im Erfolgsfall die Kopfstruktur
des gelesenen Textobjektes im Parameter HEADER und die Zeilen in Form einer
internen Tabelle im Parameter LINES.
195
4.1 Textobjekte mit Formatierungen
196
Abbildung 4.2 Screen-Shot des Fullscreen-Editors im Release 4.6 (© SAP AG)
197
4.1 Textobjekte mit Formatierungen
WINDOW
SAVE
LINE_EDITOR
CONTROL
PROGRAM
LOCAL_CAT
EXPORT
FUNCTION
NEWHEADER
RESULT
TABLES
LINES
EXCEPTIONS
ID
LANGUAGE
LINESIZE
NAME
OBJECT
TEXTFORMAT
COMMUNICATION.
In den Parametern HEADER und LINES wird dem Funktionsbaustein das zu bear-
beitende Textobjekt übergeben. Somit wird auch festgelegt, welches SAPScript-
Formular und welcher Textstil zur Bearbeitung verwendet werden soll (siehe
Kopfstruktur).
Über den Parameter DISPLAY kann gesteuert werden, ob der Text im Editor edi-
tierbar ist oder nur zur angezeigt werden soll. Wird hier ein »X« übergeben,
kann der Text vom Benutzer nicht geändert werden. Im Editor sind dann die
Funktionscodes zum Sichern des Textes deaktiviert.
Über den Parameter LINE_EDITOR kann festgelegt werden, ob der Editor im PC-
Modus (Space) oder im Zeilenmodus (»X«) gestartet werden soll.
Für die Aufbereitung des Textobjektes im Editor ist es relevant, für welche Seite
bzw. welches Seitenfenster innerhalb des verwendeten Formulars der Text ge-
dacht ist. Diese werden in den Parametern PAGE bzw. WINDOW an den Editor über-
geben.
Innerhalb des Fullscreen-Editors kann der Benutzer, je nach Aufrufmodus, den
veränderten Text über die »Sichern«-Schaltfläche abspeichern. Über den Para-
meter SAVE des Funktionsbausteins EDIT_TEXT kann dabei gesteuert werden, ob in
diesem Fall der Funktionsbaustein das Sichern in der Datenbank durchführen
soll (»X«), ober ob dies dem rufenden Programm obliegt (Space). Beim Betätigen
der »Sichern«-Schaltfläche wird der Editor auf jeden Fall verlassen und der ver-
änderte Text dem rufenden Programm in den entsprechenden Parametern NEW-
HEADER und LINES zurückgeliefert. Während jedoch im ersten Fall das Textobjekt
auch innerhalb des Funktionsbausteins in der Datenbank gespeichert wird,
198
muss dies im letzteren Fall immer vom rufenden Programm durchgeführt wer-
den. Dies ist insbesondere beim Anlegen neuer Anwendungsobjekte sinnvoll,
deren Erzeugung auch nach Pflege des dazugehörigen Textobjektes vom An-
wender ohne zu sichern abgebrochen werden kann.
Die Steuerung des Editors erfolgt über eine Struktur, die im Parameter CONTROL
an den Funktionsbaustein EDIT_TEXT übergeben wird. Sie hat den Aufbau der
Data Dictionary-Struktur ITCED, die in Tabelle 4.3 dargestellt ist.
EXIT_SYMB CHAR 30 Name des Funktionsbausteins für Exit-Routine Kapitel 4 – Arbeiten mit Texten
Tabelle 4.3
Aufbau der Struktur ITCED
199
4.1 Textobjekte mit Formatierungen
Feldname Bedeutung
Tabelle 4.4
Bedeutung der Felder im zusammengesetzten Editor-Titel
Wird im Feld SCROLLEND der Struktur der Wert »X« übergeben, wird der Einga-
becursor beim Betreten des Editors an das Ende des Textes gesetzt. Der Editor
scrollt in diesem Moment so, dass das Textende im Fenster des Editors sichtbar
ist.
Der SAPScript-Editor bietet für die Bearbeitung von Textobjekten eine Reihe
von GUI-Oberflächen mit unterschiedlichen Verarbeitungsmöglichkeiten an.
Welche der TextEditor-Oberflächen im Einzelfall verwendet wird, hängt vom
200
Objekttyp (TDOBJECT) des jeweiligen Textobjektes ab. In der Transaktion SE75
kann je Textobjekt das zu verwendende GUI festgelegt werden. Weiterhin kann
hier auch der Verbuchungsmodus sowie das zu verwendende SAPScript-For-
mular und –stil definiert werden. Wird für den Objekttyp des Textobjekts der
GUI-Status TA festgelegt, können bei Bedarf Buttons in der Schaltflächenleiste
des Editors angezeigt werden, um zum nächsten bzw. vorigen zu editierenden
Text zu verzweigen. Die Sichtbarkeit dieser Schaltflächen wird über die beiden
Felder APP_NEXT bzw. APP_PREV der Struktur ITCED an den Editor übergeben. Ein
»X« im jeweiligen Feld besagt, dass die dazugehörige Schaltfläche im GUI des
Editors angezeigt wird.
Über das Feld APP_SUBID kann der in der Transaktion SE75 definierte GUI-Status
explizit vom Programmierer übersteuert werden. Ansonsten gilt dabei die glei-
che Logik, wie bei der Ermittlung des konkreten GUI-Status bei Verwendung
des Feldes der Tabelle TTXOB (SE75).
Das Feld CHANGEMODE der Struktur ITCED legt fest, ob der Benutzer im Editor von
der Anzeige in den Editormodus wechseln kann oder umgekehrt. Dieser Wech-
sel ist möglich, wenn in diesem Feld der Wert »X« an den Funktionsbaustein
übergeben wird.
Innerhalb von Textobjekten können Symbole verwendet werden, die zur Lauf-
zeit durch die Inhalte von Variablen aus dem Programmkontext ersetzt werden.
Um für die Druckausgabe bzw. die Druckvorschau des Textobjekts im Editor
die Ersetzung durchführen zu können, benötigt der Editor den Namen des Pro-
gramms, aus dessen globalem Datenbereich die Variablen für die Symbolerset-
zung entnommen werden. Der Name dieses Programmes kann dem Editor im
Parameter PROGRAM übergeben werden. Wird dieser Wert nicht gesetzt, nimmt
das System hierfür den Inhalt der Systemvariable SY-CPROG, welches das laufen-
de ABAP-Programm auf höchster Ebene enthält.
Nach Beendigung des Editors enthält der Rückgabeparameter FUNCTION die im
Editor durchgeführte Aktion. Hierbei können die in Tabelle 4.5 dargestellten
Werte vorkommen.
Kapitel 4 – Arbeiten mit Texten
Wert Bedeutung
Tabelle 4.5
Mögliche Rückgabewerte des SAPScript-Editors im Feld FUNCTION
Neben der Kopfstruktur des Textbausteins nach der Bearbeitung (NEWHEADER) lie-
fert der Funktionsbaustein weiterhin eine Struktur zurück, die dem Programm
201
4.1 Textobjekte mit Formatierungen
anzeigt, auf welche Weise der Editor vom Benutzer verlassen wurde (RESULT).
Der Rückgabeparamter RESULT hat hierbei den Aufbau der Dictionary-Struktur
ITCER, wie er in Tabelle 4.6 dargestellt ist.
Tabelle 4.6
Aufbau der Struktur ITCER
Im Feld USEREXIT der Struktur wird zurückgegeben, auf welche Weise der Editor
verlassen wurde. Mögliche Werte für dieses Feld sind in Tabelle 4.7 angegeben.
Wert Bedeutung
Tabelle 4.7
Mögliche Werte des Feldes USEREXIT der Struktur ITCER
Im Feld FUNCTION der Struktur wird der Inhalt des Rückgabeparamters FUNCTION
des Funktionsbausteins wiederholt. Schließlich enthält das Feld PCEDITOR der
Struktur nach Beendigung des Editors den Wert »X«, wenn beim Verlassen des
Editors der PC-Editor aktiv war. Hat der Benutzer zuletzt mit dem Zeileneditor
gearbeitet, enthält dieses Feld keinen Wert.
202
Normalerweise werden die Einträge in den Transportaufträgen für Textobjekte
– so wie bei Entwicklungsobjekten auch – automatisch vom System generiert. In
seltenen Fällen ist es jedoch notwendig, diese Einträge manuell zu erstellen.
Im Folgenden soll exemplarisch gezeigt werden, wie ein Transportauftrag zum
Transport von Textobjekten erstellt werden kann.
Im ersten Schritt wird hierzu ein Customizing-Auftrag erstellt. Dies erfolgt in
der Transaktion SE01 (Transport Organizer). Die Nummernvergabe für Trans-
portaufträge erfolgt stets intern. Im Einstiegsbild der Transaktion wird ein
Transportauftrag mit der ANLEGEN-Schaltfläche erstellt und im darauf folgen-
den Fenster die Option »Customizing-Auftrag« ausgewählt (siehe Abbildung
4.3).
Abbildung 4.3
Transport Organizer (SE01) beim Anlegen eines neuen Auftrags (© SAP AG)
Im Folgenden erscheint eine Maske, in der eine Beschreibung für den Transport-
auftrag erfasst werden muss, bevor der Benutzer in die Übersichtsmaske ge-
langt. Um Textobjekte zu transportieren, müssen manuell die entsprechenden
Einträge in der Objektliste des Auftrags vorgenommen werden. In der Objekt-
liste des Auftrags muss ein Eintrag, wie in Abbildung 4.4 beispielhaft darge-
stellt, getätigt werden. Die manuell getätigten Einträge müssen gesichert wer-
den und anschließend kann der Transportauftrag freigegeben und exportiert
werden.
203
4.2 Verwendung von Textobjekten
Einträge zum Transport von Textobjekten müssen zur Programm-ID R3TR und
dem Objekttyp TEXT erfolgen. Der Objektname setzt sich für Textobjekte aus
einer durch Komma getrennten Liste der vier Schlüsselfelder für Textobjekte
zusammen.
Insgesamt haben Einträge in Transportaufträgen für Textobjekte den Aufbau:
R3TR TEXT <OBJECT>,<NAME>,<ID>,<LANGUAGE>
Hierbei muss beachtet werden, dass das Sprachkennzeichen nicht bei der An-
meldung mit zwei Zeichen angegeben wird, sondern lediglich mit der bisher
verwendeten einstelligen Darstellung.
Abbildung 4.4
Eintrag in der Objektliste zum Transport von Textobjekten (© SAP AG)
204
bige Textobjekte integriert werden und bieten als grundlegende Eigenschaft,
dass beim Lesen ggf. ein Mandantendurchgriff in den Mandanten 000 des Sys-
tems erfolgen kann.
4.2.2 Standardtexte
Standardtexte sind Textbausteine, die im R/3-System hinterlegt werden kön-
nen, um die Erstellung von Dokumenten zu erleichtern und zu standardisieren.
Standardtexte zeichnen sich dadurch aus, dass Sie zum Objekttyp »TEXT« an-
gelegt sind. Ansonsten handelt es sich hierbei um Textobjekte, wie zuvor be-
schrieben. Lediglich im Bereich der Funktionen bieten Standardtexte dem Pro-
grammierer erweiterte Möglichkeiten.
Textobjekte sind – wie in Abschnitt 4.1.1 gezeigt – mandantenabhängig. Viele
der Textbausteine, die im System verwendet werden, können jedoch mandan-
tenübergreifend in mehreren Einheiten eines Konzerns gültig sein. Um den Auf-
wand für die Textpflege – die Texte sind schließlich das, was die Geschäftspart-
ner eines Unternehmens in Form der Korrespondenz erhalten – möglichst Kapitel 4 – Arbeiten mit Texten
gering zu halten, bieten die Standardtexte die Möglichkeit, eine allgemein gül-
tige Version des Textes im Mandanten 000 des jeweiligen Systems anzulegen
und lediglich von der Standardformulierung abweichende Versionen in den
einzelnen aktiven Mandanten des Systems vorzuhalten.
Wie in Abschnitt 4.1.2 gezeigt, steht für das Lesen von Standardtexten ein leis-
tungsfähiger Funktionsbaustein READ_STDTEXT zur Verfügung, der bei Bedarf ver-
sucht ein Textobjekt in einer alternativen Sprache oder eben – wie beschrieben –
aus dem Mandaten 000 zu lesen.
Hierdurch können im Bereich der Textpflege hohe Kosten gespart werden und
eine wichtige Fehlerquelle bei der Erstellung der Geschäftskorrespondenz aus-
geschlossen werden.
205
4.3 Texte ohne Formatierungen
206
Abbildung 4.5
SAP TextEdit auf Tab-Strip-Seite (© SAP AG)
Wie bereits erwähnt handelt es sich beim SAP TextEdit um ein weiteres Control
aus dem mit Release 4.6 eingeführten Control Frameworks. Analog zur neuen
Baumdarstellung (SAPTree) handelt es sich bei der Instanz der Klasse
CL_GUI_TextEdit, welche in diesem Zusammenhang zum Zuge kommt, lediglich
um eine programminterne Repräsentation für das Control selbst, welches Re-
mote auf dem Präsentationsrechner des Benutzers entweder im SAPGUI oder in
der Browserdarstellung abläuft. Die Implementierung des Controls selbst, ist
entweder als ActiveX auf den Microsoft-Plattformen, oder in Form von Java-
Beans auf den übrigen Plattformen realisiert. Die Kommunikation des Controls
207
4.3 Texte ohne Formatierungen
selbst mit seiner Repräsentation im ABAP erfolgt über verschiedene Klassen des
Control Frameworks.
Für den Programmierer ist der Unterschied zwischen einem TreeView und
einem TextEdit lediglich im ABAP-Programm selbst, nicht jedoch im Dynpro-
Editor relevant. In beiden Fällen läuft das Control in einem Container, der im
Dynpro-Editor in Form einer Customer-Area realisiert wird.
Das TextEdit ist für den Benutzer erheblich komfortabler zu benutzen, als der
bisher bekannte Zeileneditor. Wird das TextEdit im »Bearbeiten«-Modus (auch
eine reine Textanzeige ist möglich) dargestellt, stehen die aus den bekannten
Desktop-Anwendungen gewohnten Funktionalitäten wie
◗ Einfüge-/Überschreibmodus,
◗ Textauswahl mit Maus und Tastatur,
◗ Ausschneiden/Kopieren/Einfügen,
◗ Suchen/Ersetzen,
◗ Widerrufen sowie auf Wunsch ein
◗ Automatischer Zeilenumbruch
zur Verfügung.
Weiterhin kann die maximale Textlänge in Zeichen gesetzt sowie das Laden
und Speichern in lokalen Dateien optional vom Control angeboten werden.
In der Darstellung besitzt das TextEdit in der Regel eine Toolbar mit Schaltflä-
chen für die oben genannten Funktionen oberhalb des Eingabebereiches sowie
eine Statuszeile unterhalb des Eingabebereichs. In der Statuszeile werden Infor-
mationen über den aktuellen Text sowie der Status des Editors selbst dargestellt
(siehe Abbildung 4.5). Weiterhin können beliebige Nachrichten für den Benut-
zer im Bereich der Statuszeile ausgegeben werden.
Sowohl die Ausgabe der Toolbar als auch die der Statuszeile ist optional und
können bei Bedarf vom Programmierer unterdrückt werden. Das TextEdit
besteht in diesem Fall lediglich aus dem Eingabebereich. Diese Form der Dar-
stellung wird auch häufig in den Standard-Transaktionen des R/3-Systems
verwendet. SAP verzichtet oft zugunsten einer geringeren Anzahl von Bild-
wechseln auf die Möglichkeit, innerhalb der Langtexte zu den Anwendungsob-
jekten Formatierungen zuzulassen.
208
In den Eigenschaften der neuen Seite wird die Beschriftung des Tab-Reiters, so-
wie der Funktionscode, der beim Betätigen des Reiters ausgeführt wird, defi-
niert. Je nach verwendetem Blättertyp des Tab-Strips handelt es sich hierbei um
einen Funktionscode, der lokal im SAPGUI des Benutzers verarbeitet werden
soll (Funktionstyp »P«) oder um einen Funktionscode, der ein PAI/PBO-Ereig-
nispaar auslöst und somit das Blättern auf dem Applikationsserver realisieren
lässt (Funktionstyp » «). Detaillierte Informationen zu den Funktionstypen und
den Seitenwechseln in Tab-Strips kann Kapitel 3.2 entnommen werden.
Im Anschluss daran muss die neue Tab-Seite in die Ablauflogik des Dynpros
aufgenommen werden. Es wird davon ausgegangen, dass die neue Seite als
Subscreen mit der Dynpro-Nummer 9400 im Modulpool angelegt wird.
Beim Blättern im SAPGUI geschieht dies durch Hinzufügen der jeweiligen CALL
SUBSCREEN-Anweisung sowohl im PBO als auch PAI des Dynpros. Beim Blättern
auf dem Applikationsserver entsprechend durch Reagieren auf den Funktions-
code für die neue Tab-Seite und umsetzten der aktiven Seite in den globalen
Datenfeldern des Programms.
Auf eine Darstellung des Codes wird hier verzichtet, da dieser analog zu dem
bereits in Kapitel 3 gezeigten Anweisungen ist.
Abbildung 4.6
Eigenschaften des Containers für das TextEdit-Control (© SAP AG)
209
4.3 Texte ohne Formatierungen
Nun muss noch das neue Dynpro mit der Dynpro-Nummer 9400 im Modulpool
angelegt werden, um das Programm wieder in einen funktionsfähigen Zustand
zu versetzten.
Als letzte Aktion – um die Arbeiten im Dynpro-Editor zu vervollständigen –
muss schließlich noch die Custom Control-Area auf dem gerade erstellten Sub-
screen angelegt werden.
In den Eigenschaften des Custom Controls ist neben der Größe des Bereichs auf
dem Dynpro, lediglich der Name des Controls, welcher im ABAP-Programm
verwendet wird, um auf den Bereich zuzugreifen, zu pflegen. Im obigen Bei-
spiel (Abbildung 4.6) wurde hier der Name TextEdit verwendet.
Nachdem die geänderten Entwicklungsobjekte aktiviert wurden, kann die
Transaktion fehlerfrei ausgeführt werden. Der neue Tab-Reiter ist - wie definiert
– vorhanden und die neue Seite, zeigt einen dunklen Bereich an der Stelle in der
Maske, an der später das TextEdit-Control zu sehen sein wird.
In der Ablauflogik des neuen Dynpros werden die beiden neu deklarierten
Variablen initialisiert. Zunächst wird der Container, in dem das TextEdit dar-
gestellt werden soll, erzeugt. Dies erfolgt einmalig beim ersten Durchlaufen
des PBO im Module 9400_CREATE_CONTAINER.
MODULE 9400_CREATE_CONTAINER OUTPUT.
IF G_TEXTCONTAINER IS INITIAL.
* Erzeugen des Containers
CREATE OBJECT G_TEXTCONTAINER
EXPORTING
CONTAINER_NAME = 'TEXTEDIT'
EXCEPTIONS
CNTL_ERROR = 1
210
CNTL_SYSTEM_ERROR = 2
CREATE_ERROR = 3
LIFETIME_ERROR = 4.
ENDIF.
ENDMODULE. " 9400_create_container OUTPUT
Der erste Aufruf des PBO wird daran erkannt, dass die Variable G_TEXTCONTAINER
noch nicht initialisiert ist. Bei allen weiteren PBO-Aufrufen enthält diese Variab-
le eine Referenz auf die hier erzeugte Container-Instanz. Der Name »TEXTEDIT«
ist der im Dynpro-Editor vergebene Name für den Custom Control-Bereich.
Im Anschluss an den Container muss noch das TextEdit-Control selbst erzeugt
werden. Dies geschieht in einem eigenen Module 9400_CREATE_TEXTEDIT unter der
Voraussetzung, dass die vorherige Erzeugung des Containers fehlerfrei
geglückt ist.
MODULE 9400_CREATE_TEXTEDIT OUTPUT.
* Das Textedit soll nur erzeugt werden, wenn das Anlegen des
* Containers erfolgreich war.
CHECK NOT G_TEXTCONTAINER IS INITIAL.
211
4.3 Texte ohne Formatierungen
übergeben wird, ist als Pflichtparameter definiert. Die übrigen Parameter sind
optional und werden mit entsprechenden Defaultwerten übergeben.
Im Parameter MAX_NUMBER_CHARS wird die maximale Länge des Textes in Zeichen
übergeben. Hierüber kann verhindert werden, dass der Benutzer im Control
mehr Text erfasst, als tatsächlich in den dahinter liegenden Datenfeldern abge-
speichert werden kann. Wird – wie hier gezeigt – der Paramter nicht übergeben
bzw. der Wert »0« übergeben, besteht keine Längenbeschränkung im Text-Con-
trol und der Benutzer kann einen beliebig langen Text erzeugen.
Über den Parameter Style können Eigenschaften des Controls gesetzt werden.
Hierbei können die in der Klasse CL_GUI_CONTROL definierten Konstanten, deren
Name mit WS_ beginnt, verwendet werden. Mehrere dieser Werte können
durch einfache Addition der jeweiligen Konstanten kombiniert werden. Bei die-
sen Konstanten handelt es sich um Variable auf einer sehr technischen Ebene,
wie z.B. WS_CLIPCHILDREN, mit dem das Verhalten eines Fensters beim Überlappen
durch andere Fenster definiert werden kann. Das Setzten dieser Variable durch
den Programmierer wird in der Regel nicht notwendig sein, da R/3 standard-
mäßig eine, für das jeweilige Control passende, Einstellung annimmt.
Das SAP TextEdit kann auf Texteingaben, die die sichtbare Breite des Controls
überschreiten, auf unterschiedliche Weise reagieren. Das gewünschte Verhalten
wird dem Control über die Parameter WORDWRAP_MODE, WORDWRAP_POSITION sowie
WORDWRAP_TO_LINEBREAK_MODE beim Konstruktor-Aufruf übergeben. Der Parameter
WORDWRAP_MODE bestimmt hierbei das generelle Zeilenumbruch-Verhalten des
Controls. In der Klasse CL_GUI_TEXTEDIT sind hierfür drei Konstanten definiert,
die das unterschiedliche Verhalten festlegen. Diese sind in Tabelle 4.8 darge-
stellt.
Tabelle 4.8
Konstanten für den Parameter WORDWRAP_MODE des SAP TextEdit
212
Beim durch WORDWRAP_AT_WINDOWBORDER definierten Zeilenumbruchverhalten,
wird der Text beim Erreichen des rechten Randes des Text-Controls automa-
tisch umgebrochen. Je nachdem, wie groß das Textcontrol auf dem Dynpro dar-
gestellt wird, erfolgt der Zeilenumbruch an anderer Stelle. Diese Option eignet
sich besonders für Texte, die auch in anderen Zusammenhängen, wie zum Bei-
spiel beim Ausdruck verwendet werden. Da der Text auf dem Papier in der Re-
gel ohnehin anders umgebrochen werden muss, als auf dem Bildschirm, ist es
sogar sinnvoll, dieses vom jeweiligen Kontext abhängige Verhalten dem Benut-
zer zu visualisieren.
Soll der Text jedoch unabhängig vom verwendeten Zeichensatz und von der
jeweiligen Fensterbreite an einer festen Position umgebrochen werden, kann
dies durch Verwendung der Konstante WORDWRAP_AT_FIXED_POSITION erreicht
werden. In diesem – und nur in diesem Fall (!) – definiert der Parameter
WORDWRAP_POSITION die maximale Zeilenbreite in Zeichen. Bei den anderen Zeilen-
umbruchmodi hat dieser Parameter keine Funktion.
Schließlich hat noch der Parameter WORDWRAP_TO_LINEBREAK_MODE des Konstruktors
die Funktion festzulegen, ob beim Auslesen des Textes aus dem Zwischenspei-
cher des Controls Zeilenumbrüche in tatsächliche Zeilenumbrüche umgewan-
delt (auch »harte« Zeilenumbrüche genannt) werden, wie sie auch das Betätigen
der (¢)-Taste während der Eingabe erzeugen, oder ob die auomatisch erzeug-
ten Zeilenumbrüche beim Auslesen nicht berücksichtigt werden (»weicher«-
Zeilenumbruch). Im letzteren Fall werden alle Zeilen bis zum nächsten »harten«
Zeilenumbruch logisch als eine Einheit (Zeile) behandelt. Bei erneuter Ausgabe
in einem schmaleren oder breiteren Eingabefenster würden die Umbrüche in
diesem Fall neu ermittelt, während sie im ersten Fall durch den Text festgelegt
wären, da diese Zeilenumbrüche nicht mehr von denen, die explizit durch die
(¢)-Taste gesetzt wurden, unterschieden werden können.
Die durch diese drei Parameter gesetzten Werte für das Zeilenumbruchverhal-
ten können nachträglich durch einen Aufruf der Methode SET_WORDWRAP_BEHAVIOR
der Klasse CL_GUI_TEXTEDIT jederzeit verändert werden.
Über den Parameter FILEDROP_MODE kann das Drag&Drop-Verhalten des Controls Kapitel 4 – Arbeiten mit Texten
im GUI des Benutzers beeinflusst werden. Die Darstellung der Drag&Drop-
Funktionalitäten des Control Frameworks würden den Rahmen dieses Buches
sprengen. An dieser Stelle sei daher auf das Buch »Controls Technology« von
SAP verwiesen.
Der Parameter LIFETIME entspricht exakt dem gleichnamigen Parameter der
Klassen des SAP TreeView. Das Verhalten kann daher in Abschnitt 3.3 dieses
Buches nachgelesen werden. Über den Parameter NAME schließlich kann der
Instanz des Controls ein Name mitgegeben werden. Was dieser bewirkt, ist
im System jedoch nicht dokumentiert.
213
4.3 Texte ohne Formatierungen
METHOD SET_TEXT_AS_R3TABLE
IMPORTING
TABLE
EXCEPTIONS
ERROR_DP = 1
ERROR_DP_CREATE = 2.
Im Parameter TABLE werden die Zeilen der internen Tabelle übergeben. Hier-
bei spielt es keine Rolle, wie lange die Zeilen sind. Vor der Anzeige des Textes
im Editor wird dieser entsprechend den aktuell gesetzten Zeilenumbruchspara-
metern formatiert.
METHOD GET_TEXT_AS_R3TABLE
IMPORTING
ONLY_WHEN_MODIFIED
EXPORTING
TABLE
IS_MODIFIED
EXCEPTIONS
ERROR_DP = 1
ERROR_CNTL_CALL_METHOD = 2
ERROR_DP_CREATE = 3
POTENTIAL_DATA_LOSS = 4.
Auch bei der Methode GET_TEXT_AS_R3TABLE erfolgt der Transfer des Textes in
Form einer internen Tabelle. Hierbei ist zu beachten, dass die Zeilen des Editors
abgeschnitten werden, wenn ihre Länge die einer Zeile der internen Tabelle
überschreitet. In diesem Zusammenhang sei erwähnt, dass im Sinne des Text-
Edit-Controls eine Zeile immer durch einen »harten« Zeilenumbruch beendet
wird. Dieser wird gesetzt, wenn der Benutzer eine Zeile mit der (¢)-Taste ab-
214
schließt, oder wenn der Parameter WORDWRAP_TO_LINEBREAK_MODE des Controls auf
CL_GUI_TEXTEDIT=>TRUE gesetzt ist. Alle anderen Zeilenumbrüche, die der Benut-
zer im Editor sieht, sind so genannte »weiche« Zeilenumbrüche und werden
von den hier genannten beiden Methoden ignoriert. Für das Edit-Control kann
eine Zeile daher wesentlich länger sein, als es für den Benutzer im Editor
erscheint.
SAP empfiehlt, diese beiden Methoden nur im Zusammenhang mit der Zeilen-
umbruch-Methode WORDWRAP_AT_FIXED_POSITION zu verwenden. Bei den anderen
beiden Verfahren besteht nicht die Möglichkeit, eine maximale Zeilenlänge zu
definieren. Nur wenn die maximale Zeilenlänge bekannt ist, kann garantiert
werden, dass beim Auslesen des Textes keine Textinformationen verloren
gehen.
Die Methode GET_TEXT_AS_R3TABLE bietet weiterhin die Möglichkeit, den Text nur
dann vom Front-End des Benutzers auf den Server zu transferieren, wenn der
Benutzer Änderungen im Text vorgenommen hat. Hierfür steht der Parameter
ONLY_WHEN_MODIFIED zur Verfügung. Wird hier der Wert CL_GUI_TEXTEDIT=>TRUE
übergeben und der Text hat sich nicht geändert, wird der Text nicht übertragen
und im Parameter TABLE eine leere Tabelle zurückgeliefert. Um die Datenmenge,
die zwischen dem Applikationsserver und dem GUI übetragen werden müssen,
möglichst gering zu halten, ist die Verwendung dieses Parameters sehr anzu-
raten.
Aus dem Rückgabeparameter IS_MODIFIED kann zusätzlich erkannt werden, ob
sich der Text im Edit-Control geändert hat. Als Werte werden auch hier die, in
der Klasse CL_GUI_TEXTEDIT definierten, boolschen Konstanten verwendet.
215
4.3 Texte ohne Formatierungen
METHOD SET_TEXT_AS_STREAM
IMPORTING
TEXT
EXCEPTIONS
ERROR_DP = 1
ERROR_DP_CREATE = 2.
METHOD SET_READONLY_MODE
IMPORTING
READ_ONLY
EXCEPTIONS
ERROR_CNTL_CALL_METHOD = 1
INVALID_PARAMETER = 2.
Die Methode erhält lediglich einen Parameter, der den Editiermodus beschreibt.
Dieser kann den Wert CL_GUI_TEXTEDIT=>TRUE enthalten, wenn das Text-Control
den Text nicht veränderbar anzeigen soll. Der andere gültige Wert ist der in der
Klassenvariable CL_GUI_TEXTEDIT=>FALSE definierte Wert, der den Texteditor
anweist, den Text vom Benutzer bearbeitbar darzustellen.
Wird der Parameter nicht übergeben, wird der Wert TRUE angenommen und der
Text entsprechend lediglich angezeigt.
216
4.3.6 Ein-/Ausblenden der Toolbar und Statuszeile
Im einführenden Abschnitt dieses Kapitels wurde bereits erwähnt, dass beim
SAP Textedit-Control die Möglichkeit besteht, sowohl die Toolbar oberhalb, als
auch die Statuszeile unterhalb des Editierbereiches des Controls bei Bedarf aus-
zublenden.
Hierfür stehen in der Klasse CL_GUI_TEXTEDIT die Methoden SET_TOOLBAR_MODE
bzw. SET_STATUSBAR_MODE zur Verfügung.
METHOD SET_TOOLBAR_MODE
IMPORTING
TOOLBAR_MODE
EXCEPTIONS
ERROR_CNTL_CALL_METHOD = 1
INVALID_PARAMETER = 2.
METHOD SET_STATUSBAR_MODE
IMPORTING
STATUSBAR_MODE
EXCEPTIONS
ERROR_CNTL_CALL_METHOD = 1
INVALID_PARAMETER = 2.
Wie gezeigt, verfügen diese beiden Methoden über eine sehr ähnliche Schnitt-
stelle. Im einzigen Parameter der Methoden kann – wie bei der Methode
SET_READONLY_MODE – entweder der Wert CL_GUI_TEXTEDIT=>TRUE zum Anzeigen
bzw. CL_GUI_TEXTEDIT=>FALSE zum Verbergen der Toolbar bzw. der Statuszeile
übergeben werden.
Wenn die Statuszeile im Control sichtbar ist, besteht die Möglichkeit, dem
Benutzer hier Informationen anzuzeigen. Hierfür existiert die Methode
SET_STATUS_TEXT, die als einzigen Parameter den in der Statuszeile darzustellen-
den Text erhält.
METHOD SET_STATUS_TEXT Kapitel 4 – Arbeiten mit Texten
IMPORTING
STATUS_TEXT
EXCEPTIONS
ERROR_CNTL_CALL_METHOD = 1.
Der so gesetzte Text bleibt erhalten, bis er explizit durch einen weiteren Aufruf
dieser Methode oder implizit durch eine Systemmeldung ersetzt wird.
217
4.3 Texte ohne Formatierungen
218
METHOD SET_HIGHLIGHT_COMMENTS_MODE
IMPORTING
HIGHLIGHT_COMMENTS_MODE
EXCEPTIONS
ERROR_CNTL_CALL_METHOD = 1
INVALID_PARAMTER = 2.
Wird im Parameter FROM_LINE ein Wert kleiner als eins übergeben, wird mit der
ersten Zeile des Textes begonnen. Ebenso wird beim Parameter TO_LINE die letz-
te Zeile angenommen, wenn der übergebene Index größer ist als die Anzahl Zei-
len im Text.
Das TextEdit-Control bietet weiterhin die Möglichkeit, Zeilen gegen Eingaben
zu schützen. Auf dieses Feature wird hier jedoch nicht näher eingegangen. Mit
dem Parameter ENABLE_EDITING_PROTECTED_TEXT wird festgelegt, ob auch diese
Zeilen von der Auskommentierung betroffen sein sollen (CL_GUI_TEXTEDIT=>TRUE)
oder ob diese Zeilen bei der Verarbeitung ausgelassen werden sollen
Kapitel 4 – Arbeiten mit Texten
(CL_GUI_TEXTEDIT=>FALSE). Wird dieser Parameter nicht übergeben, wird als
Defaultwert der Wert FALSE angenommen, d.h. geschützte Zeilen werden nicht
mit dem Kommentarzeichen versehen.
Diese Methode wird verwendet, wenn Zeilen über ihre Zeilen-Indizes ange-
sprochen werden können. Mit der Methode COMMENT_SELECTION können die aktu-
ell ausgewählten Zeilen im Editor in Kommentarzeilen verwandelt werden. Die
Aufrufschnittstelle dieser Methode ist einfacher als die der Methode
COMMENT_LINES, da keine Zeilen-Indizes übergeben werden müssen.
219
4.3 Texte ohne Formatierungen
METHOD COMMENT_SELECTION
IMPORTING
ENABLE_EDITING_PROTECTED_TEXT
EXCEPTIONS
ERROR_CNTL_CALL_METHOD = 1.
Für den Parameter ENABLE_EDITING_PROTECTED_TEXT gilt das gleiche wie bei der
Methode COMMENT_LINES. Entsprechend werden geschützte Zeilen bei der Aktion
berücksichtigt, oder nicht.
Die Aufrufschnittstelle der Methode ist identisch mit der des Methode
COMMENT_LINES. Ebenso verhält es sich bei der Methode UNCOMMENT_SELECTION als
Gegenstück zur Methode COMMENT_SELECTION.
METHOD UNCOMMENT_SELECTION
IMPORTING
ENABLE_EDITING_PROTECTED_TEXT
EXCEPTIONS
ERROR_CNTL_CALL_METHOD = 1.
220
Weiterhin stellt das Control umfangreiche Methoden zur Verfügung, um wäh-
rend des Editiervorgangs aus ABAP heraus Einfluss auf das Control zu nehmen.
Bei diesen handelt es sich beispielsweise um Methoden, um die aktuelle Selek-
tion zu ermitteln bzw. zu setzten, Textzeilen einzurücken oder um eine Metho-
de zum Suchen und Ersetzen. Auch diese Methoden sollen hier jedoch nicht
näher betrachtet werden, da die benötigten Informationen, um diese Optionen
zu nutzen, ebenfalls leicht aus dem R/3-System entnommen werden können.
4.4.1 COPY_TEXTS
Mit dem Funktionsbaustein COPY_TEXTS können ein oder mehrere Textobjekte in-
nerhalb des R/3-Systems kopiert werden. Die Paramter SAVEMODE_DIRECT, INSERT
sowie LOCAL_CAT entsprechen denen des Funktionsbausteins SAVE_TEXT.
Zu beachten ist hierbei, dass Textobjekte, die zu betriebswirtschaftlichen An-
wendungsobjekten gehören ohne weiteres kopiert werden können. Allerdings
muss die Verknüpfung mit dem jeweiligen Anwendungsobjekt separat herge-
stellt werden. Der Funktionsbaustein COPY_TEXTS beinhaltet lediglich das Kopie-
ren selbst.
Import-Parameter
Kapitel 4 – Arbeiten mit Texten
SAVEMODE_DIRECT Kennzeichen, ob das Textobjekt sofort, d.h. synchron gespeichert
werden soll (»X«) oder im Rahmen der Verbuchung der LUW
(Space)
Export-Parameter
221
4.4 Verwendete und wichtige Funktionsbausteine
Tabellen-Parameter
Exceptions
Keine
Tabelle 4.9
Aufbau der Kopierstruktur ITCTC
4.4.2 DELETE_TEXT
Der Funktionsbaustein DELETE_TEXT löscht ein Textobjekt aus der Datenbank
oder dem lokalen Katalog. Das gewünschte Textobjekt wird über die Para-
meter des Funktionsbausteins eindeutig identifiziert. Wird im Parameter
SAVEMODE_DIRECT der Wert«X« übergeben, kann im Parameter TEXTMODE_ONLY fest-
gelegt werden, ob das Textobjekt in der Datenbank oder lediglich im lokalen
Katalog gelöscht werden soll.
222
Import-Parameter
CLIENT Mandant
Exceptions
4.4.3 EDIT_TEXT
Der Funktionsbaustein EDIT_TEXT ist die Aufrufschnittstelle für den R/3-Full-
screen-Editor. Dieser kann sich dem Benutzer entweder als Zeileneditor wie aus
älteren R/3-Releaseständen bekannt oder als moderner PC-Editor darstellen.
Beim PC-Editor erfolgt die Bearbeitung des Textes vollständig im GUI des Be-
nutzers. Eine Kommunikation mit dem Applikationsserver wird – bei den nor-
malen Editierfunktionen – nicht durchgeführt. Erst bei Beendigung des Editors
oder bei Veränderung einer Editor-Einstellung erfolgt das Auslösen der PAI/
PBO-Ereignisse.
Kapitel 4 – Arbeiten mit Texten
Import-Parameter
PAGE Seite im Formular, auf der der Text dargestellt werden soll
223
4.4 Verwendete und wichtige Funktionsbausteine
Export-Parameter
Tabellen-Parameter
Exceptions
COMMUNICATION Kommunikationsfehler
224
4.4.4 INIT_TEXT
Der Funktionsbaustein INIT_TEXT wird dazu verwendet, um die Arbeitsbereiche
für ein Textobjekt zu initialisieren. Die interne Tabelle mit den Textzeilen wird
gelöscht sowie die Kopfstruktur mit den bekannten Daten aus der Aufruf-
schnittstelle vorbelegt.
Import-Parameter
ID Text-ID
LANGUAGE Sprachkennzeichen
Export-Parameter
Tabellen-Parameter
Exceptions
ID Ungültige Text-ID
4.4.5 READ_STDTEXT
Kapitel 4 – Arbeiten mit Texten
Mit dem Funktionsbaustein READ_STDTEXT werden Textobjekte mit dem Objekt-
typ »TEXT« gelesen. Falls der gewünschte Textbaustein in der angegebenen
Sprache nicht vorhanden ist, wird bei Bedarf versucht, das Textobjekt in einer
Alternativsprache zu lesen. Scheitert auch dies, kann ein Mandantendurchgriff
auf den Mandanten 000 des Systems erfolgen, und dort ggf. auch auf das Text-
objekt in der Alternativsprache zugegriffen werden. Der Zugriff auf den Stan-
dardtext erfolgt somit maximal 4-stufig:
A Aktueller Mandant, gewünschte Sprache
B Aktueller Mandant, Alternativsprache
C Mandant 000, gewünschte Sprache
D Mandant 000, Alternativsprache
225
4.4 Verwendete und wichtige Funktionsbausteine
Import-Parameter
ID Text-ID (TDID)
Export-Parameter
Tabellen-Parameter
Exceptions
ID Ungültige Text-ID
4.4.6 READ_TEXT
Mit dem Funktionsbaustein READ_TEXT werden existierende Textobjekte aus
der Datenbank gelesen. Die Schnittstelle des Funktionsbausteins enthält alle Fel-
der, die ein Textobjekt in einem R/3-System eindeutig identifizieren.
Wird das Textobjekt nicht gefunden, bricht die Funktion mit einer Exception ab.
Import-Parameter
CLIENT Mandant
ID Text-ID (TDID)
226
NAME Name des Textobjekts (TDNAME)
Export-Parameter
Tabellen-Parameter
Exceptions
ID Ungültige Text-ID
4.4.7 SAVE_TEXT
Kapitel 4 – Arbeiten mit Texten
Mit der Funktion SAVE_TEXT werden Textobjekte in der Datenbank des R/3-Sys-
tems abgelegt. Es kann sich hierbei sowohl um neue Textobjekte als auch bereits
bestehende Texte handeln, die mit diesem Funktionsbaustein aktualisiert wer-
den.
Wenn nicht durch andere Mechanismen übersteuert, werden sämtliche Verwal-
tungsinformationen des zu speichernden Textobjekts aus der übergebenen
Kopfstruktur der Aufrufschnittstelle (HEADER) übernommen.
227
4.4 Verwendete und wichtige Funktionsbausteine
Import-Parameter
CLIENT Mandant
Export-Parameter
Tabellen-Parameter
Exceptions
228
Programmierung SAP-
Grafik
5
5.1 Allgemeines zur Grafik
Schon seit längerem besteht in R/3 die Möglichkeit, sowohl Geschäftsgrafiken
als auch Strukturgrafiken in die Anwendungen einzubeziehen. Bis zur Einfüh-
rung des Control Frameworks (siehe Kapitel 3) bestand jedoch lediglich die
Möglichkeit, Grafiken durch einen externen Viewer, der optisch an das bekann-
te SAPGUI angelehnt ist, anzuzeigen. Zur Erstellung dieser Grafiken standen
und stehen eine Reihe von Funktionsbausteinen zur Verfügung, deren Verwen-
dung hier auch gezeigt werden soll.
Der Schwerpunkt dieses Kapitels liegt jedoch in der neuen, auf dem Control
Framework basierenden Technik, Geschäfts- sowie Strukturgrafiken anzuzei-
gen. Da die grundlegenden Techniken der Programmierung von Geschäfts- und
Strukturgrafiken identisch sind, wird auf eine Darstellung von Strukturgrafiken
verzichtet. Der Leser kann sich das hierfür notwendige Wissen aus der Online-
Dokumentation zum Release 4.6 sowie dem R/3-System selbst erarbeiten.
Wichtiger sind hier die grundlegenden Techniken, deren Dokumentation im
System nur teilweise detailliert genug ist.
Die Beispielprogramme dieses Kapitels greifen wiederum auf die Tabellen aus
dem Flugbuchungssystem zurück. Für einen – im Beispiel fest vorgegebenen –
Flug sollen die Verteilung der Buchungen auf die einzelnen Klassen in Form ei-
ner Grafik dargestellt werden. Dies erfolgt zum einen als Balkengrafik der abso-
luten Werte, aber auch als Tortengrafik, um die Verteilung innerhalb des Fluges
darzustellen.
229
5.2 Grafiken über die Funktionsbausteinschnittstelle
230
FUNCTION GRAPH_2D
IMPORT
DISPLAY_TYPE
MAIL_ALLOW
SMFONT
SO_CONTENTS
SO_RECEIVER
SO_SEND
SO_TITLE
TITL
VALT
WINPOS
WINSZX
WINSZY
TABLES
DATA
EXCEPTIONS
GUI_REFUSE_GRAPHIC.
Mit den hier gezeigten Parametern kann eine Business-Grafik angezeigt wer-
den. Weiterhin kann die Grafik entweder automatisch oder vom Benutzer initi-
iert als Mail über SAPOffice, die Mailkomponente des Systems R/3 (siehe Kapi-
tel 10), versandt werden. Hierfür steht der Parameter MAIL_ALLOW sowie die
Parameter, die mit dem Präfix SO_ beginnen zur Verfügung.
Eine vollständige Darstellung der Aufrufschnitttstelle des Funktionsbausteins
GRAPH_2D ist am Ende des Kapitels in Abschnitt 5.8.1 zu finden.
* Tabellendeklarationen
TABLES SBOOK. "Flugbuchung
231
5.3 Geschäftsgrafiken mit GRAPH_2D
Der eigentliche Verarbeitungsteil des Programms besteht aus zwei Teilen. Zu-
nächst müssen die darzustellenden Informationen aus der Datenbank gelesen
werden und in der zuvor deklarierten internen Tabelle abgelegt werden.
Dies erfolgt mit einer SELECT-Anweisung auf die Tabelle SBOOK, wobei die Anzahl
der Buchungssätze zum gewünschten Flug, gruppiert nach der gebuchten Klas-
se, ermittelt werden.
START-OF-SELECTION.
* Datenbasis laden
SELECT CLASS COUNT(*)
INTO (G_DATA-CLASS, G_DATA-BOOKINGS)
FROM SBOOK
WHERE CARRID = C_CARRID AND
CONNID = C_CONNID AND
FLDATE = C_FLDATE
GROUP BY CLASS.
APPEND G_DATA.
ENDSELECT.
Zuletzt erfolgt die Anzeige der gelesenen Daten über den Funktionsbaustein
GRAPH_2D.
* Grafik anzeigen
CALL FUNCTION 'GRAPH_2D'
EXPORTING
* DISPLAY_TYPE = ' '
* SMFONT = ' '
TITL = 'Buchungen Flug AZ555 am 13.11.1999'
VALT = 'Gebuchte Plätze'
TABLES
DATA = G_DATA
EXCEPTIONS
GUI_REFUSE_GRAPHIC = 1
OTHERS = 2.
232
Im ersten Parameter des Bausteins wird der Typ der Geschäftsgrafik festgelegt,
der zur Anzeige verwendet werden soll. Die Aufrufschnittstelle von GRAPH_2D
definiert einen weiteren Parameter namens TYPE, mit dem dies auch möglich ist,
der aber laut SAP nicht für diesen Zweck verwendet werden soll. Tabelle 5.1
zeigt die für 2-dimensionale Geschäftsgrafiken zulässigen Werte des Para-
meters DISPLAY_TYPE.
DISPLAY_TYPE Grafik
VB Vertikale Balken
HB Horizontale Balken
TD Perspektivische Balken
VT Vertikale Dreiecke
ST Stufenlinien
MS Stufenflächen
LN Linien
SA Gestapelte Flächen
MA Maskierte Flächen
PI Tortendiagramm
TP Perspektivisches Tortendiagramm
PO Polardiagramm
Tabelle 5.1
Zulässige Grafiktypen für 2D-Geschäftsgrafiken
Über den Parameter SMFONT kann festgelegt werden, dass bei Bedarf eine kleinere
Schrift innerhalb der Darstellung der Grafik verwendet wird. In Versuchen mit
dem Funktionsbaustein konnte jedoch kein Unterschied bei der Verwendung
dieses Parameters festgestellt werden.
233
5.3 Geschäftsgrafiken mit GRAPH_2D
Abbildung 5.1
2D-Balkengrafik im externen Viewer (© SAP AG)
234
Abbildung 5.2
2D-Tortengrafik im externen Viewer (© SAP AG)
Neben der Überschrift der Grafik sowie der Bezeichnung der Y-Skala hat der
Programmierer bei Verwendung des Bausteins GRAPH_2D ausschließlich die Mög-
lichkeit, den verwendeten Grafiktyp zu bestimmen. Weitere Einflussmöglich-
keit auf die Darstellung der Grafik stehen hier nicht zur Verfügung. Es besteht
lediglich noch die Möglichkeit, zu steuern, wie die Grafik in Form einer Mail
versendet werden kann, sowie die Größe und Position des Viewer-Fensters auf
235
5.3 Geschäftsgrafiken mit GRAPH_2D
1 links oben
2 zentriert oben
3 rechts oben
4 links zentriert
5 zentriert zentriert
6 rechts zentriert
7 links unten
8 zentriert unten
9 rechts unten
Tabelle 5.2
Bedeutung des Parameters WINPOS
Wird keiner der dargestellten Werte übergeben, wird der Viewer jeweils 1/3 der
Bildschirmgröße vom unteren bzw. linken Bildschirmrand entfernt angezeigt.
Die Werte in den Parametern WINSZX bzw. WINSZY definieren die prozentuale Aus-
dehnung des Viewerfensters zur Auflösung des Bildschirm des Benutzers.
Beispiel:
Es wird von einer Bildschirmgröße von 800x600 Bildpunkten ausgegangen.
Werden in den Parametern WINPOS, WINSZX und WINSZY die Werte »5«, »50« und
»50« an den Funktionsbaustein übergeben, wird der Viewer in der Größe
400x300 Bildpunkten zentriert auf dem Bildschirm des Benutzers ausgegeben.
236
übergeben werden. Das System generiert daraufhin eine Mail mit dem im Para-
meter SO_TITLE definierten Titel. Die im Parameter SO_CONTENTS übergebene Zei-
chenkette wird zusätzlich zur Grafik in die Mail aufgenommen. Schließlich
kann über den Parameter SO_RECEIVER der Benutzername des R/3-Benutzers, der
die Mail erhalten soll, festgelegt werden.
237
5.4 Geschäftsgrafiken mit GRAPH_MATRIX_2D
Anders als beim Funktionsbaustein GRAPH_2D kann die Datentabelle für diesen
Funktionsbaustein mehrere Datenspalten enthalten. Die erste Spalte der Tabelle
muss auch hier eine Zeichenkette sein und bezeichnet den Namen der Spalte.
Daran schließen sich ein oder mehrere numerische Spalten an. Die Datentabelle
bildet somit ein zweidimensionales Feld numerischer Werte. Bei der Anzeige
kann der Funktionsbaustein angewiesen werden als Basis entweder alle Werte
einer Zeile oder alle Werte einer Spalte zur Anzeige zu bringen. Dies wird über
die Parameter NCOL bzw. NROW der Aufrufschnittstelle gesteuert. Die Spalten bzw.
Zeilen werden hierbei mit 1 beginnend durchnummeriert.
Werden beide Parameter versorgt, so hat der Parameter NCOL Vorrang, und es
werden die Werte einer Spalte über alle Zeilen der Tabelle grafisch aufbereitet.
Um dies zu demonstrieren, wird die interne Tabelle um eine weitere Spalte,
in der das durchschnittliche Gepäckgewicht je Klasse abgelegt wird, ermittelt.
Tatsächlich macht es in der Regel keinen Sinn, die Anzahl der Flugbuchungen
auf der gleichen Skala aufzutragen, wie das durchschnittliche Gepäckgewicht je
Buchung, aber um das Prinzip zu verdeutlichen soll das Beispiel genügen.
Um die notwendige Datenbasis zu schaffen, wurde die Tabelle G_DATA aus dem
vorigen Abschnitt um das Feld AVG_LUGGWEIGHT erweitert. Ebenfalls erweitert
wurde die SELECT-Anweisung, um die entsprechenden Daten aus der Datenbank
zu ermitteln.
...
* Datentabelle
DATA: BEGIN OF G_DATA OCCURS 0,
CLASS(20) TYPE C,
BOOKINGS TYPE I,
AVG_LUGGWEIGHT TYPE F,
END OF G_DATA.
START-OF-SELECTION.
* Datenbasis laden
SELECT CLASS
COUNT( * )
AVG( LUGGWEIGHT )
INTO (G_DATA-CLASS,
G_DATA-BOOKINGS,
G_DATA-AVG_LUGGWEIGHT)
FROM SBOOK
WHERE CARRID = C_CARRID AND
CONNID = C_CONNID AND
FLDATE = C_FLDATE
GROUP BY CLASS.
APPEND G_DATA.
ENDSELECT.
238
Aus der so ermittelten Datenbasis soll die erste Zeile als Grafik dargestellt wer-
den. Hierfür wird beim Aufruf des Funktionsbausteins GRAPH_MATRIX_2D der Pa-
rameter NROW mit dem Wert »1« belegt und der Parameter NCOL nicht übergeben.
...
* Grafik anzeigen
CALL FUNCTION 'GRAPH_MATRIX_2D'
EXPORTING
* NCOL = ' '
NROW = 1
TITL = 'Flug AZ555 - Avg. Gepäckgewicht'
VALT = '[Bookings|kg]'
TABLES
DATA = G_DATA
OPTS = G_OPT
TCOL = G_TCOL
EXCEPTIONS
COL_INVALID = 1
OPT_INVALID = 2
OTHERS = 3.
Das Zeichenfeld am Anfang der Zeile wird hierbei ignoriert, da sie nicht die
Spaltenüberschriften der jeweiligen Spalten der Zeile enthalten kann. Aus die-
sem Grund akzeptiert der Funktionsbaustein den neuen Tabellenparameter
TCOL, in dem die Überschriften und die Anzahl der Spalten definiert werden, die
für die Datenzeile angezeigt werden sollen.
Vor dem Aufruf des Funktionsbausteins müssen jedoch im Deklarationsteil des
Programms die interen Tabellen G_OPT und G_TCOL definiert werden.
...
* Optionen
DATA: BEGIN OF G_OPT OCCURS 0,
* Überschriften
DATA: BEGIN OF G_TCOL OCCURS 0,
HEADER(20) TYPE C,
END OF G_TCOL.
...
Der Aufbau dieser Tabellen ist nicht weiter vorgegeben. Zeichenketten bieten
sich aufgrund der abzulegenden Informationen allerdings an.
Die Überschriften der beiden Spalten, die in der Grafik angezeigt werden sollen,
werden vor dem Aufruf des Funktionsbausteins in der internen Tabelle G_TCOL
abgelegt.
239
5.4 Geschäftsgrafiken mit GRAPH_MATRIX_2D
...
* Spaltenüberschriften setzen
G_TCOL-HEADER = 'Buchungen'.
APPEND G_TCOL.
G_TCOL-HEADER = 'Gepäck Avg.'.
APPEND G_TCOL.
...
gesetzt.
Zunächst wird über die Option P2TYPE der Typ der Grafik festgelegt. Auf die ein-
zelnen Grafiktypen wird auch hier über die bereits in Tabelle 5.1 gezeigten Kür-
zel zugegriffen. Anschließend wird die Breite der einzelnen Balken festgelegt.
Der hier gezeigte Wert »1« entspricht einer geringen Balkenbreite. Gültige Wer-
te für diese Option sind die Zahle 1 bis 5. Zuletzt wird über die Option FIFRST
die Erstdarstellung der Grafik festgelegt. Hier sind die in Tabelle 5.3 dargestell-
ten Werte definiert. Allerdings sind nicht alle Werte in jedem Zusammenhang
gültig. Die dreidimensionale Darstellung ist beispielsweise bei Verwendung des
Funktionsbausteins GRAPH_MATRIX_2D nicht zugelassen.
240
FIFRST Bedeutung
2D 2D-Darstellung
3D 3D-Darstellung
GP Gruppendarstellung
PU Übersichtsdarstellung
Tabelle 5.3
Mögliche Werte für die Option FIFRST
SAP definiert eine ganze Reihe dieser Schalter. Tabelle 5.4 zeigt alle zulässigen
Optionen im Überblick. Hierbei sind alle Optionen, auch die, die beispielsweise
nur für 3D-Grafiken sinnvoll sind, aufgeführt.
241
5.4 Geschäftsgrafiken mit GRAPH_MATRIX_2D
Option Bedeutung
P3TYPE 3D-Grafiktyp
TO Türme
PY Pyramiden
ED Wände
WE Keile
NET Flächen
LI Linien
242
DTPEAK Daten zoomen
SCDECC Dezimaltrennzeichen
SCUNIT Skalierungseinheiten
WD Wort
EE Zehnerpotenz
EU Technisch
CLBACK Hintergrundfarbe
Tabelle 5.4
Optionen für Funktionsbausteine GRAPH_MATRIX_
243
5.5 Grafiken mit der Controls Technology
5.5.1 Überblick
Mit Einführung des Control Frameworks wurde seitens SAP auch eine neue
Möglichkeit der Darstellung von Geschäfts- und Strukturdaten etabliert. Wäh-
rend diese bisher nur in externen Viewern angezeigt werden konnten, die sich
optisch zwar am SAPGUI orientierten, jedoch eigenständige Applikationen wa-
ren, werden bei der neuen Möglichkeit zur Anzeige von Grafiken die Techniken
des Control Frameworks verwendet.
Im Einzelnen bedeutet dies, dass die Grafiken in Containern, welche wiederum
in Customer-Control-Areas innerhalb der normalen Dynpros angelegt werden,
angezeigt werden. Diese Technik wurde in diesem Buch bereits in Kapitel 3 zur
Anzeige von Baumdarstellungen eingeführt und in Kapitel 4 bei der Bearbei-
tung von Texten aufgegriffen.
Grafiken stellen daher ein weiteres wichtiges Anwendungsgebiet der Contai-
ner-Technik dar, nutzen diese aber auf eine etwas andere Art, als dies bisher
dargestellt wurde.
Wie bei den anderen Controls auch, werden hier Customer-Areas auf dem Dyn-
pro angelegt, welche zur Laufzeit von so genannten Container-Objekten ver-
waltet werden. Diese Container stellen lediglich den Ausführungsrahmen für
die jeweiligen Controls dar, egal, ob es sich hierbei um einen TreeView, ein Text-
Edit oder eine Geschäftsgrafik handelt.
Bei den aus der ABAP-Welt heraus sichtbaren Klassen handelt es sich jedoch
nicht um die tatsächlichen grafischen Komponenten. Diese laufen – entweder
als JavaBeans oder als ActiveX-Controls – auf dem Frontend-Rechner des Benut-
zers ab (siehe Abbildung 5.4). Die ABAP-Klassen, die in diesem Umfeld beteiligt
sind, stellen lediglich Platzhalter (Proxies) innerhalb der ABAP-Welt zur Kom-
munikation mit diesen entfernt ablaufenden Komponenten dar.
Die Aufgaben dieser Proxy-Klassen beschränken sich hierbei darauf, auf der
einen Seite die Kommunikation mit den entfernt ablaufenden visuellen Kom-
ponenten durchzuführen und auf der anderen Seite eine Schnittstelle für die an-
zuzeigenden Informationen sowie die Parametriesierung der Grafik durch
den Programmierer zur Verfügung zu stellen. Aus dem Gesagten geht bereits
hervor, dass zum Aufgabenbereich der Proxy-Klassen nicht die Verwaltung der
anzuzeigenden Informationen selbst gehört. Diese obliegt den so genannten
Daten-Containern, welchen neben der Verwaltung der Daten auch die Publizier-
ung von Datenänderungen obliegt.
244
Abbildung 5.4
Grundlegende Architektur der komponentenbasierten Grafik
Gründe für diese Aufgabenteilung sind zum einen die semantischen Unter-
schiede in den Aufgaben, zum anderen auch eine höhere Flexibilität bezüglich
des Aufbaus der Anwendungsdaten selbst. Das Proxy-Objekt bekommt ledig-
lich Kenntnis darüber, auf welche Art und Weise die anzuzeigenden Daten aus
dem Container extrahiert werden können, nicht jedoch, wie die Informationen
innerhalb des Containers verwaltet werden.
Ein anderer wichtiger Grund für die vollzogene Trennung zwischen dem Da-
tenmodell und der Anzeige liegt darin begründet, dass ein Datenbestand unter
Umständen gleichzeitig in mehreren Grafiken angezeigt wird. Durch die Tren-
nung von Daten und Anzeige können beliebig viele Anzeige-Objekte gleichzei-
tig auf denselben Datenbestand zugreifen, die Anzeigeobjekte selbst laufen
jedoch auf einem anderen Rechner ab.
In der Objektorientierung ist diese Architektur, die eine Teilung zwischen dem
245
5.5 Grafiken mit der Controls Technology
werden. Zuletzt wird eine Instanz eines Grafik-Proxies zur Verknüpfung dieser
beiden Elemente erstellt.
In dieser Reihenfolge soll daher auch bei der Entwicklung des Beispielpro-
gramms dieses Kapitels vorgegangen werden.
SAP unterscheidet in diesem Zusammenhang zwischen Geschäfts- und Struk-
turgrafiken. Diese spiegelt sich lediglich in unterschiedlichen Implementierun-
gen der gleichen Konzepte wieder. Im Folgenden wird daher auf Strukturgrafi-
ken nicht weiter eingegangen.
5.5.2 Daten-Container
Die Aufgabe der Daten-Container ist es, die Anwendungsdaten zu verwalten,
die in der oder den Grafiken angezeigt werden können. Aus diesem Grund
müssen Daten-Container-Klassen das ABAP-Objects-Interface IF_DC_MANAGEMENT,
in welchem der Zugriff der ABAP-Anwendung auf den Daten-Container defi-
niert ist, implementieren. Diese Schnittstelle beinhaltet Methoden, um den Con-
tainer selbst zu verwalten
Sowohl die Applikation, als Lieferant der Daten, als auch die Grafik-Proxies, die
die Informationen aus den Daten-Containern auslesen müssen und zur Ausga-
be an die Viewer-Klassen weiterleiten, benötigen Zugriff auf die im Container
enthaltenen Informationen. Um diesen beiden Parteien gleichermaßen Zugriff
auf die Daten des Containers zu ermöglichen, müssen Container das ABAP-In-
terface IF_DC_ACCESS implementieren, welches diese Zugriffe regelt.
Wenn sich die Daten im Daten-Container verändern, wird diese Umstand auto-
matisch an alle beim Container registrierten Proxy-Objekte gemeldet. Die Daten
des Containers können hierbei sowohl von der Anwendung, als auch aus einem
Viewer heraus modifiziert werden. Um den Vorgang der Registrierung und
Deregistrierung zu standardisieren, müssen Container daher das Interface
IF_DC_SUBSCRIPTION implementieren.
Alle ABAP-Klassen, die diese drei Interfaces implementieren, können als Daten-
Container fungieren. Da die Implementierung der Schnittstellen jedoch unter
Umständen sehr aufwendig ist, bietet SAP zum einen die Möglichkeit, einen ge-
nerischen Daten-Container zu verwenden, und zum anderen die Möglichkeit,
basierend auf einer im Data Dictionary definierten Struktur, einen eigenen Con-
tainer generieren zu lassen. Hierzu steht im System der »Data Container Wi-
zard« in Form des Reports GFW_DCWIZARD zur Verfügung. Daten-Container kap-
seln also die Dictionary-Strukturen und definieren eine funktionale Schale um
die ansonsten funktionslosen Strukturen. Das Modell sieht vor, dass diese funk-
tionale Schale aus den oben genannten drei Elementen besteht.
Im Folgenden sollen kurz die Kernfunktionalitäten der drei genannten Inter-
faces dargestellt werden.
246
Zugriff auf die Daten im Daten-Container (IF_DC_ACCESS)
Das Interface IF_DC_ACCESS definiert Methoden, um auf die im Daten Container
abgelegten Datenobjekte zuzugreifen. Ein Datenobjekt ist in diesem Zusam-
menhang eine Ausprägung der, dem Container zugrunde liegenden Dictionary-
Struktur.
Das Interface definiert sowohl Methoden, um schreibend (SET_VALUE) als auch le-
send auf den Container zuzugreifen (GET_VALUE). Weiterhin können einzelne
oder alle Objekte des Containers gelöscht werden (DEL_OBJECT, CLEAR).
Das Auslesen der Objekte des Containers kann auch sequentiell über die Metho-
den GET_PREDECESSOR bzw. GET_SUCCESSOR erfolgen. Änderungen an den Daten im
Container können über die Methode GET_CHANGES ermittelt werden.
Innerhalb eines Containers muss jedes gespeicherte Objekt eine ID haben, über
die, innerhalb der im Container gespeicherten Objekte, eindeutig auf das Objekt
zugegriffen werden kann.
Die Proxy-Klassen bieten die Möglichkeit, die Werte innerhalb des Containers
zu gruppieren und somit bei Bedarf mehrere Wertreihen innerhalb eines Dia-
gramms anzuzeigen. Weiterhin kann ein Feld innerhalb der Daten-Container-
Struktur als Filter definiert werden, um bei Bedarf nur auf einen Teil der Infor-
mationen des Daten-Containers zuzugreifen.
247
5.5 Grafiken mit der Controls Technology
Da dies einen erheblichen Aufwand bedeuten würde, stellt SAP einen Report
zur Verfügung, mit dem der Quelltext für einen Daten-Container generiert und
als Datei im lokalen Dateisystem des Programmierers abgelegt werden kann.
Der Report mit dem dies geschieht, hat den Namen GFW_DCWIZARD.
Um die Funktionsweise dieses Reports zu verstehen, muss an dieser Stelle ein
wenig näher auf den Zugriff der Proxies auf den Container eingegangen wer-
den.
Bei der Initialisierung der Proxy-Klasse muss dem Proxy mitgeteilt werden, wie
es auf den Daten-Container zuzugreifen hat. Die Proxies setzten hierbei folgen-
de Struktur voraus:
◗ Jedes Objekt innerhalb eines Daten-Containers ist eindeutig über ein Feld der
zugrunde liegenden Dictionary-Struktur identifizierbar.
◗ Jedes der Objekte des Daten-Containers definiert bis zu drei Werte, die für
die Darstellung des Objekts in den Präsentationsgrafiken verwendet werden
können.
◗ Die Objekte eines Daten-Containers können gruppiert werden, um mehrere
Datenreihen innerhalb eines Containers unterscheiden zu können. Diese
Gruppierung muss als Begriff in einem Attribut des Datenobjekts abgelegt
sein.
◗ Zur Einschränkung der Informationen innerhalb der oben definierten Grup-
pen besteht die Möglichkeit, ein Feld der Struktur als Filter-Feld zu definie-
ren, über die die Datenbasis während der Anzeige eingeschränkt werden
kann.
Über den Filter kann daher die Menge der, der Grafik zugrunde liegenden Ob-
jekte eingeschränkt werden, während über das Gruppenfeld parallele Datenrei-
hen aufgebaut werden. Diese beiden Konzepte können beliebig miteinander
verschachtelt werden.
Mit diesem Wissen, ist der Aufbau des Selektionsbildschirms des Reports
GFW_DCWIZARD einfach zu verstehen (Abbildung 5.5).
Zunächst muss die Data Dictionary-Struktur, welche die Basis des neu zu erstel-
lenden Containers bildet, definiert werden. Daran schließt sich die Definition
des Feldes der Struktur, welches die eindeutige Objekt-ID enthält, an.
Die Gruppenbildung innerhalb der Daten-Container erfolgt über dynamische
Verfahren. Somit kann zur Laufzeit durch Wahl eines anderen Gruppenfeldes
eine andere Sicht auf die Daten des Containers erzeugt werden.
Anders verhält es sich beim Filter, der ebenfalls als Feld in der Container-Struk-
tur enthalten sein muss. Schließlich müssen noch eine Reihe von Verwaltungs-
informationen, wie z.B. der Klassenname des Daten-Containers, definiert wer-
den, bevor die Generierung gestartet werden kann.
248
Der Data-Container-Wizard erstellt hierbei nicht direkt Code im R/3-System,
sondern generiert eine Datei im lokalen Dateisystem des Benutzers, welche
manuell vom Programmierer in das System geladen werden muss.
Abbildung 5.5
Selektionsbildschirm des Data-Container Wizards (Report GFW_DCWIZARD) (© SAP AG)
Das dargestellte Beispiel zeigt die Parameter, die nötig wären, um den im Sys-
tem bereits vorhandenen generischen Daten-Container zu generieren. Im Bei-
spiel würde allerdings lediglich der Code für eine lokale Klasse erzeugt werden.
Verbindungsglied zwischen dem Daten-Container auf der einen und dem Con-
trols-Framework mit den auf dem Präsentationsrechner ablaufenden Controls,
sind die so genannten Grafik-Proxies. Diese bilden in der ABAP-Umgebung die
programmtechnische Repräsentation der remote ablaufenden Controls.
Über die Grafik-Proxies können nicht die dargestellten Daten manipuliert wer-
den, wohl aber die Art der Darstellung. Hierfür hat SAP eine Architektur
geschaffen, die es ermöglicht, optische Eigenschaften eines Controls über vorde-
finierte parametrisierbare Klassen an bestimmte Stellen an das Proxy anzu-
schließen. Dieser Vorgang wird in diesem Zusammenhang Customization, die
dazugehörigen Klassen Customization-Objekte genannt.
249
5.6 Erstellen einer Grafik mit einer Datenreihe
250
5.6.1 Erstellen und Füllen des Daten-Containers
Das Beispiel dieses Kapitels verwendet eine Instanz des generischen Daten-
Containers LCL_GP_PRES. Hierdurch können einfach Parallelen zwischen diesem
Buch und der SAP-Dokumentation hergestellt werden.
Zunächst muss im Report das Include, in dem die Implementierung des Daten-
Containers enthalten ist, eingebunden werden. Im vorliegenden Fall beginnt
der Report daher mit der Sequenz
REPORT ZBUCH_GRAPH.
woran sich – analog zum Beispiel aus Abschnitten 5.3 und 5.4 – die Definition
der Konstanten, die den darzustellenden Flug definieren anschließen.
* Konstantendefinition des auszuwertenden Fluges
CONSTANTS: C_CARRID LIKE SBOOK-CARRID VALUE 'AZ',
C_CONNID LIKE SBOOK-CONNID VALUE '0555',
C_FLDATE LIKE SBOOK-FLDATE VALUE '19991113'.
Schließlich müssen im Deklarationsteil des Reports noch Variablen für den Da-
ten-Container, die Zugriffsnummer des Programms auf den Container sowie
ein globales Feld zur Aufnahme der Return-Codes der aufgerufenen Methoden
angelegt werden.
* Variables for the Data-Container-Handling
DATA: G_DC TYPE REF TO LCL_DC_PRES,
G_ID_AT_DC TYPE I,
G_RETVAL TYPE SYMSGNO.
* Daten-Container erzeugen
PERFORM CREATE_DC CHANGING G_DC
G_ID_AT_DC.
251
5.6 Erstellen einer Grafik mit einer Datenreihe
SELECT CLASS
COUNT( * )
INTO (L_CLASS,
L_COUNT)
FROM SBOOK
WHERE CARRID = C_ CARRID AND
CONNID = C_ CONNID AND
FLDATE = C_ FLDATE
GROUP BY CLASS.
L_GFWDCPRES-OBJID = L_CLASS.
L_GFWDCPRES-X_VAL = L_CLASS.
L_GFWDCPRES-Y_VAL = L_COUNT.
252
CALL METHOD P_DC->SET_OBJ_VALUES
EXPORTING
ID = P_ID_AT_DC
OBJ = L_GFWDCPRES
IMPORTING
RETVAL = P_RETVAL.
CHECK P_RETVAL = CL_GFW=>OK.
ENDSELECT.
ENDFORM. " FILL_DC
Die Datenermittlung ist in diesem Fall recht einfach und kann mit einer einfa-
chen SELECT-Anweisung realisiert werden. Zur eindeutigen Identifizierung der
Objekte genügt in diesem Schritt die gebuchte Klasse. Im Abschnitt 5.7 muss
dieser Begriff erweitert werden, um Buchungen mehrerer Flüge unterscheiden
zu können.
Um zu zeigen, dass das Erstellen und Füllen des Daten-Containers im Bereich
der Anwendung liegt, wurden diese Schritte direkt aus dem Ereignisblock
START-OF-SELECTION heraus ausgeführt. Die Erstellung des Dynpro-Containers
sowie des Grafik-Proxies erfolgt auf einer anderen Ebene und wurde daher in
die Implementierung des Dynpros verlagert, auf welchem die Darstellung der
Grafik erfolgen soll.
253
5.6 Erstellen einer Grafik mit einer Datenreihe
Die Erzeugung der Instanz erfolgt hierbei nur einmal. Ist die globale Variable,
welche die Instanz der Klasse CL_GUI_CUSTOM_CONTAINER enthält, nicht initial, hat
dieser Schritt bereits stattgefunden und wird im Folgenden übersprungen.
Die Variable G_CONTAINER wird hierbei global im Programm deklariert.
DATA: G_CONTAINER TYPE REF TO CL_GUI_CUSTOM_CONTAINER.
254
IMPORTING
RETVAL = G_RETVAL.
Im Anschluss daran wird die Instanz des Grafik-Proxies, welche als globale
Variable mit dem Typ CL_GUI_GP_PRES definiert ist, erzeugt. Die neue Instanz
der Klasse wird über einen Aufruf der Methode INIT initialisiert. Dabei wird
dem Proxy sowohl die Instanz des Daten-Containers, als auch die Instanz des
GUI-Containers übergeben.
Über die beiden Parameter PROD_ID und FORCE_PROD wird festgelegt, welches Gra-
fikprodukt zur Anzeige der Grafik verwendet werden soll. Bei den Grafik-Pro-
dukten handelt es sich um eine weitere Modularisierung zwischen dem Proxy
255
5.6 Erstellen einer Grafik mit einer Datenreihe
Die Grafik erscheint somit auf dem Dynpro. Analog kann mit der Methode
DEACTIVATE die Anzeige auf dem Dynpro jederzeit unterdrückt werden.
Auf die Darstellung der Grafik wurde in diesem Fall kein Einfluss genommen.
Das System nimmt in diesem Fall eine Reihe von Standardeinstellungen vor, so
dass die Ausgabe des Programmes dem in Abbildung 5.6 gezeigten Bildschirm
entspricht.
MODULE DISTRIBUTE_0100 OUTPUT.
CALL METHOD G_DC->IF_DC_MANAGEMENT~DISTRIBUTE_CHANGES
IMPORTING
RETVAL = G_RETVAL.
ENDMODULE. " DISTRIBUTE_0100 OUTPUT
Abbildung 5.6
SAP Grafik ohne Beeinflussung der Darstellung (© SAP AG)
256
5.6.4 Anpassen der Darstellung über Customizing
Im Abschnitt 5.5.3 wurde erklärt, dass die Darstellung der Grafiken auf dem
Bildschirm in weiten Grenzen vom Programmierer beeinflusst werden kann.
Hierfür bieten die Proxy-Klassen Anschlussmöglichkeiten für andere Objekte,
die die Darstellungsattribute für einen Bereich definieren. Jedes Proxy-Objekt
kann dabei andere Anschlüsse (Ports) definieren. Der Zugriff auf die Ports er-
folgt jedoch standardisiert über die Methoden, die im Interface IF_GRAPHIC_PROXY
definiert sind.
Das hier verwendete Proxy CL_GUI_GP_PRES definiert acht solcher Anschlussmög-
lichkeiten.
◗ Diagramm
◗ Chart
◗ Primäre Achse (X-, Y- und Z-Dimension)
◗ Sekundäre Achse (X-, Y- sowie Z-Dimension)
Jeder dieser Ports kann mit Customizing-Objekten versehen werden. SAP de-
fininiert eine ganze Reihe Customizing-Objekte, deren Namen mit dem Präfix
CL_CU_ beginnen.
Klasse Aufgabe
CL_CU_DIAGRAM Die Klasse enthält alle Attribute, die die Grafik als ganzes
Betreffen. Dies beinhaltet auch Informationen über Aus-
gabebereiche, falls mehrere Grafiken innerhalb eines Dia-
gramms ausgegeben werden.
257
5.6 Erstellen einer Grafik mit einer Datenreihe
Klasse Aufgabe
Tabelle 5.5
Customizing-Klassen
* Customizing-Objekt erzeugen
CREATE OBJECT L_BUNDLE_VALUES
EXPORTING
INSTANCE_ID = 'CLASSES'.
258
* Copy Display-Context into Values
CALL METHOD L_BUNDLE_VALUES->IF_CUSTOMIZING~SET
EXPORTING
ATTR_ID = CL_CU_VALUES=>CO_CURVE_CONTEXT
VALUE = L_BUNDLE_DISPLAY.
* Customizing vornehmen
CALL METHOD L_BUNDLE_VALUES->IF_CUSTOMIZING~SET
EXPORTING
ATTR_ID = CL_CU_VALUES=>CO_STYLE
VALUE = L_CHARTYPE.
259
5.6 Erstellen einer Grafik mit einer Datenreihe
CO_STYLE Aufgabe
27, 28 2D-Tortendiagramm
31, 32 3D-Tortendiagramm
Tabelle 5.6
Wichtige Grafiktypen bei der SAP Grafik
Sobald ein Customizing-Objekt vollständig initialisiert ist, kann es über die Me-
thode CU_ADD_BUNLDE einem Port an einem Proxy-Objekt zugewiesen werden.
Über den Parameter KEY kann ggf. noch gesteuert werden, für welche Objekt-
gruppe des Daten-Containers die jeweilige Einstellung vorgenommen werden
soll.
260
Abbildung 5.7
Darstellung der Buchungsanteile als 3D-Tortendiagramm (© SAP AG)
Abbildung 5.7 zeigt die Darstellung der Grafik, nachdem die Customizing-
Einstellungen aktiviert wurden. Der Unterschied zu Abbildung 5.6 zeigt, in
welchem Umfang die Darstellung durch das Customizing beeinflusst werden
kann. Außer dem Customizing wurden keinerlei Veränderungen am zugrunde
liegenden Programm durchgeführt.
261
5.7 Darstellung mehrerer Datenreihen
die Buchungen vom 11.12.1999 des gleichen Fluges dargestellt werden. Das
zweite Datum wird in Form der Kontante C_FLDATE2 am Anfang des Programms
definiert.
FORM FILL_DC USING P_DC TYPE REF TO LCL_DC_PRES
P_ID_AT_DC TYPE I
CHANGING P_RETVAL TYPE SYMSGNO.
DATA: L_GFWDCPRES TYPE GFWDCPRES.
DATA: L_CLASS TYPE SBOOK-CLASS,
L_COUNT TYPE I.
262
GROUP BY CLASS.
CONCATENATE L_CLASS
'B'
INTO L_GFWDCPRES-OBJID.
L_GFWDCPRES-GRPID = 'B'.
L_GFWDCPRES-X_VAL = L_CLASS.
L_GFWDCPRES-Y_VAL = L_COUNT.
CA A C 15
FA A F 68
YA A Y 137
CB B C 14
FB B F 67
YB B Y 134
Tabelle 5.7
Objekte im Daten-Container bei zwei Wertereihen
263
5.7 Darstellung mehrerer Datenreihen
Abbildung 5.8
3D-Balkengrafik mit zwei Wertereihen (© SAP AG)
Die Darstellung mehrerer Wertereihen funktioniert nur dann, wenn dem Gra-
fik-Proxy bei dessen Initialisierung das Strukturfeld, welches die Gruppen defi-
niert, mitgeteilt wurde. Wird beim Aufruf der Methode SET_DC_NAMES (siehe
5.6.3) der optionale Parameter GRP_ID nicht entsprechend übergeben, werden in
keinem Fall mehr als eine Wertereihe ausgeben.
Zuletzt sei noch angemerkt, dass vor Beendigung des Programms die Methode
FREE des Grafik-Proxies aufgerufen werden sollte, um eine saubere Deinitialisie-
rung der verwendeten Speicherbereiche durchzuführen. Auf diese Weise wer-
264
den unter Umständen noch belegte Ressourcen für die Kommunikation zwi-
schen dem Proxy und der Grafik selbst freigeben.
5.8.1 GRAPH_2D
Der Funktionsbaustein GRAPH_2D bietet eine einfache Möglichkeit, 2-dimensiona-
le Grafiken anzuzeigen. Die Aufrufschnittstelle des Funktionsbausteins ist mög-
lichst einfach gehalten, bietet daher aber auch nicht so viele Möglichkeiten, wie
der Funktionsbaustein GRAPH_MATRIX_2D, dessen Aufrufschnittstelle größere Ein-
flussmöglichkeiten beinhaltet.
Import-Parameter
AUTO_CMD_1 intern
AUTO_CMD_2 intern
DISPLAY_TYPE Grafiktyp
INBUF intern
265
5.8 Verwendete Funktionsbausteine
TIMER intern
X_OPT intern
Export-Parameter
RBUFF intern
Tabellen-Parameter
Export-Parameter
266
5.8.2 GRAPH_MATRIX_2D
Mit dem Funktionsbaustein GRAPH_MATRIX_2D, der stellvertretend für alle Funkti-
onsbausteine, deren Name mit GRAPH_MATRIX_ beginnt, gezeigt wird, können
Businessgrafiken mit mehr Gestaltungsoptionen des Programmierers angezeigt
werden.
Sollen lediglich einfache Datenstrukturen angezeigt werden, kann unter
Umständen die Verwendung von GRAPH_2D einfacher sein.
Import-Parameter
AUTO_CMD_1 intern
AUTO_CMD_2 intern
INBUF intern
NCOL Spaltennummer in Datentabelle, in der die Werte für die Grafik enthal-
ten sind
SO_SEND Versenden der Grafik über SAPOffice. Keine Anzeige der Grafik auf
dem Bildschirm.
TIMER intern
267
5.8 Verwendete Funktionsbausteine
X_OPT intern
Export-Parameter
RBUFF intern
Tabellen-Parameter
TCOL Spaltenüberschriften
Export-Parameter
268
Batch-Input-Techniken
6
6.1 Was ist Batch-Input
Hinter dem Begriff Batch-Input (BTC) verbirgt sich eine Technik in R/3 Dialog-
transaktionen unsichtbar abspielen zu lassen. Es handelt sich hierbei um ein au-
tomatisiertes Abspielen von Benutzereingaben, d.h. sämtliche Plausibilisierun-
gen und Ableitungen, die auch bei manueller Bedienung der Transaktion
ablaufen würden, werden auch im BTC durchgeführt. Der Weg durch die Dyn-
pros wird dem System hierbei in Form einer internen Tabelle mitgeteilt. Diese
Tabelle aufzubauen ist der wichtigste und zugleich schwierigste Schritt beim
Batch-Input. In der Tabelle werden sämtliche Benutzereingaben, d.h. sowohl in
Felder als auch Funktionstasten u.ä., sowie alle Bildschirmwechsel definiert.
Man kann sich die Technik so vorstellen, als müsste einer Person der Weg durch
eine ihr unbekannte Stadt erklärt werden. Der Person müssen Ortsbeschreibun-
gen und Anweisungen mit auf den Weg gegeben werden, um einen erreichten
Punkt zu erkennen und um zu wissen, wie an diesem Punkt weiter zu verfahren
ist. Der Person muss hierbei jeder Punkt (z.B. Kreuzung), der ihr auf dem Weg
durch die Stadt begegnet, beschrieben werden und an jedem dieser Punkte eine
oder mehrere Aktionen, die die Person dort auszuführen hat (z.B. links abbie-
gen). Wichtig hierbei ist, dass die Beschreibung lückenlos und vollständig ist.
Dies heißt, dass weder Punkte auf dem Weg fehlen dürfen, noch zuviele Orte
beschrieben sein dürfen. Sobald ein Ort beschrieben wird, der nicht stimmt,
oder eine Aktion, die nicht durchgeführt werden kann (z.B. wenn kein Zebra-
streifen da ist, wo einer überquert werden soll), weiß die Person nicht mehr, wo
sie ist und bricht die gesamte Prozedur erfolglos ab.
Übertragen auf den Batch-Input-Ablauf bedeutet dies, dass die Ablauf-Tabelle
sämtliche Dynpros, die betreten werden, nennen muss und sämtliche Aktionen,
die der Benutzer auf diesen Dynpros durchführt, benannt werden müssen. Dies
umfasst Feldeingaben aber auch das Auslösen von Funktionscodes, um Aktio-
269
6.2 Warum Batch-Input?
nen auszulösen oder Bildwechsel vorzunehmen. Wichtig hierbei ist, dass der ge-
samte Ablauf vor Aufruf der Transaktion definiert werden muss, der Program-
mierer hat also während des Abspielens des Batch-Input keinerei Möglicheiten
mehr, auf den Programmlauf Einfluss zu nehmen. Hier wird das Problem beim
Batch-Input deutlich. Wenn der Person aus obigen Beispiel der Name einer ein-
zigen Kreuzung falsch genannt wird, oder nur ein einziges Mal falsch abgebogen
wird, ist sie hoffnungslos verloren und das gewünschte Ziel unerreichbar. Bei
der Programmierung von Batch-Input-Abläufen müssen die auszuführenden
Transaktionen daher genau untersucht werden und etwaige Verzweigungen
aufgrund von Anwendungsdaten oder Systemeinstellungen vorausgesehen und
berücksichtigt werden.
Erschwerend kommt hierbei noch hinzu, dass sich Dialogtransaktionen in R/3
häufig im »echten« Dialog, d.h. bei manueller Bedienung durch einen Benutzer,
anders verhalten, als im »Batch«-Mode. Dies muss bei der Erstellung der Batch-
Input-Abläufe ebenfalls berücksichtigt werden. In Abschnitt 6.9 wird auf dieses
Phänomen nochmals eingegangen.
Bei der Erstellung von Batch-Input-Abläufen bietet das System dem Program-
mierer jedoch Unterstützung an. Über den so genannten »Batch-Input-Recor-
der« (Transaktion SHDB) können Batch-Input-Abläufe während der Bedienung
einer Dialogtransaktion aufgenommen und später entweder als Batch-Input-
Mappe (siehe Abschntt 6.6) oder als generiertes Programm für die Verwendung
der CALL TRANSACTION-Anweisung abgelegt werden. Der aufgezeichnete Ablauf
entspricht jedoch nur dem Ablauf unter der Datenkonstellation, die während
der Aufzeichnung verwendet wurde. Näheres zum Batch-Input-Recorder ist in
Abschnitt 6.7 dargestellt.
Wie bereits erwähnt, können Batch-Input-Abläufe auch als so genannte Mappen
im System abgelegt werden. Es handelt sich hierbei um die Speicherung der
Batch-Input-Abläufe im R/3-System zur asynchronen Verarbeitung. Diese
Funktionalität wird über eine Reihe von Funktionsbausteinen realisiert. Wie
diese genutzt werden und was sich sonst hinter dieser Technik verbirgt, wird im
Abschnitt 6.6 dieses Kapitels erläutert.
Das ABAP-Sprachkonstrukt, welches verwendet wird, um Batch-Input-Abläufe
abzuspielen, ist die Anweisung CALL TRANSACTION. Die Funktionalität dieser An-
weisung beschränkt sich jedoch nicht nur auf das Abspielen vollständiger
Transaktionen. Die Optionen und Nutzungsmöglichkeiten dieser Anweisung
werden ausführlich im Abschnitt 6.5 gezeigt.
270
zusammen ausgewertet werden und die Eingabebereitschaft nur bestimmter
Felder im Falle eines Fehlers erreicht werden. Bedingt durch dieses Modell be-
findet sich jedoch sehr viel Programmintelligenz in den Ablaufsteuerungen der
Dynpros. Gepaart mit der Tatsache, dass auf dieser Ebene keine lokalen Pro-
grammvariablen und kein Mechanismus zur Übergabe von Parametern vorhan-
den sind, ergibt dies ein stark an die Benutzeroberfläche gekoppeltes Ablaufmo-
dell.
Eine strikte Trennung zwischen der Darstellungsebene und der Ebene der Busi-
ness-Logik wurde lange Zeit nicht konsequent durchgeführt. Bei der Komplexi-
tät des Systems R/3 ist es daher so gut wie unmöglich, bei eigenen Programmen
sämtliche Plausibilisierungen und Ableitungen nachzubilden, die das System in
seinen Dialogtransaktionen durchführt. Auch das Speichern von Informationen
in den Anwendungstabellen des Systems R/3 sollte allenfalls mit größter Vor-
sicht vorgenommen werden, da an einer Transaktion häufig eine Vielzahl von
Tabellen mit zum Teil nicht offensichtlichen Verbindungen beteiligt sind. Unbe-
dachtes direktes Schreiben in der Datenbank führt demnach mit größter Wahr-
scheinlichkeit zu inkonsistenten Datenbeständen im System R/3. Seit einiger
Zeit versucht SAP diesem Umstand durch Bereitstellung spezieller Funktions-
bausteine, den Business APIs (BAPIs) entgegenzuwirken. Im Release 4.6 ist die
Anzahl dieser BAPIs im Vergleich zu den vorigen Releaseständen erheblich ge-
stiegen. Leider sind allerdings viele der BAPIs auch im Release 4.6C noch feh-
lerhaft und inperformant. Weiterhin ist der Programmcode der BAPIs oftmals
so komplex, dass selbst einfache Modifikationen nur von sehr erfahrenen Pro-
grammierern vorgenommen werden können. Der klare Vorteil von Batch-Input
ist hierbei, dass sämtliche Plausibilisierungen, die während der Dialogverarbei-
tung einer Transaktion durchgeführt werden, im Batch-Input ebenfalls aktiv
sind. Dies führt zwar in der Anfangsphase zu vermehrten Transaktionsabbrü-
chen aufgrund fehlerhafter Batch-Input-Informationen, in der Folge jedoch zu
sehr stabilem Code, der aus sich heraus in keiner Situation einen Datenschief-
stand erzeugt.
Kapitel 6 – Batch-Input-Techniken
6.3 Funktionsweise von Batch-Input
Beim Batch-Input werden normale Dialogtransaktionen ohne Benutzereingaben
automatisch durchgeführt. Sämtliche Benutzeraktionen werden in Form einer
Tabelle, der Batch-Input-Tabelle, vor Aufruf der eigentlichen Funktion beschrie-
ben. Beim Ablauf werden lediglich die Aktionen durchgeführt, die in dieser Ta-
belle beschrieben sind. Zusätzlich dazu enthält diese Tabelle einen Eintrag für
jedes ausgelöste PROCESS-BEFORE_OUTPUT-Ereignis. Für jedes PBO muss ein Eintrag
in der Tabelle enthalten sein, der das prozessierte Dynpro beschreibt.
Wenn die Tabelle vollständig ist, kann die beschriebene Dialogtransaktion ent-
weder direkt über die Anweisung CALL TRANSACTION ausgeführt werden, oder
aber die Tabelle wird – ggf. mit mehreren gleichartigen Tabellen zusammen – in
271
6.3 Funktionsweise von Batch-Input
1. Ausgenommen von dieser Aussage sind Aufrufe von CALL TRANSACTION im Modus
E, die in diesem Fall sichtbar in die Dialogtransaktion verzweigen.
272
6.4 Erzeugen einer Batch-Input-Tabelle
Tabelle 6.1
Aufbau der Struktur BDCDATA
In diese Tabelle müssen wie erwähnt für jedes PBO-Ereignis sowie alle Feldzu-
weisungen und Funktionscodes Einträge vorgenommen werden. Eine besonde-
re Rolle kommt hierbei dem Feld DYNBEGIN zu. Wird in diesem Feld ein »X« abge-
legt, bedeutet dies, dass der Satz sich auf ein neues Dynpro, sprich ein PBO-
Ereignis bezieht. In diesem Fall ist der Inhalt der Felder FNAM sowie FVAL unerheb-
lich. Ausgewertet werden lediglich die Inhalte der Felder PROGRAM und DYNPRO,
welche eindeutig ein Dynpo im R/3-System beschreiben. PROGRAM enthält hierbei
den Namen des Modulpools oder des Reports, in dem das jeweilige Dynpro mit
der in DYNPRO definierten Dynpro-Nummer abgelegt ist.
Kapitel 6 – Batch-Input-Techniken
Ist das Feld DYNBEGIN leer, werden die beiden genannten Felder igonriert und le-
diglich der Inhalt der Felder FNAM und FVAL vom System ausgewertet. FNAM enthält
hierbei den Namen eines Dynpro-Feldes, wie er aus der technischen Hilfe zu je-
dem Dynpro-Element ermittelt werden kann (siehe Abbildung 6.1). Der Batch-
Input-Name des Feldes ist hierbei im unteren Bereich des Fensters in der Grup-
pe »Feldbezeichnungen für Batch-Input« abgelegt. Der Inhalt der Variablen FVAL
wird beim Abspielen der Tabelle in das jeweilige Dynpro-Feld geschrieben.
Funktionstasten oder – allgemeiner ausgedrückt – Funktionscodes, die der Be-
nutzer eingeben würde, werden über den besonderen Feldnamen BDC_OKCODE in
der Tabelle abgelegt. Das Feld FVAL enhält in dieser Situation den auszuführen-
den Funktionscode. Soll der Cursor zur Laufzeit auf ein bestimmtes Dynpro-
Element gesetzt werden, (z.B. um auf einem bestimmten Feld eine Aktion
273
6.4 Erzeugen einer Batch-Input-Tabelle
Abbildung 6.1
BTC-Name eines Dynpro-Feldes in der technischen Hilfe (© SAP AG)
Dieser ist für jeden Dynprostart bis auf den Namen des Programms und der
Dynpro-Nummer identisch, es ändern sich also lediglich zwei der dargestellten
fünf Zeilen Code. Die Zeilen, um einen Feldinhalt zu setzen, füllen entspre-
chend die Felder FVAL und FNAM.
274
Wird für jeden Dynpro-Wechsel bzw. jedes Setzen von Feldinhalten diese
Sequenz direkt in den Code eingefügt, wird zum einen das Programm sehr auf-
gebläht, zum anderen leidet die Lesbarkeit des Programmes erheblich. Aus
diesem Grund verwenden Programmierer, die häufiger BTC-Abläufe realisie-
ren müssen, für diese Aufgaben in der Regel Routinen, um den eigentlichen
Programmcode zu entlasten.
Je nach persönlicher Vorliebe des einzelnen Programmierers können hierzu ein
oder mehrere Routinen realisiert werden. Ebenfalls eine Entscheidung des Pro-
grammierers ist es, ob die Routinen als FORM-Routinen in einem – oft mehrfach
verwendeten - Include, als Funktionsbausteine einer Funktionsgruppe oder als
ABAP-Objects-Klassen realisiert werden. Bei Verwendung von Funktionsbau-
steinen wird der Vorteil des kompakten Codes allerdings zugunsten von Modu-
larisierungsbemühungen aufgegeben, da der Aufruf eines Funktionsbausteins
in der Regel länger ist als die fünf dargestellten Zeilen Code, die benötigt wer-
den, wenn die Tabelle direkt versorgt wird. Der Ansatz mit ABAP-Objects ver-
spricht große Vorteile bezüglich der Wiederverwendbarkeit. Auch die Kapse-
lung der BTC-Tabelle spricht für die Verwendung dieses Ansatzes.
Aus Gründen der Einfachheit der Darstellung wird hier eine Lösung mit FORM-
Routinen dargestellt. Die Integration der Funktionalitäten in eine der anderen
Methoden ist jedoch sehr einfach.
Der Code könnte im System als Include abgelegt werden und an den verschie-
densten Stellen im System verwendet werden. Zu beachten ist jedoch, dass in
dem Programm, wo das Include eingebunden wird, keine Variable mit dem
Namen BTC_TABLE existieren darf, da diese als globale Variable – einem der sehr
seltenen Fällen wo dies sinnvoll erscheint – angelegt wurde.
DATA: BTC_TABLE LIKE BDCDATA OCCURS 0 WITH HEADER LINE.
*-----------------------------------------------------
* Routine zum Löschen der aktuellen BTC-Tabelle
*-----------------------------------------------------
FORM BTC_REFRESH. Kapitel 6 – Batch-Input-Techniken
CLEAR BTC_TABLE.
REFRESH BTC_TABLE.
ENDFORM.
*-----------------------------------------------------
* Begin eines neuen Dynpros (bzw. PBO)
*-----------------------------------------------------
FORM BTC_DYNPRO USING P_PROGRAM LIKE BDCDATA-PROGRAM
P_DYNPRO LIKE BDCDATA-DYNNR.
CLEAR BTC_TABLE.
BTC_TABLE-PROGRAM = P_PROGRAM.
BTC_TABLE-DYNPRO = P_DYNPRO.
275
6.4 Erzeugen einer Batch-Input-Tabelle
BTC_TABLE-DYNBEGIN = 'X'.
APPEND BTC_TABLE.
ENDFORM.
*-----------------------------------------------------
* Feldwert setzen
*-----------------------------------------------------
FORM BTC_DATA USING P_FNAM
P_FVAL.
CLEAR BTC_TABLE.
BTC_TABLE-FNAM = P_FNAM.
BTC_TABLE FVAL = P_FVAL.
APPEND BTC_TABLE.
ENDFORM.
*-----------------------------------------------------
* Aktulle BTC-Tabelle ermitteln
*-----------------------------------------------------
FORM BTC_TABLE_GET TABLES P_BTC_TABLE STRUCTURE BDCDATA.
P_BTC_TABLE[] = BTC_TABLE[].
P_BTC_TABLE = BTC_TABLE.
ENDFORM.
*-----------------------------------------------------
* Aktuele bTC-Tabelle setzen
*-----------------------------------------------------
FORM BTC_TABLE_SET TABLES P_BTC_TABLE STRUCTURE BDCDATA.
BTC_TABLE[] = P_BTC_TABLE[].
ENDFORM.
276
6.4.3 Verwendung numerischer Felder
Besondere Aufmerksamkeit beim Aufbau der Batch-Input-Tabelle verdienen nu-
merische Felder. Anders als in Charakter-Feldern, findet die Eingabe in numeri-
schen Feldern in der Regel rechtsbündig statt. Da das Feld FVAL der BDCDATA-Struk-
tur 132 Stellen breit ist, würde eine einfache WRITE-Zuweisung eines numerischen
Feldes an dieses Feld bewirken, dass der Feldinhalt rechtsbündig, d.h. mit der
132. Stelle endend im Feld FVAL platziert würde. Beim Batch-Input werden die
Feldinhalte jedoch von links beginnend in die Dynpro-Felder der aufgerufenen
Transaktion übertragen. Wenn der benutzte Inhalt des Feldes FVAL breiter ist als
das jeweilige Dynpro-Feld, bricht der Batch-Input mit einer Fehlermeldung ab,
da der gewünschte Feldinhalt nicht korrekt gesetzt werden kann.
Um dies zu verhindern, muss sichergestellt sein, dass die verwendete Breite der
Variable FVAL nicht größer ist als die tatsächliche Breite des Dynpro-Feldes, in
das der Inhalt übertragen werden soll. Dies kann durch Verwendung einer
Hilfsvariable, in die der numerische Wert in der gewünschten Länge übertragen
wird, realisiert werden.
...
DATA: L_FVAL LIKE BDCDATA-FVAL.
CLEAR L_FVAL.
WRITE <num-Variable> TO L_FVAL(<Breite>).
PERFORM BTC_DATA USING <Feldname>
L_FVAL.
...
277
6.4 Erzeugen einer Batch-Input-Tabelle
278
Abbildung 6.2
Darstellung einer Anleitung aus dem Bereich PM mit einem Table-View (© SAP AG)
279
6.5 Verwendung von CALL TRANSACTION
ger verhält es sich bei Step-Loops variabler Länge. Auch hier ist die Antwort auf
die Frage einfach, allerdings auch frustrierend: Der Programmierer weiß es
nicht. Sicher ist lediglich, dass mindestens eine Zeile angezeigt wird.
Am besten und sichersten ist es, wenn der Batch-Input so gestaltet werden kann,
dass die gewünschte Zeile am Anfang der Liste, also in der ersten Zeile des Ta-
ble-Views, dargestellt wird. Verschiedene Transaktionen (z.B. im Bereich der
Pflege von Arbeitsplänen) lässt dies über Funktionscodes und Dialogfenster zu.
Bevor BTC-Abläufe erstellt werden, sollte demnach genau untersucht werden,
ob die aufzurufende Transaktion derartige Funktionalitäten zur Verfügung
stellt.
Ist dies nicht möglich, und die Bearbeitung der in der Liste dargestellten Sätze
kann nicht auf andere Art gelöst werden, muss eine Dynpro-Größe – z.B. die
Standard-Größe – angenommen und das Programm hierauf abgestimmt wer-
den. Der Programmierer muss sich jedoch jederzeit im Klaren sein, dass der pro-
duzierte Code sehr fehleranfällig ist, falls die Benutzer häufig unter anderen
Bildschirmauflösungen oder Fenstergrößen arbeiten. Dieses Problem kann je-
doch unter Umständen vernachlässigt werden, wenn die Dynpros der Transak-
tion, die den Batch-Input aufruft, durch organisatorische oder gestalterische
Maßnahmen auf den Vollbildmodus der Benutzer ausgelegt werden. Um sicher
zu gehen, sollte jedoch der Fall des Transaktionsabbruchs in solchen Fällen
besonders berücksichtigt werden und die Batch-Input-Daten beispielsweise
in Form einer BTC-Mappe zur späteren Nachverbuchung abgelegt werden.
Der Anweisung muss auf jeden Fall der aufzurufende Transaktionscode über-
geben werden. Wird keiner der weiteren Parameter spezifiziert, gelangt der Be-
nutzer so direkt in die gewünschte Transaktion. Dies ist ein häufig verwendetes
Mittel, um Verzweigungen über Transaktionsgrenzen hinweg zu realisieren.
Sobald die gerufene Transaktkion beendet wird, fährt ABAP mit der Ausfüh-
rung der im Porgramm auf die, dem CALL TRANSACTION folgenden Anweisung
fort.
280
Werden zumindest für alle Mussfelder des Eingangsdynpro der gerufenen
Transaktion Werte auf programmtechnischem Weg an die aufgerufene Trans-
aktion übergeben, kann der erste Screen der Transaktion über den Zusatz AND
SKIP FIRST SCREEN übersprungen werden. Als Möglichkeit für die Wertübergabe
kommt derzeit ausschließlich das Konstrukt von Parameter-Ids (SPA/GPA-Pa-
rameter) in Frage.
Der Anweisung CALL TRANSACTION kann mit der USING-Klausel eine Batch-Input-
Tabelle (auch BTC-Tabelle genannt) übergeben werden, die explizite Anwei-
sungen für den Ablauf der Transaktion enthält. Diese Tabelle muss den in Ab-
schnitt 6.4 beschriebenen Aufbau der Data Dictionary-Struktur BDCDATA haben.
Die übergebene Tabelle muss hierbei nicht den vollständigen Transaktionsab-
lauf enthalten. Ähnlich wie bei der Option AND SKIP FIRST SCREEN kann durch die-
sen Mechanismus lediglich eine Vorbelegung der gerufenen Transaktion erfol-
gen. Eine Beschränkung auf Felder der ersten Maske, wie sie bei der zuerst
genannten Option der Fall ist, besteht hierbei nicht. Es können demnach bereits
komplexe Abläufe in der Transaktion durchgeführt werden und dem Benutzer
lediglich ein Kontrollblick auf die erfassten Daten gewährt werden. Dies funk-
tioniert allerdings nur bei Verwendung des Aufrufmodus »E« (siehe unten).
Die übrigen Parameter der Anweisung CALL TRANSACTION machen im Wesentli-
chen bei Verwendung des letztgenannten Mechanismus Sinn. Über CALL TRANS-
ACTION wird eine andere Transaktion in einem eigenen Logical Unit of Work auf-
gerufen. Neben der Tatsache, dass dies bedeutet, dass dem mindestens eine
eigene Transaktion auf Datenbank-Ebene zugeordnet ist, heisst dies auch, dass
beim Abschluss der LUW Aktionen im Rahmen des Verbucherkonzepts von
R/3 stattfinden können. Diese laufen normalerweise asynchron zur Verarbei-
tung des Dialogprozesses in so genannten Verbucherprozessen ab (genaueres
hierzu ist in Kapitel 8 dargestellt). Häufig ist es jedoch nicht wünschenswert,
dass die Verbuchung der mit CALL TRANSACTION gerufenen Transaktionen asyn-
chron zum übrigen Programmlauf erfolgt. Dies gilt insbesondere dann, wenn
mehrere aufeinander aufbauende Transaktionen in Folge aus einem Programm
heraus aufgerufen werden sollen. Wenn ein realer Benutzer diese Folge ausfüh-
ren würde, bildet dies meist kein Problem, da in der Regel die Verbuchung im Kapitel 6 – Batch-Input-Techniken
System schneller ist, als der Benutzer die Aktionen initiiert. Ist der Benutzer
doch schneller, erhält er eine Meldung und wird die Aktion später erneut durch-
führen. Anders verhält es sich, wenn die Transaktionsfolge von einem Pro-
gramm ausgelöst wird. Die erwähnte Verzögerung beim Transaktionswechsel
wird in der Regel vernachlässigbar kurz sein. Auch kann das Programm nur be-
dingt auf die Fehlermeldung reagieren. Das Programmieren von Verzögerungs-
schleifen würde das System insgesamt unnötig belasten und führt zu einem ins-
gesamt schwer beherrschbaren Zustand. Ein Abbruch nach mehreren
erfolglosen Versuchen ist hier auch nicht das beste Mittel, tauchen diese Proble-
me doch häufig auf und würden umfangreiche manuelle Nacharbeiten nach
sich ziehen. Um diese Problematik zu umgehen, bietet die Anweisung CALL
TRANSACTION die Option UPDATE an. Wird hier der Wert »S« übergeben, wird die
281
6.5 Verwendung von CALL TRANSACTION
282
Feldname Datentyp Bedeutung
Tabelle 6.2
Aufbau der Struktur BDCMSGCOLL
Jede Info- (I-), Warnungs- (W-), Fehler- (E-) oder Abbruch- (A-) Meldung, die wäh-
rend der Verarbeitung aufgetreten ist, wird in dieser Tabelle in der Reihenfolge
ihres Auftretens abgelegt.
In der Struktur wird nicht der Klartext der jeweiligen Meldung abgelegt son-
dern die interne Repräsentation der Meldungen, wie sie auch in der SY-Struktur
zur Laufzeit zu finden ist. Mit den hier verfügbaren Informationen kann aller- Kapitel 6 – Batch-Input-Techniken
dings leicht der Klartext der Meldung über einen Aufruf eines passenden Funk-
tionsbausteins (Beispielsweise BAPI_MESSAGE_GET_DETAIL) ermittelt werden.
Der Rückgabewert der Anweisung CALL TRANSACTION wird im Systemfeld SY-SUBRC
als numerischer Fehlercode abgelegt. Der Wert 0 bedeutet, dass während der
Verarbeitung kein Fehler aufgetreten ist. Werte ungleich 0 zeigen eine Fehlersi-
tuation an, der wohl häufigste Fehler wird der Fehler 1001 sein. Dieser bedeutet,
dass ein in der Transaktion auftauchendes Dynpro nicht in der Batch-Input-
Tabelle vorgesehen ist (z.B. ein unerwartet erscheinendes Pop-Up-Fenster).
283
6.5 Verwendung von CALL TRANSACTION
Die Verarbeitung des Batch-Input bricht ab, wenn das Ende der BTC-Tabelle
erreicht, die Transaktion beendet bzw. globaler ausgedrückt, ein COMMIT WORK
abgesetzt wurde (auf diesen Punkt wird in Abschnitt 6.9 noch ausführlicher ein-
gegangen).
In den Feldern ID NUMBER LANGUAGE sowie MESSAGE_V1 bis _V4 können die ent-
sprechenden Felder der Struktur BDCMSGCOLL übergeben werden. Im Parame-
ter TEXTFORMAT kann spezifiziert werden, in welchem Format die Rückgaben
generiert werden sollen. In Frage kommen hier die Werte HTM für HTML, RTF für
Rich Text Format, SCR für SAPScript sowie ASC für die Darstellung im ASCII-
Format. Welches Format hier gewählt wird, hängt vom jeweiligen Anwen-
dungsfall ab.
Bei erfolgreicher Verarbeitung wird im Rückgabeparameter MESSAGE der
Kurztext der Nachricht sowie im Tabellenparameter TEXT der Langtext der
Nachricht in Form von max. 255-Zeichen langen Zeilen zurückgeliefert.
Schlägt die Verarbeitung fehl, wird der aufgetretene Fehler im Rückgabewert
RETURN, welcher den Aufbau der Struktur xx hat, beschrieben.
Weitere Informationen zu diesem Funktionsbaustein können der Dokumen-
tation zum Funktionsbaustein entnommen werden.
284
6.6 Erzeugung einer Batch-Input-Mappe
Alternativ zur direkten Ausführung von Batch-Inputs können diese auch in
Form von so genannten Batch-Input-Mappen im System gesammelt und zu ei-
nem späteren Zeitpunkt ausgeführt werden. Dieses Vorgehen ist insbesondere
bei Datenübernahmen, dem eigentlichen Anwendungsgebiet von Batch-Input,
sinnvoll. In einer solchen Mappe können die BTC-Abläufe von mehreren Trans-
aktionsaufrufen abgelegt werden. Diese Abläufe müssen nicht zwangsweise die
gleiche R/3-Transaktion ausführen. Bei Datenübernahmen oder –migrationen
sind Batch-Input-Mappen mit mehreren tausend Dynpros und hunderten
Transaktionsaufrufen keine Seltenheit. Bei diesen Datenmengen wird häufig
von der Methode Gebrauch gemacht, an Stelle einer großen BTC-Mappe eine
Vielzahl kleinerer Mappen, die gegebenenfalls auch parallel abgespielt werden
können, anzulegen.
Im System werden die BTC-Mappen in der Transaktion SM35 verwaltet (siehe
Abbildung 6.3). BTC-Mappen können hierbei die Zustände.
◗ neu
◗ fehlerhaft
◗ verarbeitet
◗ in Bearbeitung
◗ im Hintergrund
◗ in Erstellung
◗ gesperrt
annehmen. Gruppiert nach diesen Zuständen werden Mappen in der Trans-
aktion SM35 angezeigt.
Batch-Input-Mappen werden von Programmen erzeugt. Diese bedienen sich
hierzu verschiedener Funktionsbausteine, die allesamt in der Funktionsgruppe
SBDC abgelegt sind.
Kapitel 6 – Batch-Input-Techniken
Ähnlich wie beim Schreiben einer Datei, muss eine Batch-Input-Mappe vor dem
Schreiben geöffnet werden und nach Beendigung aller Schreibvorgänge ge-
schlossen werden. Hierfür stehen die Funktionsbausteine BDC_OPEN_GROUP sowie
BDC_CLOSE_GROUP zur Verfügung. Eine Mappe wird mit einem Mappennamen
erstellt, der nicht eindeutig sein muss. SAP vergibt für die erstellten Mappen
eindeutige Bezeichner in Form einer ID.
Zwischen diesen beiden Funktionsaufrufen können in die Mappe beliebig viele
Batch-Input-Abläufe über Aufrufe des Funktionsbausteins BDC_INSERT eingefügt
werden. Die Schnittstellen dieser Funktionsbausteine ist im Abschnitt 6.10 dar-
gestellt.
285
6.6 Erzeugung einer Batch-Input-Mappe
Abbildung 6.3
Transaktion SM35: Batch-Input Mappenübersicht (© SAP AG)
PERFORM BTC_REFRESH..
PERFORM BUILD_BTC. "eigene Routine zum Aufbau des BTC-Ablaufes
PERFORM BTC_TABLE_GET TABLES L_BTC_DATA.
CALL TRANSACTION '<TCODE>'
USING L_BTC_DATA.
ist der übliche Aufbau eines mit Mappen arbeitenden Programmes schematisch
dargesellt
DATA: L_BTC_DATA LIKE BDCDATA OCCURS 0.
PERFORM BTC_REFRESH.
PERFORM BUILD_BTC. "eigene Routine zum Aufbau des BTC-Ablaufes
PERFORM BTC_TABLE_GET TABLES L_BTC_DATA.
286
CALL FUNCTION 'BDC_INSERT'
287
6.8 Der Batch-Input-Recorder
Abbildung 6.4
Benutzeroberfläche des Batch-Input-Recorders (© SAP AG)
In der Liste der Aufzeichnungen werden neben dem Namen der Aufzeichnung
und dem Namen des Erstellers mit Erstellungszeitpunkt auch die Anzahl der in
der Aufzeichnung gespeicherten Transaktionsaufrufe sowie die Anzahl der in-
nerhalb der Aufzeichnung prozessierten Dynpros ausgegeben. Im Beispiel han-
delt es sich um eine sehr einfache Aufzeichnung aus dem Bereich des Material-
stamms.
288
Mit Beendigung der Transaktion gelangt der Benutzer wieder in die Maske des
Batch-Input-Recorders zurück und kann die aufgezeichnete Sequenz speichern
oder weiterverarbeiten.
Abbildung 6.5
Attribute einer neuen Aufzeichnung (© SAP AG)
289
6.8 Der Batch-Input-Recorder
ansonsten die Funktionstasten angesprochen werden. Der Wert /01 würde dem-
nach ein Auslösen der Funktionstaste (F1) bedeuten.
Abbildung 6.6
Ändern einer Aufzeichnung (© SAP AG)
Auf den folgenden Dynpros der Transaktion taucht weiterhin noch der reser-
vierte Feldname BDC_SUBSCR auf (z.B. Zeile 12 der Aufzeichnung). Hier kann de-
finiert werden, welchen Subscreen die Aufzeichnung im jeweiligen Subscreen-
Bereich der Transaktion erwartet. Der dargestellte Ablauf würde beispielsweise
abbrechen, wenn zur Laufzeit im Subscreen-Bereich TABFRA1 des Dynpros SAPLM-
GMM 4004 nicht der Screen SAPLMGMM 2004 angezeigt würde. Diese Anweisungen
sind jedoch für den Batch-Input-Ablauf nicht zwingend erforderlich und kön-
nen demnach im Beispiel ebenfalls ohne Probleme gelöscht werden.
In der in Abbildung 6.6 dargestellten Maske können aufgezeichnete Zeilen
verändert oder auch Zeilen gelöscht oder hinzugefügt werden. Um die Modifi-
kationen zu testen, kann die Tabelle auch erneut abgespielt werden.
290
◗ Speichern einer Batch-Input-Mappe
◗ Erzeugung eines Batch-Input-Programmes
◗ Generieren eines Funktionsbausteins
Abbildung 6.7
Attribute beim Generieren einer BTC-Mappe (© SAP AG)
291
6.8 Der Batch-Input-Recorder
Abbildung 6.8
Generieren eines Batch-Input-Programms (© SAP AG)
Ersterer Fall ist – wie erwähnt – bei der Datenübernahme aus einem Fremdsys-
tem sinnvoll. Soll diese Methode verwendet werden, kann in diesem Fenster
auch die Importdatei definiert werden.
Die Daten des Programms aus der Aufzeichnung zu übernehmen ist insbeson-
dere dann sinnvoll, wenn das Programm als solches nicht direkt weiterverwen-
det werden soll, sondern lediglich als Skelett dient, auf dessen Basis ein eigenes
Programm entwickelt werden soll.
Nach Betätigen des grünen Häckchens erscheinen die üblichen Dynpros, die zur
Anlage eines ABAP-Reports notwenig sind. Im Anschluss daran, steht das ge-
nerierte Programm unmittelbar zur Verwendung im System zur Verfügung.
292
Abbildung 6.9
BTC als Funktionsbaustein ablegen (© SAP AG)
293
6.9 Tipps, Tricks & Fallen
rückgemeldet. Eine Fehlerbehebung auf dieser Ebene ist daher bei Verwendung
dieses Modus ausgeschlossen. Für den produktiven Betrieb bietet sich daher
nur der Mode »N« an.
Falls jedoch Probleme auftreten, wäre es jedoch sehr sinnvoll, die Fehlersituati-
on in der produktiven Umgebung durch sichtbares Abspielen des Batch-Inputs
transparent machen zu können. Da jedoch in Programmen im Produktivsyste-
men keine Programmänderungen durchgeführt werden sollen, müsste stets
eine Programmänderung im Entwicklungssystem mit anschließendem Trans-
port ins Produktivsystem vorgenommen werden. Hierdurch wäre jedoch der
Modus für alle Benutzer des Batch-Input-Programms geändert.
Sinnvoller erscheint hier, den Aufruf-Mode einer Transaktion in Form einer Va-
riable an CALL TRANSACTION zu übergeben. Falls der Programmierer – was eben-
falls die Regel sein dürfte – keine Berechtigung hat, im Produktivsystem Vari-
ablen im Debugger zu ändern, bieten sich die in Kapitel 2 genannten
Möglichkeiten, das Programm von außen beinflussen zu können, an.
Um den Aufruf-Modus eines Batch-Input dynamisch zu gestalten, bieten sich
die folgenden Methoden an, die hier – ergänzend zu den Ausführungen in
Kapitel 2 - in der konkreten Anwendung jeweils kurz skizziert werden.
◗ Funktionscode
◗ Steuertabelle
◗ Benutzerparameter
◗ Detaillierte Informationen zu den jeweiligen Verfahren, können in Kapitel 2
dieses Buches nachgeschlagen werden. An dieser Stelle soll jedoch nochmals
exemplarisch gezeigt werden, wie die dort beschriebenen Techniken ange-
wendet werden.
◗ Zugrunde gelegt werden soll ein Programmfragment, welches den Aufruf-
mode für den CALL TRANSACTION-Aufruf als Variable übergibt. Welcher Wert
übergeben werden soll, wird erst unmittelbar vor Aufruf des Batch-Inputs in
der FORM-Routine GET_CALL_MODE ermittelt.
DATA: L_CALLMODE TYPE C.
...
PERFORM GET_CALLMODE CHANGING L_CALLMODE.
In den folgenden Abschnitten wird jeweils eine Implementierung für die ver-
schiedenen Möglichkeiten der Ableitung des Aufruf-Modus vorgestellt.
294
Setzen des Aufruf-Modus über Funktionscodes
Bei der Methode, Programme über Funktionscodes zu beeinflussen, werden
Funktionscodes genutzt, um den Wert einer oder mehrerer globaler Variablen
zu setzen. Da für den Aufrufmode der CALL TRANSACTION-Anweisung drei Werte
möglich sind, bietet es sich an, diese jeweils durch eigene Funktionscodes abzu-
bilden.
Abgelegt werden soll der aktuelle Modus in der globalen Variable G_CALLMODE,
welche wie dargestellt deklariert ist.
DATA: G_CALLMODE TYPE C VALUE 'N'.
WHEN 'CM_N'.
G_CALLMODE = 'N'.
WHEN 'CM_E'.
G_CALLMODE = 'E'.
...
ENDCASE.
...
295
6.9 Tipps, Tricks & Fallen
Möchte der Benutzer den Aufrufmodus des Batch-Inputs verändern, genügt es,
im Fcode-Fenster im oberen Bereich des SAPGUI den entsprechenden Funkti-
onscode anzugeben und mit (¢) zu bestätigen. Da diese Funktionalität im Nor-
malfall nicht von jedem Benutzer gesehen werden soll, werden meist keine
Menüeinträge hierfür erzeugt.
Der so eingestellte Wert für den Aufrufmodus bleibt solange erhalten, bis die
Transaktion beendet wird oder explizit ein anderer Modus gesetzt wird.
296
Abbildung 6.10
Anlegen von Parameter-Ids im Object Navigator (© SAP AG)
Abbildung 6.11
Parameter-ID anlegen (© SAP AG)
Kapitel 6 – Batch-Input-Techniken
297
6.9 Tipps, Tricks & Fallen
Abbildung 6.12
Benutzerparameter festlegen (© SAP AG)
Auch die Implementierung dieser Routine geht nicht davon aus, dass der Benut-
zerparameter korrekt initialisiert ist. Im Fall eines ungültigen Wertes, wird auch
hier der Wert ‚N‘ zurückgegeben.
298
Verwendung von Steuertabellen
Die wohl aufwendigste Methode, um den Aufrufmodus für die CALL TRANSAC-
TION-Anweisung abzulegen, besteht in der Verwendung von Steuertabellen.
Aufwendig nicht wegen der Implementierung, sondern im Wesentlichen wegen
des Aufwands, eine transparente Tabelle anzulegen und diese mit Werten zu
füllen. Für den Transport zu sorgen usw.. Sie kommt meist dann zum Zuge,
wenn im Rahmen einer umfangreichen Programmierung bereits eine oder meh-
rere Steuertabellen angelegt wurden und somit der beschriebene Aufwand
ohnehin anfällt.
Im diesem Fall soll hierfür eine generische Steuertabelle ZFLIGHT000 verwendet
werden. Der Aufbau der Tabelle wird mit der in Tabelle 6.3 gezeigten Struktur
festgelegt. Die Spalte KEY1 enthält hierbei den Transaktionscode, das Feld KEY2
den Benutzernamen, für den die Einstellung gelten soll. Wird als Benutzername
der Wert »*« gespeichert, soll die Einstellung für alle Benutzer gelten, für die
nicht explizit ein anderer Wert definiert wurde.
Tabelle 6.3
Struktur der generischen Steuertabelle ZFLIGHT000
CHECK SY-SUBRC NE 0.
299
6.9 Tipps, Tricks & Fallen
FROM ZFLIGHT000
WHERE KEY1 = SY-TCODE AND
KEY2 = ‚*‘.
CHECK SY-SUBRC NE 0.
Das Programm versucht durch zweistufiges Lesen, den Aufrufmodus aus der
Tabelle zu ermitteln. Höchste Priorität hat hierbei ein expliziter Tabelleneintrag
für den angemeldeten Benutzer. Schlägt dieser Leseversuch fehl, wird mit dem
generischen Benutzernamen »*« auf die Tabelle zugegriffen. Erst wenn auch
diese SELECT-Anweisung keinen Datensatz zurückliefert, wird der Defaultwert
»N« gesetzt.
2. Nähere Informationen zu LUW und dem Verbucherkonzept in R/3 ist in Kapitel 8 darge-
stellt.
300
blendet oder sind in manchen Fällen Pflichtfelder, in anderen Fällen reine Aus-
gabefelder.
Um einen sicheren Batch-Input-Ablauf zu erstellen, müssten alle beeinflussen-
den Nebenbedingungen bei der Erstellung des Batch-Input-Ablaufs berücksich-
tigt werden. Aufgrund der Komplexität des Systems R/3 ist dies in vielen Fällen
nicht möglich.
Bei der Analyse einer Transaktion, für die ein Batch-Input erstellt werden soll,
müssen daher alle erkennbaren relevanten Randbedingungen ausgewertet und
darauf reagiert werden. In der Regel genügt dieses Vorgehen, um einen ausrei-
chend stabilen Batch-Input zu erstellen. Selbst bei sorgfältigster Arbeit ist man
dabei jedoch nicht gegen Änderungen im Customizing gefeit, die den mühsam
erstellten Batch-Input-Ablauf erneut zum scheitern bringt.
In manchen Fällen muss man jedoch auch einsehen, dass dies mit vertretbarem
Aufwand nicht möglich ist und die Transaktion als nicht Batch-Input-geeignet
bezeichnet werden muss. Anders als der im vorigen Abschnitt beschriebene
Umstand ist der hier beschriebene Sachverhalt daher keine technische Ein-
schränkung im System R/3, sondern liegt vielmehr auf der Anwendungsebene
begründet.
301
6.10 Verwendete und wichtige Funktionsbausteine
An dieser Stelle nochmals ganz explizit der Hinweis: Achten Sie auf unter-
schiedliche Fenstergrößen. Sobald die Anzahl der sichtbaren Listenzeilen vari-
ieren kann, dürfen die Blätterfunktionen nicht genutzt werden, um auf einen be-
stimmten Satz zu positionieren.
6.10.1 BDC_CLOSE_GROUP
Schließt die zuvor mit BDC_OPEN_GROUP geöffnete Batch-Input-Mappe.
Import-Parameter
Keine
Export-Paramter
Keine
Exceptions
302
6.10.2 BDC_INSERT
Fügt Ablauf-Daten für eine Dialogtransaktion in die geöffnete Batch-Input-
Mappe ein.
Import-Parameter
POST_LOCAL Schaltet die lokale Verbuchung ein, d.h. die Verbuchung erfolgt
nicht in einem Verbuchertask sondern im Dialogprozess, in dem
auch die Transaktion selbst abläuft
Tabellen-Parameter
DYNPROTAB Batch-Input-Tabelle
Exceptions
6.10.3 BDC_OPEN_GROUP
Öffnet eine neue Batch-Inputmappe und legt deren Eigenschaften fest.
Kapitel 6 – Batch-Input-Techniken
Import-Parameter
CLIENT Mandant
303
6.10 Verwendete und wichtige Funktionsbausteine
USER Benutzerkennung
Export-Parameter
Exceptions
304
Einplanen von
Hintergrundjobs
7
7.1 Jobs in SAP R/3
In heutigen Client/Server-Systemen existiert neben dem, auf kurze Antwortzei-
ten optimierten Dialogbetrieb ein, im Hinblick auf Datendurchsatz optimierter,
Batchbetrieb.
Die auszuführenden Aufgaben für den Batch-Mode werden in Form so genann-
ter Jobs definiert und bis zur tatsächlichen Ausführung zwischengespeichert.
Da ein Job immer im Hintergrund, also ohne Bezug zu einem GUI abläuft, wer-
den die Ausgaben eines Jobs in Form einer Spoolliste im System abgelegt.
Ein Job in R/3 besteht neben den Verwaltungsinformationen, die unter ande-
rem auch die Startoptionen des Jobs beinhalten (siehe unten), aus einem oder
mehreren Verarbeitungsschritten, den so genannten Jobsteps. Bei diesen han-
delt es sich entweder um einen ABAP-Report, ein – vom Systemadminstrator
definiertes externes Programm oder ein beliebiges Kommando auf der Ebene
des Betriebssystems. Für jeden Jobstep einzeln können die Ausgabeparameter
festgelegt werden, die zur Ausgabe der Spoolliste verwendet werden.
Wenn alle Schritte, die zu einem Job gehören, erfasst wurden, wird der Job ab-
geschlossen und mit Startoptionen versehen. Diesen Vorgang nennt man auch
freigeben oder einplanen. Ein Job kann entweder bei der Freigabe sofort gestar-
tet werden, zu einem späteren definierten Zeitpunkt oder bei Eintreten eines be-
stimmten Ereignisses. Näheres zu den hier verfügbaren Optionen wird an den
entsprechenden Stellen in diesem Kapitel erläutert.
Die Jobs werden vom System abgelegt und zu gegebener Zeit gestartet. Hierbei
werden alle zum Job gehörigen Steps nacheinander sequentiell abgearbeitet. Die
Verarbeitung der Schritte erfolgt in speziellen Workprozessen den Batch-Pro-
zessen. Den Bereich der Jobverwaltung und –ausführung in R/3 nennt man die
Hintergrundverwaltung/Hintergrundverarbeitung.
305
7.2 Erstellen eines einfachen Jobs
In diesem Kapitel werden mehrere Arten gezeigt, wie Jobs und Jobschritte er-
zeugt werden können. Die Vielzahl von Optionen, speziell im Bereich der exter-
nen Kommandos, können hier jedoch nicht vollständig abgebildet werden. Die
Ausführungen an dieser Stelle beschränken sich daher darauf, ABAP-Reports
im Rahmen der Hintergrundverarbeitung zu verarbeiten.
306
EXPORT
JOBCOUNT
EXCEPTIONS
CANT_CREATE_JOB
INVALID_JOB_DATA
JOBNAME_MISSING
307
7.2 Erstellen eines einfachen Jobs
EXCEPTIONS
BAD_PRIPARAMS
BAD_XPGGLAGS
INVALID_JOBDATA
JOBNAME_MISSING
JOB_NOTEX
JOB_SUBMIT_FAILED
LOCK_FAILED
PROGRAM_MISSING
PROG_ABAP_AND_EXTPG_SET
308
Feldname Datentyp Bedeutung
Tabelle 7.1
Aufbau der Dictionary-Struktur PRI_PARAMS
309
7.2 Erstellen eines einfachen Jobs
Von der Vielzahl der hier definierten Parameter ist lediglich die Angabe des
Ausgabegerätes (PDEST) notwenig. Die übrigen Parameter werden bei Bedarf
automatisch ermittelt.
Die übrigen Felder der Stuktur sind selbst sprechend und können bei Bedarf
versorgt werden. Der Funktionsbaustein versucht intern durch einen Aufruf der
Funktion GET_PRINT_PARAMETERS etwaige fehlende Angaben selbst zu ermitteln.
Falls dies nicht gelingt, wird die Ausnahme BAD_PRIPARAMS ausgelöst.
310
Abbildung 7.1
Definition eines Jobsteps im Dialog (Transaktion SM37) (© SAP AG)
311
7.3 Freigeben und Einplanen eines Jobs
312
JOB_NOSTEPS
JOB_NOTEX
LOCK_FAILED
313
7.3 Freigeben und Einplanen eines Jobs
314
Abbildung 7.2
Pflegen von Eventbezeichnungen (SM62) (© SAP AG)
In der Transaktion lässt sich lediglich ein Eventname mit dazugehöriger Erläu-
terung definieren. Bei der Verwendung von Events besteht zusätzlich die Mög-
lichkeit, den Event mit Parametern zu versorgen. Nur wenn der bei Aufruf von
JOB_CLOSE definierten Eventparameter exakt mit den beim Auslösen des Events
FUNCTION BP_EVENT_RAISE
IMPORT
EVENTID
EVENTPARAM
TARGETINSTANCE
EXCEPTIONS
SUBMIT_FAILED
315
7.3 Freigeben und Einplanen eines Jobs
316
7.4 Eingeplante Jobs freigeben
Wurde ein Job durch einen Aufruf des Funktionsbausteins JOB_CLOSE zwar ein-
geplant, aber nicht freigegeben, kann dies durch einen späteren Aufruf des
Funktionsbausteins JOB_RELEASE nachgeholt werden.
FUNCTION JOB_RELEASE
IMPORT
JOBNAME
JOBCOUNT
EXCEPTIONS
MISSING_JOBNAME
MISSING_JOBCOUNT
MISSING_START_DATE
STATUS_NOT_SCHEDULED
CANT_ENQ_JOB
CANT_START_JOB_IMMEDIATE
NO_PRIVILEGE_TO_RELEASE_JOB
CANT_RELEASE_JOB
JOB_NOT_EXIST
JOB_HAVE_NO_STEPS
ERROR_JOB_MODIFY
Zur Identifikation des Jobs genügt auch hier der Jobname (JOBNAME) zusammen
mit der Jobnummer (JOBCOUNT). Wurde der Job – vorrausgesetzt er existiert über-
haupt – noch nicht eingeplant, d.h. mit Startoptionen versehen, oder besitzt der
Benutzer, unter dessen Namen der Funktionsbaustein aufgerufen wird, nicht
die Berechtigung, Jobs freizugeben, bricht der Funktionsbaustein mit einer Aus-
nahme ab.
317
7.6 Einplanen eines Reports als Job
Dem Funktionsbaustein kann lediglich der Name des Reports sowie der Name
der Report-Variante, mit der der Report gestartet werden soll, übergeben wer-
den. R/3 generiert daraus einen Job, der nur einen Step enthält und plant diesen
mit sofortigem Start ein.
Auf diese Weise kann mit einem einzigen Funktionsaufruf eine Verarbeitung im
Hintergrund gestartet werden.
7.7.1 BP_EVENT_RAISE
Löst ein Ereignis aus und startet damit alle Jobs, die in Abhängigkeit zu diesem
Ereignis definiert und freigegeben wurden.
Import-Parameter
Exceptions
318
7.7.2 JOB_CLOSE
Mit dem Funktionsbaustein JOB_CLOSE wird ein zuvor mit JOB_OPEN erzeugter Job
geschlossen und freigegeben. Der Funktionsbaustein bietet ein Reihe von Para-
metern, um sämtliche Startmöglichkeiten für Jobs zu realisieren.
Import-Parameter
CALENDAR_ID Kalender-ID
EVENT_PARAM Eventparameter
STARTDATE_RESTRICTION
319
7.7 Verwendete Funktionsbausteine
Import-Parameter
START_ON_WORKDAY_NOT_BEFORE
START_ON_WORKDAY_NUMBER
WORKDAY_COUNT_DIRECTION
RECIPIENT_OBJ
TARGETSERVER
Export-Paramter
Exceptions
7.7.3 JOB_OPEN
Mit dem Funktionsbaustein JOB_OPEN wird ein neuer Job erzeugt. Der Funktions-
baustein erhält mindestens den Namen des neuen Jobs, der nicht eindeutig sein
muss und in der Regel auch nicht ist.
Die Felder SDLSTRTDT und SDTSTRTTM, mit denen in früheren Releaseständen das
Startdatum des Jobs definiert werden konnte, sollen im aktuellen Release 4.6
nicht mehr verwendet werden. Das Startdatum des Jobs wird über die entspre-
chenden Parameter des Funktionsbausteins JOB_CLOSE definiert.
320
Über den Rückgabeparameter JOBCOUNT wird im Erfolgsfall die Jobnummer
zurückgeliefert. Zusammen mit dem Jobnamen bildet die Jobnummer den ein-
deutigen Zugriffsschlüssel für die übrigen Funktionsbausteine.
Import-Parameter
Export-Paramter
Exceptions
7.7.4 JOB_RELEASE
Über den Funktionsbaustein JOB_RELEASE kann ein eingeplanter, aber noch nicht
freigegebener Job zur Verarbeitung freigegeben werden. Voraussetzung hierfür
ist, dass der Job existiert, mindestens einen Jobstep enthält und eingeplant ist.
Import-Parameter
JOBCOUNT Jobnummer
Exceptions
321
7.7 Verwendete Funktionsbausteine
Import-Parameter
7.7.5 JOB_SUBMIT
Mit dem Funktionsbaustein JOB_SUBMIT wird an einen, zuvor durch einen Aufruf
des Funktionsbausteins JOB_OPEN erzeugten, Job ein Verarbeitungsschritt ange-
fügt.
Über die entsprechenden Felder der Aufrufschnittstelle kann entweder ein ex-
ternes Kommando, ein externes Programm oder ein ABAP-Report übergeben
werden. Werden zuviele Felder gefüllt, bricht der Funktionsbaustein mit einer
Exception ab.
Zurückgeliefert wird im Erfolgsfall die Nummer des neu erzeugten Jobsteps
innerhalb des übergebenen Jobs.
Import-Parameter
OPERATINGSYSTEM Betriebssystem
322
Import-Parameter
JOBCOUNT Jobnummer
JOBNAME Jobname
Export-Paramter
Exceptions
323
7.7 Verwendete Funktionsbausteine
Exceptions
Import-Parameter
7.7.6 SIMPLE_BATCH_JOB
Der Funktionsbaustein SIMPLE_BATCH_JOB stellt eine vereinfachte Form dar, einen
Job zu definieren, der aus nur einem Schritt besteht. Bei dem einen Schritt des
Jobs muss es sich um einen ABAP-Report handeln .
Wenn der Job fehlerfrei erstellt und eingeplant werden konnte, liefert der Funk-
tionsbaustein kein Ergebnis. Im Fehlerfall wird die Exception ausgelöst.
Import-Parameter
Exceptions
324
Programmierung mit
Verbuchern
8
Wie bei allen Datenverarbeitungssystemen, die Daten speichern, bietet auch R/3
ein Transaktionskonzept, bei dem sichergestellt ist, dass Veränderungen am Da-
tenbestand, die während der gesamten Verarbeitung auftreten, entweder voll-
ständig oder gar nicht durchgeführt werden.
Gängiges Beispiel für ein solches Konzept sind Geldbewegungen auf Konten.
Eine Transaktion besteht hierbei mindestens aus einer Sollbuchung und einer
Habenbuchung (ggf. fallen weitere Daten zur Protokollierung z.B. in einem
Journal an). Es muss hierbei sichergestellt werden, dass entweder beide Bu-
chungen oder keine der Buchungen durchgeführt wird. Andernfalls würde ein
inkonsistenter Datenbestand (in SAP-Sprache »Datenschiefstand«) produziert.
In R/3 wird dies erreicht, indem ein Transaktionskonzept auf der Anwen-
dungsebene eingeführt wurde. Der Benutzer bewegt sich hierbei immer inner-
halb einer Transaktion. Diese beginnt mit dem Programmstart auf höchster Ebe-
ne und endet entweder implizit mit dem Ende dieses Programms oder explizit
durch Aufruf des Kommandos COMMIT WORK zum Bestätigen der Änderungen
oder ROLLBACK WORK, um die Datenänderungen zu verwerfen. Dieses – vom
Transaktionskonzept der darunter liegenden Datenbankprodukte abweichende
– Konzept ist aufgrund der Client-Server-Architektur des Systems R/3 notwen-
dig, welches im Folgenden kurz beschrieben werden soll. Eine ausführliche Be-
schreibung der Konzepte und Techniken kann im Buch »Die Technologie des
Systems R/3« von Rüdiger Buck-Emden gefunden werden. Im Anschluss daran
werden die Programmiertechniken für ABAP beschrieben, mit denen der Pro-
grammierer aktiv die Konzepte von R/3 nutzen kann, um asynchrone Programm-
abläufe bei der Verbuchung zu realisieren.
325
8.1 Architektur von R/3
326
SAP-GUI SAP-GUI SAP-GUI SAP-GUI Web-Browser Web-Browser Web-Browser
DB-Server
Abbildung 8.1
Systemarchitektur von R/3
327
8.1 Architektur von R/3
8.1.2 Workprozesse
Die Verabeitung der Anwendungslogik erfolgt innerhalb der Applikationsser-
ver in den so genannten Workprozessen. Es handelt sich hierbei um die Einhei-
ten im System, in denen die Verarbeitung der ABAP-Programme und somit die
gesamte Anwendungslogik von R/3 erfolgt.
Bei den Programmmodulen der Workprozesse handelt es sich jedoch auch nicht
um monolitische Blöcke. Vielmehr bestehen die Workprozesse aus drei Modu-
len, dem Dialogprozessor, dem ABAP-Prozessor sowie der Datenbank-Schnitt-
stelle (siehe Abbildung 8.2).
Abbildung 8.2
Aufbau von Workprozessen
328
R/3 definiert die folgenden fünf Prozesstypen:
◗ Dialogprozesse
◗ Batch-Prozesse
◗ Verbucher
◗ Spoolprozesse sowie
◗ Enqueue-Prozesse.
Wieviele Workprozesse auf einem Applikationsserver gleichzeitig ablaufen,
hängt von der Leistungsfähigkeit der zugrunde liegenden Hardware ab. Wel-
chen Typ diese Workprozesse haben, kann – bei Bedarf von verschiedenen
Parametern abhängig – von den Systemadministratoren des R/3-Systems konfi-
guriert werden.
Jeder Benutzer, der sich an einem R/3-System anmeldet, tut dies an einem be-
stimmten Applikationsserver, der unter Umständen durch Lastverteilungsme-
chanismen (Load Balancing) ausgewählt wurde. Während der gesamten An-
meldung werden alle Anfragen von diesem einen Server abgearbeitet.
Dialogprogramme oder Online-Reports werden hierbei von den Dialogprozes-
sen verarbeitet. Jedesmal, wenn das SAPGUI mit dem Applikationsserver in
Verbindung tritt, ist daran ein Dialogprozess beteiligt, der die Verarbeitung des
jeweiligen Programmschrittes durchführt. Zunächst übernimmt der Dialogpro-
zessor die Dialogsteuerung und nimmt bei Bedarf den ABAP-Prozessor zuhilfe.
Aufgrund der Architektur des Systems kann es sich hierbei jedesmal um einen
anderen Workprozess handeln, denn die Workprozesse des R/3-Systems sind
nicht an einen Benutzer gebunden (siehe Abbildung 8.3). Nach der Verarbei-
tung des jeweiligen Dialog- oder Programmschrittes werden die Ressourcen des
Workprozesses wieder vollständig freigegeben und der Prozess steht für die
329
8.1 Architektur von R/3
Abbildung 8.3
Verteilung der Benutzeranfragen auf die (Dialog-) Workprozesse
Am Abschluss jeder SAP-LUW (siehe Abschnitt 8.2) erfolgt die Verbuchung der
durchgeführten Datenbankänderungen. Um diese – oftmals zeitintensiven –
Operationen in der Datenbank durchzuführen, stehen spezielle Prozesse, die
Verbucher zur Verfügung. Sie haben – wie Batch-Prozesse – keine Möglichkeit,
eine Dialogverarbeitung durchzuführen. In der Regel dienen Verbucher ledig-
lich dazu, Datenveränderungen in der Datenbank persistent zu speichern. SAP
unterscheidet hierbei zwischen V1- und V2-Verbuchern. Der Unterschied zwi-
schen diesen beiden Workprozesstypen ist der, dass V1-Verbucher zeitnah zum
auslösenden COMMIT WORK aufgerufen werden, während V2-Vebucher - mit einer
wesentlich niedrigeren Priorität ausgestattet – unter Umständen wesentlich
später durchgeführt werden. Innerhalb von R/3 werden V1-Verbucher in der
Regel verwendet, um die Anwendungsdaten einer Transaktion asynchron aber
dennoch zeitnah zu speichern. V2-Verbucher hingegen werden verwendet, um
unkritische Daten, wie beispielsweise die Fortschreibung von Datenverdichtun-
gen, die nicht unmittelbar die Anwendungsdaten berühren, durchzuführen.
Sämtliche Druckausgaben – gleich auf welches Medium – werden von so ge-
nannten Spool-Prozessen verarbeitet. In diesen Prozessen findet die Aufberei-
tung und die Kommunikation mit den jeweiligen Ausgabegeräten (Drucker,
Fax-Server o.ä.) statt.
Der Enqueue-Prozess schließlich ist dafür zuständig, die Sperren innerhalb des
SAP-Systems zu verwalten. R/3 bietet dem Programmierer ein Sperrkonzept
auf Anwendungsebene, d.h. Sperren werden nicht auf der Ebene der Daten-
bank-Tabelle oder auf Satzebene gesetzt sondern auf der Ebene der betriebs-
wirtschaftlichen Objekte. Hierzu werden nicht die Sperrmechanismen der je-
weiligen Datenbank-Produkte verwendet. In jedem R/3-System existiert genau
ein Workprozess, der diese Sperrobjekte verwaltet. Näheres zum Sperrkonzept
und dem Enqueue-Prozess kann aus Kapitel 9 entnommen werden.
330
Mit Ausnahme der beiden zuletzt genannten Workprozess-Typen können die
Workprozesse gezielt zur Realisierung von asynchronen, d.h. voneinander un-
abhängigen Programmsträngen während der Verbuchung verwendet werden.
Um die Konsistenz der Daten auch über parallele Ausführungspfade hinweg zu
gewährleisten, stellt R/3 das Konzept von logischen Programmeinheiten zur
Verfügung. Bevor auf die jeweiligen Programmiertechniken zur Nutzung dieser
Möglichkeiten eingegangen wird, soll im Folgenden ein Überblick über diese
Programmeinheiten (auch Logical Unit of Work, kurz LUW, genannt) gegeben
werden.
8.2.1 Datenbank-LUWs
Fast alle relationalen Datenbanksysteme kennen das Konzept der Transaktions-
sicherheit. Dieses ist aus der Notwendigkeit heraus entstanden, dass Verände-
rungen am Datenbestand der Datenbank in der Regel nicht in einem Schritt
331
8.2 Logical Units of Work
Transaktion gestartet werden kann, muss zuvor die aktive Transaktion beendet
werden. Gleichzeitig gilt jedoch, dass ein Workprozess nicht exklusiv für einen
Benutzer zur Verfügung steht, woraus sich ableitet, dass ein Transaktionskon-
zept auf Anwendungsebene nicht mit den Mitteln der Transaktionen auf Daten-
bank-Ebene abgewickelt werden kann. Selbst wenn ein Dialogprozess exklusiv
für eine R/3-Transaktion zur Verfügung stünde, wäre das Verbucherkonzept in
seiner realisierten Form nicht möglich, da spätestens in diesem Falle ein Wech-
sel des Workprozesses notwendig würde.
Datenbank
Abbildung 8.4
Zugriff der Workprozesse auf die Datenbank
In R/3 wird dieses Problem dadurch gelöst, dass ein eigenes Transaktionskon-
zept, welches auf den so genannten SAP-LUW basiert, etabliert wurde. Dieses
verwendet im »kleinen« zwar die Funktionalität der Datenbank-Transaktionen,
definiert im Ganzen gesehen jedoch einen eigenen Transaktionsbegriff. Tatsäch-
lich ist es so, dass jeder Workprozess, eine neue Datenbank-LUW eröffnet, so-
bald er einen neuen Kontext (bei Dialogtransaktionen z.B. einen Dialogschritt)
zur Ausführung zugewiesen bekommt. Sobald der jeweilige Dialogschritt ab-
geschlossen ist und der Workprozess zur Bearbeitung eines anderen Kontextes
vorbereitet wird, wird auch die zugrunde liegende Datenbank-LUW ab-
geschlossen. Hierdurch wird gewährleistet, dass alle Veränderungen auf der
Ebene der Datenbank konsistent durchgeführt werden können.
8.2.2 SAP-LUW
Auf Anwendungsebene hat der Begriff Transaktion einen wesentlich größeren
Umfang, als auf Datenbank-Ebene. Mit Beginn einer Dialogtransaktion beginnt
auch eine SAP-LUW. Diese endet entweder implizit mit dem Ende des Dialog-
programms oder explizit durch Aufruf der ABAP-Kommandos COMMIT WORK oder
ROLLBACK WORK zum Bestätigen bzw. Abbrechen der Transaktion. Jeder Dialog-
332
schritt der SAP-LUW kann hierbei von einem anderen Workprozess und dem-
entsprechend in einer eigenen Datenbank-LUW durchgeführt werden (Abbil-
dung 8.5). Sämtliche Änderungen am Datenbestand werden hierbei in eigenen
Tabellen des R/3-Systems mitgeführt und erst am Ende der Dialogtransaktion
in einem speziellen Prozess, dem Verbucher-Task, in einer einzigen Datenbank-
LUW transaktionssicher in den Anwendungstabellen der Datenbank fortge-
schrieben.
Abbildung 8.5
Verteilung der Dialogschritte auf die Workprozesse
333
8.3 Asynchrone Programmiertechniken
334
Anschluss daran beginnt die eigentliche Verbuchung. Hierzu werden in einem
Verbucher-Workprozess die Verbuchungsbausteine mit höherer Priorität (V1-
Verbucher) abgearbeitet. Diese Verbuchung läuft asynchron aber zeitnah mit
der Dialogverarbeitung. Mit geringerer Priorität werden die V2-Verbucherbau-
steine in den entsprechenden Workprozessen verarbeitet.
Nach erfolgreicher Verarbeitung der V1-Verbucher werden etwaige noch beste-
hende Sperreinträge aufgehoben, um den produktiven Datenbestand wieder
für andere LUW freizugeben. Nicht zuletzt aus diesem Grund heraus ist es an-
zuraten, Änderungen nicht an den operativen Unternehmensdaten in einem V2-
Verbucherbaustein durchzuführen.
Wenn alle Verbucherbausteine erfolgreich verarbeitet wurden, ist die LUW
vollständig abgeschlossen.
G_INT = 1.
PERFORM WRITE_INT.
PERFORM WRITE_INT ON COMMIT.
G_INT = 5.
PERFORM WRITE_INT.
PERFORM WRITE_INT ON COMMIT.
G_INT = 7.
COMMIT WORK.
335
8.3 Asynchrone Programmiertechniken
...
FORM WRITE_INT.
WRITE / G_INT.
ENDFORM.
liefern.
Der erste – synchrone – Aufruf der Routine WRITE_INT würde den aktuellen Wert
1 der Variable G_INT zur Ausgabe bringen. Zum Zeitpunkt des zweiten Aufrufs
der Routine hat die Variable zwar ebenfalls den Wert 1, jedoch erfolgt die Aus-
führung dieses Aufrufs erst innerhalb der Verbuchung des Programms, zu dem
die Variable den Wert 7 enthält.
Im Folgenden wird die Routine WRITE_INT nochmals synchron und asynchron
aufgerufen. Hierbei erkennt man eine weitere Einschränkung der Verwendung
von ON COMMIT zur Verbuchung. Jede FORM-Routine wird bei diesem Verfahren
maximal einmal aufgerufen. Weitere PERFORM ... ON COMMIT werden vom System
ignoriert, würden sie doch die gleichen Verarbeitungen auf den gleichen Daten
erneut durchführen.
336
SAP unterscheidet hierbei zwischen V1-Verbuchern und V2-Verbuchern. Diese
Unterscheidung wird in den Eigenschaften des Funktionsbausteins getroffen
(siehe Abbildung 8.6). Die Festlegung erfolgt hier durch die Definition des Pro-
zesstypen für den Baustein.
Abbildung 8.6
Verbucherbausteine anlegen (© SAP AG)
337
8.3 Asynchrone Programmiertechniken
aufgerufen hat, wird mit einer Express-Mail auf die Fehlersituation hingewiesen
und kann diesen in der Transaktion SM13 (siehe Abbildung 8.7) analysieren. Falls es
sich lediglich um einen korrigierbaren Fehler handelt, kann der Benutzer den Ver-
bucher erneut starten und ggf. zum positiven Abschluss bringen.
Verbucherbausteine vom Typ »Start sofort, nicht nachverbuchbar« sind eben-
falls V1-Verbucher. Im Gegensatz zu den zuvor genannten V1-Verbuchern be-
steht hierbei jedoch nicht die Möglichkeit der Nachverbuchung in der Transak-
tion SM13. Tritt während der Verarbeitung eines solchen Bausteins ein Fehler auf,
wird die Verbuchung abgebrochen und die LUW beendet. Der Benutzer be-
kommt diesen Zustand ebenfalls per Express-Mail mitgeteilt, kann jedoch nicht
mehr in den Ablauf eingreifen, um den Fehler zu korrigieren.
Abbildung 8.7
Verbuchungsmonitor (Transaktion SM13) (© SAP AG)
Ein Funktionsbaustein wird als V2-Verbucher definiert, indem er mit dem Pro-
zesstyp »Verbuchung mit Start verzögert« angelegt wird. Diese Funktionsbau-
steine werden mit geringerer Priorität als V1-Verbucher ausgeführt. Sie laufen
immer in einer eigenen Datenbank-LUW ab.
Die weitere Implementierung der Verbucherbausteine erfolgt identisch wie die
von normalen Funktionsbausteinen. Der Programmierer sollte jedoch immer
den asynchronen Programmablauf bedenken. Die Verwendung globaler Vari-
ablen und andere, von Umgebungsbedingungen abhängige Annahmen verbie-
ten sich daher.
338
Aufruf von Funktionsbausteinen im Verbucher
Der Aufruf von Verbucherbausteinen ist fast identisch mit dem Aufruf norma-
ler Bausteine. Soll beispielsweise der Funktionsbaustein Z_VERBUCHER im Rahmen
der Verbuchung aufgerufen werden, würde der Aufruf folgendes Aussehen
haben:
CALL FUNCTION 'Z_VERBUCHER' IN UPDATE TASK
EXPORTING
....
TABLES
.....
EXCEPTIONS
....
Der Aufruf unterscheidet sich lediglich durch den Zusatz IN UPDATE TASK von ei-
nem synchronen Aufruf. Die übrigen Möglichkeiten der Parameterübergabe
sind von diesem Konzept unberührt. Im Gegensatz zu FORM-Routinen, die mit
dem Zusatz ON COMMIT aufgerufen werden können, besteht bei Verbucherbaustei-
nen demnach die Möglichkeit Parameter zu übergeben. Diese werden zum Zeit-
punkt des Aufrufs in Verbuchertabellen zwischengespeichert. Anders als bei
den zuvor genannten Unterprogrammen enthalten Parameter von Verbucher-
bausteinen während der Ausfühung des Bausteins die Werte, die zum Zeit-
punkt des Funktionsaufrufes aktuell waren und nicht die Werte, die zum Zeit-
punkt der Funktionsausführung aktiv sind.
Wird ein Funktionsbaustein im Rahmen einer Transaktion mehrfach aufgeru-
fen, wird er auch im Rahmen der Verbuchung mehrmals mit den jeweiligen
Parametern ausgeführt.
Ob ein Verbucherbaustein im V1-Verbucher oder im Rahmen der V2-Verbu-
339
8.3 Asynchrone Programmiertechniken
340
Der aufgerufene Funktionsbaustein muss hierbei den bislang noch nicht er-
wähnten Prozesstyp »Remote Function Call unterstützt« besitzen. Dieser Typ
kennzeichnet Funktionsbausteine als über RFC aufrufbar. Der Funktionsbau-
stein kann jedoch auch innerhalb eines R/3-Systems normal aufgerufen wer-
den.
Der Aufruf des Funktionsbausteins im Zielsystem erfolgt durch Hinzufügen der
Zieladresse an den CALL FUNCTION-Aufruf. Dies geschieht in der Form
CALL FUNCTION <Funktionsname>
DESTINATION <Zielsystem>
...
würde – genauso wie obiger synchroner Aufruf – in einer eigenen LUW ablau-
fen. R/3 bündelt hierbei alle entfernten Funktionsaufrufe in ein System zu einer
eigenen LUW, d.h. nicht jeder Funktionsaufruf bildet für sich genommen eine
LUW im fremden System, sondern alle Funktionsaufrufe in einem Fremdsys-
tem werden in einer LUW abgearbeitet.
Dieser Mechanismus des asynchronen Funktionsaufrufs in fremden Systemen
wird in R/3 unter dem Begriff »transaktionaler RFC« (tRFC) zusammengefasst.
Das Konzept der transaktionalen RFC beinhaltet zusätzlich, dass das Fremdsys-
tem zum Zeitpunkt des Funktionsaufrufes nicht unbedingt verfügbar sein
341
8.3 Asynchrone Programmiertechniken
muss. Ist dies nicht der Fall, plant R/3 den Funktionsaufruf im Rahmen der Hin-
tergrundverarbeitung ein und versucht in Abständen von 15 Minuten bis zu 30
Mal die Funktion im fremden System zu starten. Ein anderes Konzept asynchro-
ner Funktionsaufrufe, die eine Verfügbarkeit des fremden Systems voraussetzt,
wird in R/3 unter dem Namen »asynchroner RFC« (aRFC) geführt. Nähere In-
formationen hierzu und zur Programmierung von RFC-Bausteinen im Allge-
meinen findet sich in der SAP-Dokumentation »RFC-Programmierung in
ABAP«.
Zusammenfassend kann gesagt werden, dass Funktionsbausteine in einer ande-
ren LUW unter Zuhilfenahme der RFC-Schnittstelle von R/3 erfolgen können.
Diese können entweder synchron über den Zusatz DESTINATION des Kommandos
CALL FUNCTION oder asynchron als transaktionaler RFC über den Zusatz DESTINA-
TION ... IN BACKGROUND TASK erfolgen. Der aufgerufene Funktionsbausein kann –
je nach Definition der RFC-Ziele im jeweiligen System – im gleichen oder in
anderen Systemen als dem aktuellen R/3-System erfolgen.
342
Programmieren mit
Sperren
9
9.1 Allgemeines zu Sperrmechanismen
In einer Client/Server-Umgebung wie in R/3 arbeiten viele Benutzer mit dem
gleichen Datenbestand. Sperrmechanismen verhindern hierbei, dass mehrere
Benutzer zum gleichen Zeitpunkt versuchen, auf dieselben Anwendungsobjek-
te zuzugreifen. Die ist beim konkurrierenden Schreibzugriff mehrerer Benutzer
unbedingt erforderlich, kann aber auch beim Lesenden Zugriff notwendig sein,
um zu verhindern, dass ein anderer Benutzer die angezeigten Daten verändert.
Um den Datenbestand in der Datenbank konsistent zu halten, ist es daher nicht
nur notwendig, ein Transaktionskonzept zu realisieren, um Datenänderungen
zu bündeln, sondern auch, konkurrierende Zugriffe auf Anwendungsobjekte zu
verhindern.
Die Datenbankprodukte bieten in der Regel Mechanismen, um einzelne oder
mehrere Datensätze oder ganze Tabellen zu sperren. Es gibt im Wesentlichen
zwei Gründe, warum diese Sperrmechanismen in R/3 keine Verwendung finden.
Zum einen haben diese Sperren in der Regel für die Dauer einer Datenbank-
Transaktion, im Umfeld von R/3 also einer Datenbank-LUW Bestand. In R/3 ist
der Kontext, währenddessen auf ein Anwendungsobjekt exklusiv zugegriffen
werden soll, jedoch wesentlich länger als eine Datenbank-LUW. Daher muss die
Möglichkeit bestehen, Objekte für die Dauer einer SAP-LUW gegen Zugriff von
anderen Programmen zu schützen. Diese Zugriffe können unter Umständen von
verschiedenen Workprozessen, in Ausnahmefällen sogar von verschiedenen Ser-
vern aus erfolgen. Hierfür bieten die Datenbank-Hersteller keine Lösung.
Zum anderen ist es auf der Ebene der Datenbank lediglich möglich, Sperren auf
die im Meta-Modell der Datenbank enthaltenen Objekte zu setzten. Im Beispiel
der R/3 zugrunde liegenden Datenbanken handelt es sich hierbei um Relatio-
nen, also Tabellen. Das Meta-Modell von R/3 basiert jedoch nicht auf Relatio-
343
9.2 Der Sperrmechanismus von R/3
344
R/3 unterscheidet verschiedene Sperrmodi. Sperren können hierbei entweder
als Lesesperre oder als Schreibsperre realisiert werden. Bei Schreibsperren wird
wiederum zwischen normalen Schreibsperren und erweiterten Schreibsperren
unterschieden.
Eine Lesesperre bedeutet hierbei, dass ein Programm ein Anwendungsobjekt
dahingehend kennzeichnet, dass es darauf lesend zugreift. Andere Programme
können gleichzeitig ebenfalls Lesesperren auf das gleiche Objekt setzten. Ver-
sucht ein Programm jedoch eine Schreibsperre auf das Objekt zu setzten, schei-
tert dies, da durch einen schreibenden Zugriff die von anderen Programmen an-
gezeigten Daten verändert würden.
Andersherum kann keine Lesesperre gesetzt werden, wenn ein Objekt bereits
mit einer Schreibsperre versehen ist.
Im Gegensatz zur erweiterten Schreibsperre kann ein Programm bei der norma-
len Schreibsperre ein Anwendungsobjekt mehrfach mit einer Sperre versehen.
Wird das Objekt innerhalb eines Programms mehrfach gesperrt, wird die tat-
sächliche Sperre erst aufgehoben, wenn die Anzahl der Freigaben gleich der An-
zahl der vorherigen Sperren ist. Sperraufrufe können also innerhalb eines Pro-
gramms kumulliert werden. Wird eine Tabelle mit einer erweiterten Sperre
ausgestattet, ist auch innerhalb eines Programms keine weitere Sperrung des
Anwendungsobjekts möglich.
Beim Anlegen von Sperrobjekten im Data Dictionary kann sowohl für die Pri-
märtabelle als auch jede Sekundärtabelle gesondert der Sperrmodus definiert
werden.
345
9.3 Sperren von Anwendungsobjekten
Abbildung 9.1
Sperrobjekte der Transaktion IW32 (© SAP AG)
346
Weitere Informationen zu den gesetzten Sperren können aus der Detailsicht der
Sperren ermittelt werden. In diese gelangt man durch einen Doppelclick auf die
entsprechende Zeile der Liste der Sperreinträge (Abbildung 9.2).
Aus dem erscheinenden Fenster können alle benötigten Informationen bezüg-
lich der gesetzten Sperre ermittelt werden. Für den Programmierer besonders
wichtig sind hierbei der Name des Sperrobjekts (im Beispiel ESORDER für den
Auftrag) im unteren Bereich des Fensters sowie das Sperrargument unten im
ersten Gruppenrahmen.
Über den Kumulations-Zähler kann hier gesehen werden, ob das Anwendungs-
objekt mehrfach von der Anwendung gesperrt wurde. Im Beispiel ist dies nicht
der Fall.
Weiterhin ist aus der Abbildung ersichtlich, dass eine Sperre bis zu zwei Eigen-
tümer haben kann. Es handelt sich hierbei um das Dialogprogramm, welches
die Sperre angefordert hat sowie ggf. um den Verbucherbaustein, der die Sperre
ebenfalls verwendet.
Um in einem eigenen Programm zu verhindern, dass ein anderer Benutzer das
gleiche Anwendungsobjekt (hier Auftrag) parallel bearbeitet, müssen daher die
gleichen Sperren gesetzt werden, wie im Standard. Es müssen jedoch nicht un-
bedingt alle Sperren gesetzt werden. Um eine Auftragsbearbeitung in der Trans-
347
9.3 Sperren von Anwendungsobjekten
aktion IW32 zu verhindern, genügt es, das Sperrobjekt ESORDER zu setzen. Aller-
dings könnte ein Benutzer dennoch die, dem Auftrag zugrunde liegende
Meldung verändern und damit indirekt Einfluss auf den Auftrag nehmen.
Abbildung 9.3
Sperrparameter für Sperrobjekt ESORDER (© SAP AG)
348
Parameter von Enqueue-Bausteinen
Der Baustein zum Sperren von Aufträgen hat im Beispiel demnach den Namen
ENQUEUE_ESORDER mit der im Folgenden dargestellten Schnittstelle.
FUNCTION ENQUEUE_ESORDER
IMPORT
MODE_AUFK
MANDT
AUFNR
X_AUFNR
_SCOPE
_WAIT
_COLLECT
EXCEPTIONS
FOREIGN_LOCK
SYSTEM_FAILURE
Sperrmodus Bedeutung
»S« Lesesperre
Tabelle 9.1
Sperrmodi
Die genaue Bedeutung der jeweiligen Werte kann Abschnitt 9.2 dieses Kapitels
entnommen werden.
Den Sperrmodi folgen in der Aufrufschnittstelle des Enqueue-Bausteins die
Sperrparameter des Sperrobjekts. Für jeden Parameter – außer dem Feld Man-
dant – existiert hier neben dem im Data Dictionary definierten Namen des Sper-
rarguments ein weiterer Parameter mit dem Namen X_<Sperrparameter>. Über
dieses Feld wird – falls der Sperrparameter selbst initial übergeben wird – fest-
349
9.3 Sperren von Anwendungsobjekten
gelegt, ob der initiale Sperrparameter bedeutet, dass alle Werte gesperrt werden
sollen (Space) oder ob tatsächlich nur die Objekte gesperrt werden sollen, die im
dazugehören Feld keinen Wert enthalten (»X«).
Im Beispiel des Auftrags existiert auch nur ein Sperrparameter (AUFK), der dem-
entsprechend mit den Schnittstellenparametern AUFK sowie X_AUFK versorgt wird.
Diese Parameter definieren die zweite Gruppe innerhalb der Aufrufschnittstelle
von Enqueue-Bausteinen. Die dritte Gruppe, die Verwaltungsfelder, sind für
alle Sperrbausteine identisch und bestehen aus den drei Parametern _SCOPE,
_WAIT und _COLLECT.
Mit dem Parameter _SCOPE kann der Gültigkeitsbereich der Sperre definiert wer-
den. Hier sind die in Tabelle 9.2 dargestellten Werte gültig. Wird der Parameter
nicht versorgt, wird als Default immer der Wert »2« angenommen.
Scope Bedeutung
Tabelle 9.2
Gültigkeitsparameter für Sperren.
Wenn das Setzen einer Sperre durch den Funktionsbaustein nicht gelingt, bricht
der Baustein mit einer Exception (FOREIGN_LOCK) ab. Dies geschieht normalerwei-
se sofort, wenn festgestellt wird, dass die Sperre nicht gesetzt werden kann.
Durch den Parameter _WAIT kann - durch Übergabe des Wertes »X« - gesteuert
werden, dass bei bereits vorhandener Sperre durch einen anderen Anwender,
die Verarbeitung nicht sofort abgebrochen wird, sondern vielmehr mehrfach
hintereinander der Versuch erfolgt, die Sperre zu setzen in der Hoffnung, dass
die bereits existierende Sperre in diesem Zeitraum aufgehoben wird.
Über den Parameter _COLLECT schließlich kann gesteuert werden, ob die Sperran-
forderung sofort an den Enqueue-Server weitergeleitet werden soll (» X«) oder
gebündelt. Näheres zu diesem Konzept ist in Abschnitt 9.4 zu finden.
350
FUNCTION DEQUEUE_ESORDER
IMPORT
MODE_AUFK
MANDT
AUFNR
X_AUFNR
_SCOPE
_SYNCHRON
_COLLECT
351
9.5 Anlegen von eigenen Sperrobjekten
352
Neue Sperrobjekte müssen zunächst mit einem Namen versehen werden. Die-
ser muss immer mit dem Buchstaben »E« beginnen. Anschließend folgt der
Buchstabe »X«, »Y« oder »J«, um das Sperrobjekt im Kundennamensraum anzu-
legen.
Daran schließt sich der sprechende Teil des Namens für das Sperrobjekt an. Ins-
gesamt kann der Name von Sperrobjekten bis zu 16 Stellen lang sein.
Nachdem im Eingangsbild der Transaktion SE11 der Name des Sperrobjekts de-
finiert ist, kann das Sperrobjekt angelegt werden. Die Pflegetransaktion für
Sperrobjekte besteht aus einem Dynpro mit einem aus drei Seiten bestehenden
Tab-Strip. Auf der ersten Seite kann lediglich festgelegt werden, ob das Sperr-
objekt auch über Remote Function Calls (RFC) ansprechbar sein soll. Desweite-
ren werden auf dieser Seite die Verwaltungsinformationen zum Sperrobjekt an-
gezeigt. Auf eine Darstellung wurde daher an dieser Stelle verzichtet.
Auf der zweiten Seite des Tab-Strips mit dem Titel »Tabellen« können die Tabel-
len, die zum Sperrobjekt gehören, definiert werden (siehe Abbildung 9.4).
Jedem Sperrobjekt liegt mindestens eine Datenbank-Tabelle zugrunde, die als
Primärtabelle bezeichnet wird. Hierbei handelt es sich um die führende Tabelle,
in der das Anwendungsobjekt abgelegt wird. Gegebenenfalls können weitere
Tabellen als Sekundärtabellen dem Sperrobjekt zugewiesen werden.
Abbildung 9.4
Sperrtabellen definieren (© SAP AG)
353
9.5 Anlegen von eigenen Sperrobjekten
Für jede Tabelle einzeln kann der Vorschlagswert für den Sperrmodus definiert
werden. Der hier festgelegte Wert wird als Default-Wert für die entsprechenden
MODE_<Tabelle>-Parameter des Enqueue-Bausteins verwendet, kann beim Aufruf
jedoch beliebig vom Programmierer überschrieben werden.
Zuletzt müssen noch auf der dritten Seite des Tab-Strips die Parameter für das
Sperrobjekt definiert werden (Abbildung 9.5). Das System schlägt hier die
Schlüsselfelder der verwendeten Tabellen vor. Der Name der Sperrparameter
kann an dieser Stelle noch geändert werden. Er findet sich anschließend in der
Aufrufschnittstelle des Enqueue- und des Dequeue-Bausteins wieder.
Über das Ankreuzfeld kann gesteuert werden, ob für den jeweiligen Sperrpara-
meter ein Feld in der Aufrufschnittstelle der Funktionsbausteine angelegt wer-
den soll.
Abbildung 9.5
Definition der Sperrparameter (© SAP AG)
354
9.6 Verwendete Funktionsbauteine
9.6.1 DEQUEUE_<Sperrobjekt>
Mit den Dequeue-Bausteinen können zuvor gesetzte Sperren entfernt werden.
Dequeue-Bausteine werden nicht vom Programmierer angelegt, sondern aus
den Informationen des Sperrobjekts im Data Dictionary generiert. Manuelle
Eingriffe dürfen hier nicht erfolgen. Dazu gehört auch das Umhängen des Bau-
steins in eine andere als die generierte Funktionsgruppe oder der Transport des
Funktionsbausteins. Der Funktionsbaustein im Zielsystem wird beim Transport
des Sperrobjekts im Zielsystem automatisch generiert.
Import-Parameter
MANDT Mandant
355
9.6 Verwendete Funktionsbauteine
9.6.2 ENQUEUE_<Sperrobjekt>
Generierte Funktionsbausteine zum Setzen von Sperren auf Anwendungsobjekte.
Mit dem Funktionsbaustein können sowohl ein als auch mehrere Anwendungs-
objekte gesperrt werden. Da die Sperren nicht mit Datenbank-Sperren gelöst
werden, können auch nicht existierende Sätze gesperrt werden.
Analog zu den Dequeue-Bausteinen dürfen die Enqueue-Bausteine nicht manu-
ell vom Programmierer verändert werden oder in ein anderes System transpor-
tiert werden. Die Funktionsbausteine werden beim Transport der Sperrobjekte
im Zielsystem automatisch generiert.
Import-Parameter
MANDT Mandant
_WAIT Falls die Sperre nicht gesetzt werden konnte wird gewartet und
später erneut versucht, die Sperre zu setzen (»X«) oder sofor-
tiger Abbruch (Space)
Exceptions
356
9.6.3 FLUSH_ENQUEUE
Bei gebündelten Sperraufrufen wird durch den Aufruf dieses Funktionsbau-
steins die Übertragung der Aufrufe zum Sperrserver und somit das tatsächliche
Setzen der Sperren ausgelöst.
Der Funktionsbaustein hat keine Aufrufparameter, definiert aber die gleichen
Ausnahmen wie die Enqueue-Bausteine, nachdem erst beim tatsächlichen Set-
zen der Sperren Konflikte auftreten können.
Exceptions
9.6.4 RESET_ENQUEUE
Mit dem Funktionsbaustein RESET_ENQUEUE werden gebündelte und noch nicht
zum Sperrserver übertragene Sperraufrufe verworfen. Dies betrifft sowohl
Enqueue- als auch Dequeue-Aufrufe.
Der Funktionsbaustein definiert weder Aufruf- noch Rückgabeparameter. Es
werden auch keine Exceptions ausgelöst.
357
Versenden von Mails
10
10.1 SAPOffice – Das Ablagesystem in R/3
Bestandteil jedes R/3-Basissystems ist das Ablagesystem SAPOffice. Dieses be-
steht zum einen aus dem Ablagesystem, bei dem Textobjekte (hier SAPOffice-
Dokumente genannt) in Form von Ordnern organisiert abgelegt werden kön-
nen. Zum anderen können diese Textobjekte über das integrierte Mailsystem an
andere Benutzer versandt werden. Hierbei kann es sich sowohl um SAP-Benut-
zer innerhalb des gleichen oder anderer Systeme handeln. Auch der Versand an
Empfänger im Internet ist hier möglich. Welche Empfänger durch das jeweilige
SAPOffice erreicht werden können, hängt von der Konfiguration des R/3-Sys-
tems ab.
Ebenfalls von der Konfiguration des Systems hängt auch ab, ob Textobjekte als
FAX-Mitteilung versendet werden können.
Das Ablage- und Nachrichtensystem SAPOffice bildet auch die Kernfunktiona-
lität des SAP Workflow-Moduls. Nachrichten, die im Rahmen eines Workflows
ausgetauscht werden, landen in einem speziellen Ordner des SAPOffice und
können hier vom Benutzer weiterverarbeitet werden. Die Übertragung der
Workitems findet hierbei ebenfalls über das integrierte Mailsystem statt.
Abbildung 10.1 zeigt die Ordnerübersicht von SAPOffice für einen Standard-
Benutzer im R/3-Release 4.6C. In der Baumdarstellung auf der linken Seite sieht
man die Ordner des Ablagesystems, auf die der Benutzer zugreifen kann. Diese
Ordner sind auf der einen Seite private, d.h. nur für den jeweiligen Benutzer zu-
gängliche, Ordner, wie z.B. der Ordner »Eingang« mit allen untergeordneten
Ordnern. Hier befinden sich auch die Ordner des Workflows. Weiterhin zeigt
die Abbildung eine Reihe von »öffentlichen« Ordnern. Dabei handelt es sich um
Ordner, die mehreren Benutzern zugänglich sind. Die verschiedenen Benutzer
sehen hierbei nicht Kopien der Informationen sondern den tatsächlichen Ordner
selbst. In der Abbildung handelt es sich beispielsweise beim Ordner »Allgemei-
359
10.1 SAPOffice – Das Ablagesystem in R/3
Abbildung 10.1
Ordnerübersicht im SAPOffice (© SAP AG)
Soweit zum SAPOffice. Dieses Kapitel soll zeigen, wie aus ABAP-Programmen
heraus Nachrichten erzeugt und an einen oder mehrere Empfänger versendet
werden können. Dies ist insbesondere bei der Programmierung von Hinter-
grundprogrammen und Jobs, aber auch bei Schnittstellenprogrammen, die von
außerhalb des R/3-Systems aufgerufen werden und daher Verarbeitungsfehler
ebenfalls nicht direkt an einen Benutzer melden können, sinnvoll.
360
Der Mailversand erfolgt in ABAP-Programmen durch einen Aufruf des Funkti-
onsbausteins SO_OBJECT_SEND, der in der Funktionsgruppe SOA2 (»SAPOffice:
Funktionen – Senden«) enthalten ist. Dieser wird im Folgenden zunächst in sei-
ner Grundform vorgestellt und sukzessive in den folgenden Abschnitten erwei-
tert. Die Möglichkeiten dieses Funktionsbausteins sind jedoch so vielfältig, dass
eine vollständige Darstellung aller Möglichkeiten im Rahmen dieses Buches
nicht möglich ist. Es werden jedoch die wesentlichen Funktionen zur Erzeu-
gung und zum Versand von Nachrichten gezeigt.
361
10.2 Senden einer einfachen Textmitteilung
ORIGINATOR_ID
TABLES
OBJCONT
OBJHEAD
OBJPARA
OBJPARB
RECEIVERS
PACKING_LIST
ATT_CONT
ATT_HEAD
NOTE_TEXT
LINK_LIST
APPLICATION_OBJECT
EXCEPTIONS
ACTIVE_USER_NOT_EXIST
COMMUNICATION_FAILURE
COMPONENT_NOT_AVAILABLE
FOLDER_NOT_EXIST
FOLDER_NO_AUTHORIZATION
FORWARDER_NOT_EXIST
OBJECT_NOT_EXIST
OBJECT_NOT_SENT
OBJECT_NO_AUTHORIZATION
OBJECT_TYPE_NOT_EXIST
OPERATION_NO_AUTHORIZATION
OWNER_NOT_EXIST
PARAMETER_ERROR
SUBSTITUTE_NOT_ACTIVE
SUBSTITUTE_NOT_DEFINED
SYSTEM_FAILURE
TOO_MUCH_RECEIVERS
USER_NOT_EXIST
ORIGINATOR_NOT_EXIST
X_ERROR
OTHERS
In diesem Abschnitt soll begonnen werden, eine einfache Textnachricht via SAP-
Office an einen anderen Benutzer im R/3-System zu versenden. Von den vielen
Parametern, die der Funktionsbaustein anbietet, werden hierfür lediglich die
Parameter OBJECT_HD_CHANGE, OBJECT_TYPE, OBJECT_CONT sowie RECEIVERS benötigt.
362
Kopfstruktur OBJECT_HD_CHANGE
Im Parameter OBJECT_HD_CHANGE wird dem Funktionsbaustein die Kopfstruktur
für das zu sendende SAPOffice-Dokument übergeben. Die zugrunde liegende
Struktur ist im Data Dictionary unter dem Namen SOOD1 definiert (Tabelle 10.1).
OBJCP CHAR 1 Kennzeichen, ob das Dokument verändert werden Kapitel – Versenden von Mails
kann
363
10.2 Senden einer einfachen Textmitteilung
Tabelle 10.1
Kopfstruktur für SAPOffice-Dokumente (SOOD1).
364
Dokumentinhalt (OBJECT_CONT)
Der eigentliche Inhalt des zu versendenden Dokuments wird in Form einer in-
ternen Tabelle im Parameter OBJECT_CONT an den Funktionsbaustein übergeben.
Tabelle 10.2
Aufbau der Struktur SOLI
Diese Tabelle hat den Aufbau der Dictionary-Struktur SOLI, welche in Tabelle
10.2 wiedergegeben ist. Die Struktur besteht nur aus einem einzigen Feld LINE.
Empfänger (RECEIVERS)
Nachdem das zu versendende Dokument vollständig beschrieben ist, fehlen
nur noch die Informationen, an wen die Mail geschickt werden soll. Die Emp-
fänger der Mail werden dem Funktionsbaustein ebenfalls in Form einer internen
Tabelle übergeben, welche den Aufbau der Data Dictionary-Struktur SOOS1 hat.
Diese Struktur enthält insgesamt 98 Felder. Eine vollständige Darstellung wür-
de den Rahmen an dieser Stelle sprengen. Tabelle 10.3 beschränkt sich daher
darauf die, für diesen Schritt benötigten Felder aufzulisten.
...
...
Tabelle 10.3
Aufbau der Tabelle für Mailempfänger (Auszug)
365
10.2 Senden einer einfachen Textmitteilung
Eine Mail kann entweder an einen einzelnen Benutzer (in diesem Schritt werden
nur Benutzer innerhalb des gleichen R/3-Systems adressiert) oder an eine zuvor
in Form einer internen Verteilerliste definierten Empfängerkreis gesendet wer-
den. Für diese beiden Varianten stehen in der Struktur entsprechend die Felder
DLINAM für eine Verteilerliste und RECNAM für einen einzelnen Mail-Empfänger zur
Verfügung. Es darf jeweils nur eines dieser beiden Felder versorgt werden.
Für jeden Empfänger gesondert, können hier Eigenschaften für die Mail defi-
niert werden. Über das Feld SNDCP wird der Empfänger als Kopieempfänger der
Mail gekennzeichnet. Die Empfänger der Mail sehen am Mailkopf, wer eben-
falls Mailempfänger und Kopienempfänger ist. Über das Feld SNDBC kann ein
Empfänger als geheimer Kopieempfänger klassifiziert werden. Die übrigen
Empfänger können geheime Mailempfänger nicht erkennen.
Beispielsweise beim Abbruch der Verbuchung erhält der Anwender eine vom
System generierte Mail, die den Verbuchungsabbruch mitteilt. Diese Mail wird
als so genannte Express-Mail im System versandt. Beim Anwender erscheint ein
PopUp, welches ihn auf den Eingang einer Express-Mail hinweist. Mit dem
Funktionsbaustein SO_OBJECT_SEND können Express-Mails versandt werden, in-
dem im Feld SNDEX der RECEIVERS-Tabelle ein »X« übergeben wird. Zusätzlich
kann die Wichtigkeit der Mail in Form einer Priorität im Parameter SNDPRI defi-
niert werden. Hier sind Werte zwischen 1 (hoch) und 9 (niedrig) definiert wor-
den.
Zur Mailverfolgung können in den Feldern DELIVER, NOT_DELI und READ Zustel-
lung bzw. nicht –Zustellung sowie eine Lesebestätigung angefordert werden.
Beispiel
In diesem Abschnitt soll ein vollständiges Beispielprogramm dargestellt wer-
den, mit dem eine einfache Mail als Express-Mail versendet wird. Das Pro-
gramm ist als Report ohne weitere Struktur realisiert.
REPORT ZMAIL.
366
* Objekttyp
G_OBJECT_TYPE = 'RAW'.
* Nachricht
G_OBJCONT-LINE = 'Zeile 1'.
APPEND G_OBJCONT.
G_OBJCONT-LINE = 'Zeile 2'.
APPEND G_OBJCONT.
* Empfänger
G_RECEIVERS-RECNAM = 'RIEKERT'.
G_RECEIVERS-SNDEX = 'X'. "Als Express-Mail
APPEND G_RECEIVERS.
OBJECT_TYPE_NOT_EXIST = 11
OPERATION_NO_AUTHORIZATION = 12
OWNER_NOT_EXIST = 13
PARAMETER_ERROR = 14
SUBSTITUTE_NOT_ACTIVE = 15
SUBSTITUTE_NOT_DEFINED = 16
SYSTEM_FAILURE = 17
TOO_MUCH_RECEIVERS = 18
USER_NOT_EXIST = 19
ORIGINATOR_NOT_EXIST = 20
X_ERROR = 21
OTHERS = 22.
367
10.3 Mails mit Ausführungsparametern
Das Programm zeigt, wie einfach im Grunde der Versand einer Mail in SAPOf-
fice ist. Wie so oft verdeckt die Vielzahl der zur Verfügung stehenden Parameter
die eigentlich einfache Funktionalität.
Das Beispielprogramm versorgt lediglich die notwendigen Felder der Kopf-
struktur und der Empfängertabelle. Weiterhin werden exemplarisch zwei lite-
rale Textzeilen als Rumpf der Mail definiert.
Auf keinen Fall darf die Festlegung des Mailtypen (in der Regel »RAW«) unterblei-
ben. Der Funktionsbaustein würde sonst mit der Ausnahme PARAMETER_ERROR ab-
brechen.
Der Funktionsbaustein liefert in diesem Beispiel eine Struktur mit den Primär-
schlüsselfeldern des neu erzeugten SAPOffice-Dokuments sowie ein Flag, ob
die Mail an alle Empfänger erfolgreich versendet werden konnte, zurück. Wei-
tere Rückgabeparameter existieren, sollen hier aber nicht näher erläutert wer-
den.
Der Primärschlüssel für SAPOffice-Dokumente ist in der Dictionary-Struktur
SOODK (Tabelle 10.4) definiert und besteht aus drei Feldern.
Tabelle 10.4
Primärschlüssel für SAPOffice-Dokumente (Struktur SOODK)
368
VMTYP Bedeutung
»D« Dialogbaustein
»F« Funktionsbaustein
»R« Report
»T« Dialogtransaktion
Tabelle 10.5
Mögliche Typen von Ausführungsparametern
Je nach Ausführungstyp haben weitere Felder der Kopfstruktur sowie der In-
halt der Tabellenparameter OBJPARA sowie OBJPARB unterschiedliche Bedeutun-
gen. Im Folgenden soll kurz auf die einzelnen Varianten zur Steuerung der Aus-
führungsparameter eingegangen werden, bevor das Beispiel des vorigen
Abschnitts exemplarisch erweitert wird, um den Aufruf einer Dialogtransaktion
als Ausführungsparameter zu zeigen.
Zur Parameterübergabe an das auszuführende Programm (gleich welchen
Typs) definiert die Aufrufschnittstelle von SO_OBJECT_SEND zwei Tabellenpara-
meter OBJPARA und OBJPARB. Während die in OBJPARA definierten Einträge in Form
von Benutzerparametern abgelegt werden, erfolgt die Weitergabe der internen
Tabelle des Parameters OBJPARB direkt an das entsprechende Programm.
Der Tabellenparameter des Parameters OBJPARA entspricht der Dictionary-Struk-
tur SELC, deren Aufbau in Tabelle 10.6 wiedergegeben ist.
Tabelle 10.6
Aufbau der Data Dictionary-Struktur SELC
Der Aufbau der Tabelle entspricht somit dem Aufbau einer Selektionstabelle
wie sie z.B. mit der RANGES-Anweisung von ABAP erzeugt werden kann. Das
369
10.3 Mails mit Ausführungsparametern
Tabelle 10.7
Variable, die zur Laufzeit durch Dokumentinformationen ersetzt werden
370
Die Sätze der im Tabellenparameter OBJPARB übergebenen Tabelle werden un-
verändert an den aufzurufenden Dialog- bzw. Funktionsbaustein übergeben.
Bei Aufruf von Reports oder Dialogtransaktionen wird dieser Tabellenparame-
ter bei Bedarf über das ABAP-Memory an das aufzurufende Programm weiter-
gegeben.
Der Tabellenparameter OBJPARB ist ebenfalls mit Bezug zu einer Dictionary-
Struktur definiert. Es handelt sich hierbei um die Struktur SOOP1, deren Aufbau
Tabelle 10.8 zeigt.
Tabelle 10.8
Dictionary-Struktur SOOP1
Ausführungstyp »Dialogbaustein«
Ausführungsparameter vom Typ »D« ermöglichen es, direkt aus der Mail heraus
einen Dialogbaustein im R/3-System aufzurufen. Hierbei werden zunächst die
im Tabellenparameter OBJPARA definierten Benutzerparameter gesetzt, bevor der
eigentliche Dialogbaustein aufgerufen wird.
Der aufzurufende Dialogbaustein muss eine festgelegte Aufrufschnittstelle de-
finieren. Diese besteht lediglich aus einem Tabellenparameter MSGDIAL, in dem
die im Parameter OBJPARB an den Funktionsbaustein SO_OBJECT_SEND übergebene
interne Tabelle übergeben wird.
Der Name des Dialogbausteins wird im Parameter ACNAM der Kopfstruktur über-
geben. Vor dem Aufruf prüft das System die Existenz des Bausteins und bricht
gegebenenfalls mit einer Meldung ab.
Ausführungstyp »Funktionsbaustein«
Kapitel – Versenden von Mails
Mit dem Ausführungstyp »F« wird definiert, dass der im Feld ACNAM der Kopf-
struktur übergebene Wert der Name eines aufzurufenden Funktionsbausteins
ist. Analog zum Ausführungstyp »Dialogbaustein« werden zunächst die im Pa-
rameter OBJPARA definierten Benutzerparameter gesetzt, bevor der Funktions-
baustein mit der in OBJPARB übergebenen Tabelle als Parameter aufgerufen wird.
Die Aufrufschnittstelle des Funktionsbausteins muss daher folgenden Aufbau
besitzen:
FUNCTION <Funktionsname>
TABLES
MSG_DIAL.
371
10.3 Mails mit Ausführungsparametern
Ausführungstyp »Report«
Wird im Feld VMTYP der Kopfstruktur der Wert »R« oder »S« übergeben, wird der
Wert ACNAM als Name eines ABAP-Reports interpretiert. Auch in diesem Fall
werden die Sätze des Tabellenparameters OBJPARA in Benutzerparameter umge-
setzt. Da Reports anders als Funktionsbausteine keine Aufrufschnittstelle defi-
nieren, besteht die Möglichkeit, die im Parameter OBJPARB übergebene Tabelle
über das ABAP-Memory an den aufzurufenden Report weiterzugeben. Dies er-
folgt jedoch nur beim Ausführungstyp »S« und auch nur dann, wenn im Feld
ACMEM der Kopfstruktur ein Name für das ABAP-Memory übergeben wurde.
Anschließend wird der gewünschte Report über die SUBMIT-Anweisung des
ABAP-Sprachschatzes gestartet. Über das Feld SKIPS der Kopfstruktur kann
hierbei gesteuert werden, ob der Selektionsbildschirm des Reports übersprun-
gen werden soll. Analog zu anderen Aufrufen mit SUBMIT funktioniert dies na-
türlich nur, wenn über die entsprechenden Mechanismen alle notwendigen Fel-
der des Selektions-Dynpros versorgt wurden.
Ausführungstyp »Dialogtransaktion«
Analog zum Aufruf von Reports werden die Ausführungstypen »T« und »U« ge-
nutzt, um Dialogtransaktionen entweder ohne oder mit Nutzung des ABAP-
Memories aufzurufen.
Von der Funktionalität her gleichen sich diese beiden Ausführungstypen mit
dem Unterschied, dass der Inhalt des Feldes ACNAM nicht den Programmnamen,
sondern den Transaktionscode der zu rufenden Dialogtransaktion enthält. Die-
se wird nach dem Versorgen der entsprechenden Benutzerparameter und ggf.
des ABAP-Memories mit der CALL TRANSACTION-Anweisung von ABAP aufgeru-
fen.
Auch hier besteht die Möglichkeit, das erste Dynpro der Transaktion zu über-
springen. Dies wird über das Feld SKIPS der Kopfstruktur gesteuert.
Beispiel
Zur Demonstration der Möglichkeiten, eine Mail mit Ausführungsparametern
zu versehen, soll das Beispielprogramm aus dem vorigen Abschnitt dahinge-
hend erweitert werden, dass über die versendete Mail die Transaktion »Auftrag
ändern« (Transaktionscode IW32) aufgerufen werden kann. Der Transaktion soll
eine feste Auftragsnummer übergeben werden und der Eingangsbildschirm
übersprungen werden.
Hierfür müssen zunächst weitere Felder der Kopfstruktur versorgt werden.
* Versorgen des Headers
...
G_OBJECT_HD_CHANGE-VMTYP = 'F'.
372
G_OBJECT_HD_CHANGE-ACNAM = 'IW32'.
G_OBJECT_HD_CHANGE-SKIPS = 'X'.
...
Der Ausführungstyp wird hier auf »F« gesetzt, da außer der Auftragsnummer,
welche über einen Benutzerparameter gesetzt werden kann, keine Parameter
übergeben werden müssen.
Der Transaktionscode IW32 wird im Feld ACNAM abgelegt. Über den Wert »X« im
Feld SKIPS wird gesteuert, dass der erste Screen der Transaktion übersprungen
werden soll.
Zuletzt muss noch der Benutzerparameter ANR, welcher zur Aufnahme einer
Auftragsnummer definiert wurde und von der Transaktion IW32 verwendet
wird, gesetzt werden. Um dies zu bewerkstelligen, muss eine weitere Variable
als interne Tabelle deklariert werden.
REPORT ZMAIL.
...
DATA: G_OBJPARA LIKE SELC OCCURS 0 WITH HEADER LINE.
...
In diese Tabelle wird vor dem Aufruf des Funktionsbausteins SO_OBJECT_SEND die
Zeile, die das Setzen des Benutzerparameters ANR bewirkt, eingefügt.
* Benutzerparameter setzten
G_OBJPARA-NAME = 'ANR'.
G_OBJPARA-LOW = '810360'.
APPEND G_OBJPARA.
TABLES
OBJCONT = G_OBJCONT
OBJPARA = G_OBJPARA
RECEIVERS = G_RECEIVERS
EXCEPTIONS
ACTIVE_USER_NOT_EXIST = 1
COMMUNICATION_FAILURE = 2
COMPONENT_NOT_AVAILABLE = 3
FOLDER_NOT_EXIST = 4
FOLDER_NO_AUTHORIZATION = 5
FORWARDER_NOT_EXIST = 6
NOTE_NOT_EXIST = 7
373
10.4 Verwendete Funktionsbausteine
OBJECT_NOT_EXIST = 8
OBJECT_NOT_SENT = 9
OBJECT_NO_AUTHORIZATION = 10
OBJECT_TYPE_NOT_EXIST = 11
OPERATION_NO_AUTHORIZATION = 12
OWNER_NOT_EXIST = 13
PARAMETER_ERROR = 14
SUBSTITUTE_NOT_ACTIVE = 15
SUBSTITUTE_NOT_DEFINED = 16
SYSTEM_FAILURE = 17
TOO_MUCH_RECEIVERS = 18
USER_NOT_EXIST = 19
ORIGINATOR_NOT_EXIST = 20
X_ERROR = 21
OTHERS = 22.
10.4.1 SO_OBJECT_SEND
Der Funktionsbaustein SO_OBJECT_SEND wird verwendet, um Dokumente aus
dem Bereich von SAPOffice über das integrierte Mailsystem an einen oder meh-
rere Benutzer im gleichen oder anderen R/3-Systemen oder fremden Mailsyste-
men zu senden.
Import-Parameter
OBJECT_TYPE Dokumenttyp
374
STORE_FLAG Kennzeichen, ob Dokument gespeichert werden
soll
ORIGINATOR Vertreter
LINK_FOLDER_ID undokumentiert
Export-Paramter
ALL_BINDINGS_DONE undokumentiert
OFFICE_OBJECT_KEY undokumentiert
ORIGINATOR_ID undokumentiert
Tabellen
OBJCONT Mailrumpf
PACKING_LIST undokumentiert
ATT_CONT undokumentiert
ATT_HEAD undokumentiert
375
10.4 Verwendete Funktionsbausteine
NOTE_TEXT undokumentiert
LINK_LIST undokumentiert
APPLICATION_OBJECT undokumentiert
Exceptions
COMMUNICATION_FAILURE Kommunikationsfehler
SYSTEM_FAILURE Systemfehler
376
Literaturverzeichnis
377
Stichwortverzeichnis
◗◗ A AT SELECTION-SCREEN OUTPUT 28
AT USER-COMMAND 30
ABAP-Memory 40, 43, 371 Ausführungsparameter 368
ABAP-Objects 276 Ausgabefeld 52
ABAP-Prozessor 328 Ausgabegerät 152, 310, 330
Ablage Ausgabemode 216
öffentlich 360 Ausgabeparameter 305
private 359 Ausnahme 41
Ablageordner 360 Auswahldialog 104
Ablagesystem 359 Auswahlfeld 23, 170
Ablauflogik 121, 126, 175, 328 AUTHORITY-CHECK 55
Ablaufsteuerung 31, 271 AVL Grid Control 131
ActiveX 131, 161, 244
Alternativsprache 225
Ankreuzfeld 23, 170 ◗◗ B
Antwortzeit 305
Anwendungslogik 326 Balkengrafik 229
Anwendungsobjekt 187, 204, 352 BAPI 271
Anzeigeattribut 240 BAPI_MESSAGE_GET_DETAIL 283
Applikationsevent 162 Batchbetrieb 305
Applikationsserver 161, 197, 326 Batch-Input 269
ARCHIVE_OPEN_FOR_READ 193 Batch-Input-Aufzeichnung
Archivierung 193 Anlegen 288
aRFC 342 Bearbeiten 288
AS CHECKBOX 23 Funktionsbaustein generieren 292
AS WINDOW 22 Programm generieren 291
Asynchrone Programmiertechnik 334 Speichern 291
asynchroner RFC 342 Batch-Input-Mappe 270, 272, 291
AT LINE-SELECTION 30 abspielen 270, 287
AT PFxxx 30 erzeugen 273, 285
AT SELECTION-SCREEN 26, 29 Batch-Input-Recorder 270, 287
AT SELECTION-SCREEN FIELD 29 Batch-Input-Technik 329
ortverzeichnis
◗◗ I Knoten 74
Erzeugung 81
Icon 141 Farbattribute 89
IF_DC_ACCESS 246–247 löschen 105, 107
IF_DC_MANAGEMENT 246 mit Texteattributen 85
IF_DC_SUBSCRIPTION 246 Wurzelknoten erzeugen 76
IF_GRAPHIC_PROXY 257 Knotenattribut 105–106
Ikone 79, 90, 110, 158 Knotenelement 77
INCLUDE 16 Knotenname 74
INCLUDE-STRUCTURE 17, 20 Knotentabelle 106
INIT_TEXT 225 Knotentyp 76
INITIALIZE 28 Kommentarzeilen 217
Instanzmethode 163 hervorheben 218
Interaktion 161 kennzeichnen 218
Stichwortverzeichnis
◗◗ L ◗◗ N
TREEV_LHDR 153
Textbaustein 225 TREEV_NODE 138, 144
Texte 187 Tree-View 73
Texte ohne Formatierung 206 tRFC 341
TextEdit 131, 210 TYPE-POOL 18, 92
aktuelle Selektion 221 TYPES 17
Suchen 221 Typgruppe 42
Suchen&Ersetzen 221
Zeilen einrücken 221
ortverzeichnis
◗◗ U Viewer-Fenster 237
visuelle Komponente 244
Überschrift 235, 239 Vollbild-Editor 196
unstrukturierten Text 206 Vorgängerjob 316
Unterprogramm 15 VRM 167
Unterprogrammtechnik 21, 39 VRM_SET_VALUES 167
◗◗ V ◗◗ W
Bei Fragen zu diesem Thema wenden Sie sich bitte an: [email protected]
Zusatzdaten
Möglicherweise liegt dem gedruckten Buch eine CD-ROM mit Zusatzdaten bei. Die
Zurverfügungstellung dieser Daten auf unseren Websites ist eine freiwillige Leistung
des Verlags. Der Rechtsweg ist ausgeschlossen.
Hinweis
Dieses und viele weitere eBooks können Sie rund um die Uhr
und legal auf unserer Website
http://www.informit.de
herunterladen