Einstieg in ABAP

Als Nächstes wenden wir uns der Welt der Zahlen zu.
Erfahren Sie in diesem Kapitel, wie Sie Berechnungen in
ABAP-Programmen durchführen.
4
Felder und Berechnungen
Sie sollten mit allem rechnen – im SAP-System können Sie das sogar
mit Datumswerten und Zeichenketten. In diesem Kapitel beginnen
wir jedoch mit dem Einfachsten: dem Rechnen mit Zahlen.
Vorbereitungen
Bevor wir beginnen, sollten Sie entscheiden, ob Sie für die ersten Berechnungen in ABAP einen neuen Report anlegen oder diese einfach in unserem Report aus Kapitel 3, »Programmieren im ABAP Editor«, einbauen.
Beides ist natürlich möglich – doch nicht zuletzt für eine bessere Übersichtlichkeit sollten Sie mit einem frischen Report arbeiten. Die Neuanlage
eines Reports wird in Abschnitt 3.1, »ABAP-Report anlegen«, beschrieben.
Als Alternative können Sie aber auch einen bestehenden Report kopieren
und ihn anschließend modifizieren. Auf diese Weise bleibt der alte Report
erhalten, und der neue wird unter einem eigenen Namen abgespeichert.
4.1
Report vorbereiten
Starten Sie im Einstiegsbild für den ABAP Editor (SAP Menü 폷 Werkzeuge 폷 ABAP Workbench 폷 Entwicklung 폷 ABAP Editor). Im Startbildschirm geben Sie als Programmnamen den Namen unseres letzten Reports ein, »Z_TEILNEHMERLISTE01«. Anschließend können
107
Report kopieren und
modifizieren
4
Felder und Berechnungen
Report vorbereiten
Sie entweder über Programm 폷 Kopieren oder über den Button
Kopieren ( , (Strg) + (F5)) den Kopiervorgang starten (siehe Abbildung 4.1).
Abbildung 4.3 Elemente eines ABAP-Reports mit kopieren
Abbildung 4.1 ABAP-Programm kopieren
Sie werden nach dem Namen des Zielprogramms gefragt (siehe Abbildung 4.2). Dieser muss sich vom Namen des Quellprogramms unterscheiden, und es gelten für ihn selbstverständlich auch die Namenskonventionen, wie sie in Abschnitt 2.1.2, »Tabelle anlegen und
pflegen«, beschrieben werden.
Abbildung 4.2 Namen eines Zielprogramms auswählen
Haben Sie den Namen des Zielprogramms eingetragen, setzen Sie den
Kopiervorgang über die Schaltfläche Kopieren oder die (¢)-Taste
fort. Anschließend haben Sie die Wahl, neben dem Quellcode und
den Textelementen auch andere Elemente des alten Programms mit
zu kopieren (siehe Abbildung 4.3).
108
Für den Anfang können Sie, ohne ein Häkchen zu setzen, einfach
über die Schaltfläche Kopieren den Prozess fortführen und unseren
neuen Report als Lokales Objekt abspeichern. Das System zeigt
Ihnen anschließend wieder das Einstiegsbild des ABAP Editors mit
dem neuen Programmnamen. Das alte Programm wurde mit allen
gewählten Elementen kopiert; beachten sollten Sie nur, dass der neue
Quellcode noch inaktiv ist.
Elemente kopieren
Hätten Sie beispielsweise für den alten Quellcode eine Dokumentation
hinterlegt, könnte diese ausgewählt und kopiert werden. Alle Elemente
dieses Fensters sind keine eigenen Objekte der Datenbank, sondern hängen fest am Report, d. h., dass beispielsweise die Dokumentation für den
Report nicht mehrfach verwendbar ist (etwa für andere Reports), wie es
bei einem Datenelement der Fall wäre. Ein Datenelement ist dagegen ein
eigenes Objekt und damit mehrfach verwendbar.
Über den Ändern-Button ( ) gelangen Sie in den Änderungsmodus
für den Quellcode. Was Sie jetzt sehen, ist nicht neu: Den alten Quellcode kennen Sie bereits. Auffallen könnte Ihnen aber, dass die
REPORT-Anweisung nicht mehr ganz korrekt ist. Sie wurde zwar richtig kopiert, doch da sich der Programmname im Operanden geändert
hat, sollte es der erste Arbeitsschritt im neuen Quellcode sein, den
Namen auf unseren neuen Programmnamen umzuschreiben: Z_TEILNEHMERLISTE02.
109
4.1
4
Felder und Berechnungen
Report vorbereiten
4.1
Zeilenblock in Kommentarzeilen umwandeln
Was machen Sie mit den Programmzeilen, die Sie nicht mehr benötigen?
Es gibt zwei Möglichkeiten: Entweder Sie löschen die Zeilen, oder Sie wandeln sie in Kommentarzeilen um (»auskommentieren«). Vorsichtige Entwickler werden sich zunächst für die zweite Möglichkeit entscheiden, vermeintlich überflüssige Anweisungen in Kommentarzeilen umzuwandeln,
die man vielleicht für die eine oder die andere Anweisung doch noch einmal braucht – man kann ja nie wissen.
Deshalb gehen auch wir so vor und wandeln vorsichtshalber zunächst
die alten Anweisungen in Kommentarzeilen um. Hierzu markieren Sie
mit dem Cursor den zu bearbeitenden Zeilenblock wie in jedem Editor
üblich mit den Cursortasten oder mit der Maus. Der markierte Block
wird nun dunkelblau hinterlegt dargestellt (siehe Abbildung 4.4)
Abbildung 4.5 Block in Kommentarzeilen umwandeln
Aus Abbildung 4.5 können Sie auch ableiten, wie Sie bei Bedarf einen
Block von Kommentarzeilen analog wieder in Anweisungszeilen
umwandeln: Hierzu markieren Sie den Block sowie das Blockende
und wählen Hilfsmittel 폷 Block/Ablage 폷 Kommentar-* löschen.
Da wir für die Anweisungen ab Zeile 10 aber tatsächlich im Folgenden keine Verwendung mehr haben, können Sie den Zeilenblock
ruhig löschen. Hierfür markieren Sie zunächst wieder den entsprechenden Block und drücken dann die (Entf)-Taste auf Ihrer Tastatur.
Abbildung 4.4 Block markieren
Anschließend wandeln Sie über Hilfsmittel 폷 Block/Ablage 폷 Kommentar-* einfügen den gesamten Block in Kommentarzeilen um
(siehe Abbildung 4.5). Als Ergebnis sind alle Zeilen des Blocks in
Spalte 1 mit einem Stern als Kommentarzeilen gekennzeichnet. War
eine Zeile bereits vorher eine Kommentarzeile, hat sie jetzt zwei führende Sterne.
110
Zeilenblock löschen
Sichern nicht vergessen!
Vergessen Sie nicht, die Veränderung am Quellcode nach wichtigen
Arbeitsschritten oder vor Arbeitspausen über den Sichern-Button ( ) zu
speichern.
Wir können uns nun der eigentlichen Aufgabe dieses Kapitels zuwenden: Wir verarbeiten nun zwei Zahlen mit ABAP mithilfe der vier
111
Spreu vom
Weizen trennen
4
Felder und Berechnungen
Grundrechenarten und schreiben das Ergebnis in eine Liste. Hierzu
sind drei Arbeitsschritte erforderlich:
1. die Felder für die Zahlen deklarieren
2. das Ergebnis berechnen
3. das Ergebnis ausgeben
Die Namen der Variablen sollten darüber hinaus sprechend, d. h. selbsterklärend sein. Nennen Sie die Variable für einen Familiennamen z. B. FAMILIENNAME und nicht A1. Legen Sie großen Wert auf Lesbarkeit, und seien
Sie dementsprechend gnädig mit Dritten – Sie könnten es in wenigen
Wochen selbst sein.
Wie in der Praxis müssen auch bei unserer Teilnehmerverwaltung
Inhalte einer oder mehrerer Tabellen im Report durch Berechnungen
weiterverarbeitet, ergänzt oder ausgewertet werden. Hierzu benötigen wir im Report eigene Felder.
Auch ABAP verfügt über Regeln, auf welche Weise Felder verarbeitet
werden. Das System muss die Zahlen in unserem Beispiel zwischenspeichern, ablegen und sie sich für folgende Verarbeitungsschritte
wieder zurückholen. Hierzu werden die Werte an einem Ort bzw.
einer Datenadresse im Speicher temporär abgelegt.
Sollen sich die Inhalte unserer Zahlenfelder verändern können,
deklarieren wir für den Einstieg unsere Felder mit der DATA-Anweisung. Für unsere Berechnungen bieten sich vorerst zwei Datentypen
für die Variablen an, nämlich ganze Zahlen (Integer) und Dezimalzahlen.
DATA
In ABAP heißen diese Orte Felder oder Datenobjekte. Sind die Inhalte
der Datenobjekte durch ABAP-Anweisungen veränderbar, spricht
man von Variablen, sind sie es nicht, spricht man von Konstanten.
Soll das Feld ZAHL01 eine ganze Zahl enthalten, lautet die Anweisung
folgendermaßen:
TYPE i
4.2.1
Namen vergeben
Sprechende Variablen
Felder haben einen symbolischen Namen (z. B. ZAHL01), eine definierte Länge und einen Datentyp. Über die symbolischen Namen
werden die Speicheradressen angesprochen, und die dort abgelegten
Inhalte können gelesen und verarbeitet werden. Für die Verarbeitung
gelten je nach Datentyp entsprechende Regeln, die allerdings von
Programmiersprache zu Programmiersprache sehr unterschiedlich
sind.
4.2
Felder verarbeiten
Felder deklarieren
Felder deklarieren
Variablen deklarieren
Bei der Namensvergabe für Variablen müssen Sie Folgendes beachten:
왘 Der Name soll mit einem Buchstaben beginnen; er darf nicht ausschließlich aus Ziffern bestehen.
왘 Der Name darf maximal 30 Zeichen lang sein.
왘 Der Name soll möglichst keine Sonderzeichen enthalten, bis auf den
Unterstrich. Ausdrücklich verbotene Sonderzeichen sind Plus (+),
Komma (,), Doppelpunkt (:), Klammer auf (() und Klammer zu ()).
왘 Für den Namen dürfen keine reservierten Wörter für ABAP-Anweisungen oder Zusätze verwendet werden.
112
DATA zahl01 TYPE i.
Soll das Feld ZAHL01 hingegen eine Dezimalzahl mit zwei Nachkommastellen sein, lautet die Anweisung:
DATA zahl01 TYPE p DECIMALS 2.
Bei der Entscheidung, welche Deklaration sinnvoller ist, kommt es
demnach auf den Verwendungszweck an. Felder vom Typ i werden
üblicherweise für Zähler oder Stückzahlen verwendet. Felder vom
Typ p sind für arithmetische Berechnungen mit Nachkommastellen
üblich. Wichtig ist, vor der weiteren Programmierung zu überlegen,
welche Rechen- und Anzeigegenauigkeit bei der gewünschten
Berechnung erforderlich ist, weil sich die Zahl der nötigen Nachkommastellen hiernach richtet – denken Sie z. B. an Wechselkurse. Fünf
Nachkommastellen sind in solchen Fällen keine Seltenheit, wogegen
die 14 erlaubten Nachkommastellen eher selten ausgereizt werden.
113
TYPE p
4.2
4
Felder und Berechnungen
Elementare
Datentypen
Beide Datentypen, i und p, sind für ABAP elementare Datentypen
mit fester Länge. Deshalb müssen Sie die Feldlänge hier nicht explizit
angeben. Die beiden Datentypen sind zwei von acht dieser in ABAP
eingebauten elementaren Datentypen fester Länge.
Umfassenderes Typkonzept
Einen elementaren Datentyp variabler Länge werden Sie noch kennenlernen. Für ein leichteres Verständnis beschränken wir uns vorerst auf die
wichtigsten Datentypen. Auf die Darstellung von Referenzdatentypen und
komplexen Datentypen wird verzichtet. Sie sollten jedoch im Hinterkopf
behalten, dass das Typkonzept in ABAP für fortgeschrittene Anwendungen
viel umfassender ist, als hier dargestellt.
Möchten Sie zwei Variablen gleichlautend deklarieren, müssen Sie
zwei Anweisungszeilen schreiben und darauf achten, dass Sie dieselben Attribute verwenden, beispielsweise:
DATA zahl01 TYPE p DECIMALS 2.
DATA zahl02 TYPE p DECIMALS 2.
LIKE
Dies hat allerdings den entscheidenden Nachteil, dass Sie immer
selbst dafür sorgen müssen, die Deklaration von ZAHL02 nachzupflegen, falls sich die Deklaration von ZAHL01 ändert. Bei vielen abhängigen Deklarationen wird dies schnell zu einer sehr mühseligen und
langatmigen Arbeit. Einfacher ist es, bei ZAHL02 auf die Deklaration
von ZAHL01 zu verweisen. Dies geschieht mit dem Zusatz LIKE:
DATA zahl01 TYPE p DECIMALS 2.
DATA zahl02 LIKE zahl01.
Damit ist gewährleistet, dass die Deklaration von ZAHL02 immer richtig bleibt, da sie so an die Deklaration von ZAHL01 geknüpft ist. Sollte
einmal ein Anlass bestehen, die Zahl der Dezimalstellen beispielsweise von zwei auf vier zu erhöhen, muss nur die Deklaration von
ZAHL01 geändert werden; die Deklaration von ZAHL02 wird automatisch angepasst. Natürlich gilt dies entsprechend für alle Variablen in
einem Report, die auf die Deklaration von ZAHL01 verweisen.
Inkonsistenzen
vermeiden
Auf diese Weise können Sie zwar erreichen, dass Inkonsistenzen
innerhalb eines Reports vermieden werden, aber falls in verschiedenen Reports gleichlautende Deklarationen von Variablen benötigt
114
Felder deklarieren
werden, müssen Sie sich bei der Deklaration beispielsweise auf ein
Tabellenfeld im ABAP Dictionary beziehen. Möchten Sie im Report
die Variable LAUFENDE_NUMMER genauso deklarieren wie das Feld
TNUMMER der Tabelle ZTEILNEHMER, schreiben Sie:
DATA laufende_nummer TYPE zteilnehmer-tnummer.
Mit dieser Methode müssen Sie in den einzelnen Reports keine Anpassung dieser Variablen mehr vornehmen. Sollte sich je eine Änderung
hinsichtlich der Länge ergeben, betrifft sie ausschließlich die Domäne
des Tabellenfeldes. Alle betroffenen Reports werden automatisch
beim ersten Start nach der Änderung nachgeneriert, und kein einziger
Quellcode muss aus diesem Grund mehr geändert werden.
Postleitzahlen
Der Praxisbezug dieses Vorgehens wird schnell deutlich, wenn Sie sich
daran erinnern, dass in der Bundesrepublik die Postleitzahlen früher vierstellig waren und im Jahr 1993 auf fünf Stellen umgestellt wurden. Teilweise mussten Entwickler in Hunderten kundenspezifischer Programme
das Postleitzahlenfeld suchen und umstellen, die Programme wieder binden und kompilieren. Dies war eine absolut lästige Angelegenheit – man
glaubt gar nicht, wie viele verschiedene Möglichkeiten es gibt, um das
Wort »Postleitzahl« abzukürzen und eine Variable zu deklarieren! Mit
unserer Methode wäre das Problem schnell gelöst gewesen.
Ähnliche Probleme treten auf, wenn Unternehmen – beispielsweise
bedingt durch eine Fusion – ihre Organisation erheblich umstellen und
plötzlich das früher einstellige Regionskennzeichen nicht mehr ausreicht,
um knapp fünfhundert Regionen zu unterscheiden, in denen das Unternehmen tätig ist. Oder, um zum Beispiel Postleitzahl zurückzukehren, das
Unternehmen wird international tätig und muss neben rein numerischen
Postleitzahlen auch englische Postleitzahlen verwalten, die Buchstaben
enthalten.
Für jeden Datentyp vergibt das System Initialwerte. Für die Datentypen i und p belegt das SAP-System das Feld zunächst mit dem
Wert 0. Manchmal kann es jedoch sehr nützlich sein, eine Variable
selbst mit einem Startwert zu versehen – hierzu verwenden Sie bei
der DATA-Anweisung den Zusatz VALUE. Soll beispielsweise die Variable ZAHL01 eine ganze Zahl darstellen und mit dem Wert 5 vorbelegt
werden, lautet die Anweisung:
115
VALUE
4.2
4
Felder und Berechnungen
DATA zahl01 TYPE i VALUE 5.
Bei einer Vorbelegung mit dem negativen Wert –105 müsste das
negative Vorzeichen mitgeschrieben werden, und die Anweisung
würde entsprechend lauten:
DATA zahl01 TYPE i VALUE -105.
Initialwerte mit
Nachkommastellen
Auch dies ist relativ einfach. Soll die Variable ZAHL01 hingegen eine
Dezimalzahl mit zwei Nachkommastellen sein, wird das Ganze schon
etwas aufwendiger. Lautet der Plan, die Variable ZAHL01 beispielsweise mit dem Wert 3,14 vorzubelegen, würde man eigentlich eine
Anweisung vermuten wie:
DATA zahl01 TYPE p DECIMALS 2 VALUE 3,14.
Dies funktioniert aber leider nicht: Der Doppelpunkt nach DATA fehlt,
und das Komma ist für einen Kettensatz und eine zweite Anweisung
reserviert, in diesem Fall:
DATA 14.
Dies ergäbe leider auch keinen Sinn. Es funktioniert auch nicht, für
das Dezimaltrennzeichen anstelle des Kommas einen Punkt einzusetzen. Grundsätzlich ist diese Idee ausgezeichnet, weil das System
intern als Dezimaltrennzeichen tatsächlich einen Punkt verwendet,
aber wie Sie wissen, ist der Punkt für das Ende einer Anweisung
reserviert. Für das System würden dann zwei Anweisungen in einer
Zeile stehen, wobei die zweite keinen Sinn ergibt.
Lösung: Literal
Deshalb ist es formal korrekt, wenn Sie den Vorbelegungswert in ein
Literal schreiben:
Grundrechenarten
derten Inhalt, mit einer eigenen Anweisung namens CONSTANTS arbeiten. Damit werden wir denjenigen Fällen gerecht, in denen
gewährleistet sein muss, dass ein Feldinhalt während der Laufzeit des
Reports unverändert bleiben soll. Stoßen Sie in der Praxis auf ein solches Beispiel, ist die CONSTANTS-Anweisung geeigneter als die DATAAnweisung. Das System unterstützt dieses Konzept dadurch, dass bei
Veränderungsversuchen dieser Felder Syntax- oder Laufzeitfehler
generiert werden.
Da diese Anweisungen allerdings bis auf den Verwendungszweck
weitgehend identisch sind, verzichten wir für den Einstieg auf die
CONSTANTS-Anweisung. Für einfache arithmetische Operationen
könnten unsere Deklarationen deshalb vorerst so aussehen:
DATA zahl01 TYPE p DECIMALS 2 VALUE '-4.56'.
DATA zahl02 LIKE zahl01 VALUE '5.67'.
DATA ergebnis LIKE zahl01.
Die Variable ZAHL01 gibt den Datentyp p und die Anzahl von zwei
Dezimalstellen vor. Außerdem wird der Variablen die negative Zahl –
4,56 als Startwert zugewiesen. Die Variable ZAHL02 verweist hinsichtlich des Typs und der Dezimalstellen auf die Variable ZAHL01 und
erhält als Startwert die Zahl 5,67. Die Variable ERGEBNIS verweist hinsichtlich des Typs und der Dezimalstellen ebenfalls auf ZAHL01.
Der Vorteil dieser Schreibweise besteht darin, dass bei einer Änderung der Deklaration nur die Deklaration von ZAHL01 geändert werden muss, die Deklarationen von ZAHL02 und ERGEBNIS werden automatisch angepasst.
DATA zahl01 TYPE p DECIMALS 2 VALUE '3.14'.
Bei der Vorbelegung mit der negativen Zahl –4,56 lautet die richtige
Syntax entsprechend:
DATA zahl01 TYPE p DECIMALS 2 VALUE '-4.56'.
4.2.2
CONSTANTS
Konstanten deklarieren
Der Vollständigkeit halber erwähnen wir hier, dass wir für die Deklaration von Konstanten, d. h. Feldern mit gleichbleibendem unverän-
116
4.3
Grundrechenarten
Für die Addition, Subtraktion, Multiplikation und Division in ABAP
haben wir damit bereits alle erforderlichen Variablen deklariert.
Arithmetische Operationen können Sie nun leicht über Zuweisungen
durchführen: Soll beispielsweise der Inhalt der Felder ZAHL01 und
ZAHL02 addiert werden, schreiben Sie einfach:
ergebnis = zahl01 + zahl02.
117
Einfache
arithmetische
Operationen
4.3
4
Felder und Berechnungen
Mathematischer
Ausdruck
Formal ist anzumerken, dass rechts vom Gleichheitszeichen die arithmetische Operation selbst stehen muss. Das Ergebnis der Operation
wird in das links vom Gleichheitszeichen stehende Feld eingetragen,
die Felder ZAHL01 und ZAHL02 behalten auch nach der Berechnung
ihren alten Inhalt. Anders hingegen verhält es sich mit dem Feld links
vom Gleichheitszeichen: Im Feld ERGEBNIS steht nach der Berechnung
nicht mehr der alte, sondern der neue Inhalt; der alte Inhalt des Feldes wurde ersetzt.
Leerzeichen in arithmetischen Operationen
Darüber hinaus ist für die richtige Schreibweise der Umgang mit Leerzeichen wichtig: Sie müssen sowohl vor als auch nach dem Gleichheitszeichen sowie vor und nach dem Rechenzeichen stehen, im oberen Beispiel
dem Pluszeichen (+). Wenn Sie später einmal mit komplexeren Ausdrücken und mehreren Klammerebenen arbeiten, sollten Sie schon jetzt daran
denken, dass in solchen Fällen auch vor und nach jeder Klammer ein Leerzeichen stehen muss. Dabei muss es jeweils mindestens ein Leerzeichen
sein; die Eingabe mehrerer Leerzeichen schadet nicht weiter.
Der Grund für diese Schreibkonvention liegt darin, dass es Funktionen
gibt, die ohne Leerzeichen direkt an das Feld geschrieben werden. Damit
das System nun unterscheiden kann, ob es sich um eine arithmetische
Operation oder eine solche Funktion handelt, wird das Leerzeichen unbedingt benötigt.
Mit Festwerten
arbeiten
Soll zum Inhalt der Variablen ZAHL02 ein Festwert, beispielsweise die
Zahl 2, addiert werden, lautet die Anweisung:
zahl02 = zahl01 + 2.
Auch hier gilt die Regel, dass in der Variablen links vom Gleichheitszeichen der alte Inhalt durch den neuen ersetzt wird. Natürlich
könnte man zum Inhalt derselben Variablen auch einen Festwert
addieren, beispielsweise um einen Zähler um 1 zu erhöhen. Dann
würde die Anweisung lauten:
zahl01 = zahl01 + 1.
Auch hier gilt wieder das gleiche Prinzip: Rechts vom Gleichheitszeichen wird der Wert der Operation bestimmt, d. h. der Inhalt von
ZAHL01 und 1 werden addiert und das Ergebnis der Operation in die
118
Grundrechenarten
4.3
Variable links vom Gleichheitszeichen eingesetzt. Mit anderen Worten: ZAHL01 erhält einen neuen Inhalt.
Für die Subtraktion, Multiplikation und Division lautet die Schreibweise entsprechend:
ergebnis = zahl01 - zahl02.
ergebnis = zahl01 * zahl02.
ergebnis = zahl01 / zahl02.
Als Rechenzeichen für Subtraktionen verwenden Sie das Minuszeichen (-), für Multiplikationen das Sternchen (*) und für Divisionen
den Schrägstrich (/). Anstelle von Rechenzeichen könnten wir auch
die Schlüsselwörter ADD, SUBTRACT, MULTIPLY und DIVIDE verwenden,
die in der Praxis aber relativ selten anzutreffen sind; auch wir werden
im Folgenden darauf verzichten.
Anweisungen mit
Schlüsselwort
Damit haben Sie die Grundvoraussetzungen kennengelernt – und wir
wenden uns den Details zu, denn hierin versteckt sich ja bekanntlich
oft der Teufel. Beispielsweise haben nicht alle Felder die gleichen
Attribute oder sind untereinander verträglich.
4.3.1
Kompatible und konvertible Datenobjekte
Verfügen Felder über die gleichen Attribute, spricht man von kompatiblen Datenobjekten, d. h. dass diese Felder in allen technischen
Eigenschaften (Typ, Feldlänge, Dezimalstellen) vollständig übereinstimmen. Sind die Attribute untereinander verträglich, spricht man
von konvertiblen Datenobjekten. Dabei müssen die Datentypen konvertiert, d. h. umgewandelt werden; Voraussetzung hierfür sind entsprechende Konvertierungsregeln. Falls die Konvertierung nicht
möglich ist, entstehen Syntax- oder Laufzeitfehler.
Kompatible und
konvertible
Datenobjekte
Beruhigend ist, dass im SAP-System bereits zahlreiche Konvertierungsregeln hinterlegt sind (siehe Abschnitt 4.3.2, »Konvertierungsregeln«). Das System wandelt bei entsprechenden Anweisungen nach
diesen Regeln automatisch von einem Datentyp in einen anderen um.
Sofern diese Regeln die von uns gewünschten Ergebnisse erzielen,
haben wir kein Problem. Leider ist dies aber nicht immer der Fall,
und leider existieren auch nicht für alle denkbaren Konstellationen
Konvertierungsregeln.
Automatische
Umwandlung
119
4
Felder und Berechnungen
Fehlerquellen
Ganze und gepackte Zahlen sowie Exponentialzahlen
Zähneknirschend muss außerdem hingenommen werden, dass für solche
Fehler überwiegend die Entwickler selbst verantwortlich sind – denn es gibt
z. B. keinen logischen Grund dafür, in einem Datumsfeld Sternchen und
Sonderzeichen speichern zu wollen. Solche Syntax- oder Laufzeitfehler
geschehen immer wieder einmal auch Fortgeschrittenen, und zwar insbesondere dann, wenn bereits bestehende Anwendungen modifiziert werden
müssen. Auch bei einer Datenübernahme aus anderen Systemen tauchen
solche Fehler auf – für einen Einsteiger erst einmal kein Grund zur Panik.
Sollten beispielsweise ganze Zahlen, gepackte Zahlen und Exponentialzahlen in einer Operation vorkommen, würden die Exponentialzahlen den
Datentyp auf höchster Ebene darstellen. Erst würden alle ganzen Zahlen in
gepackte Zahlen umgewandelt, dann alle Zahlen in Exponentialzahlen,
und schließlich würde die Operation mit Exponentialzahlen berechnet.
Anschließend würde gemäß den Konvertierungsregeln der Wert der Exponentialzahlen in das Ergebnisfeld eingetragen. Sie können sich wahrscheinlich gut vorstellen, dass die Rechengenauigkeit schon durch den
Datentyp des Ergebnisfeldes beeinflusst werden kann.
4.3.2
Was geschieht,
wenn ...
Dezimalzahl
in ganze Zahl
umwandeln
Konvertierung
verschiedener
Datentypen
Grundrechenarten
Konvertierungsregeln
Die Konvertierungsregeln legen fest, wie der Inhalt eines Quellfeldes in
ein Zielfeld eingetragen wird. Quellfelder können verschiedene Datentypen haben, wie die bereits vorgestellten vom Typ p für gepackte und
Typ i für ganze Zahlen. Da es, wie erwähnt, auch weitere Datentypen
für Datums- und Zeitfelder oder Zeichenketten gibt, legen die Konvertierungsregeln pro Datentyp genau fest, wie der Inhalt des Quellfeldes
in das Zielfeld eingestellt wird. Was geschieht, wenn Sie eine gepackte
Zahl in ein Integerfeld stellen, was geschieht, wenn Sie eine gepackte
Zahl zum Inhalt eines Datumsfeldes addieren, oder was geschieht,
wenn Sie eine gepackte Zahl in ein Character-Feld schreiben? Lassen Sie
uns hierzu eine Konvertierungsregel als Beispiel ansehen.
Ist der Quelltyp ein Datenobjekt vom Typ p und der Zieltyp ein
Datenobjekt vom Typ i (eine ganze Zahl), rundet das System die Dezimalstellen des Quellfeldes und stellt den Inhalt rechtsbündig in das
Zielfeld. Ist das Zielfeld von seiner Länge her ausreichend, wird links
mit Nullen aufgefüllt, anderenfalls kommt es zu einem Überlauf bzw.
Laufzeitfehler. Stellen Sie beispielsweise die gepackte Zahl 4,44 in ein
Integerfeld, hat ein Integerfeld danach den Inhalt 4; stellen Sie die
gepackte Zahl 5,55 in ein Integerfeld, hat es den Inhalt 6.
Falls in einer numerischen Operation mehrere verschiedene Datentypen vorkommen, konvertiert ABAP vor dem Ausführen der Operation alle Datentypen in den höchsten vorkommenden Datentyp, führt
dann die Operation mit den konvertierten Werten aus und stellt
anschließend das Ergebnis – eventuell wieder über eine Konvertierungsregel – in das Ergebnisfeld.
120
Um sich das Leben nicht zu erschweren, sollten Sie von Anfang an
darauf achten, Ihre Datenobjekte möglichst kompatibel zu halten.
Der Vollständigkeit halber erwähnen wir hier das COMPUTE-Schlüsselwort, das für numerische Operationen das ursprüngliche ABAP-Kommando ist. Die Schreibweise für eine Addition unter Zuhilfenahme
des Schlüsselwortes COMPUTE lautet:
COMPUTE ergebnis = zahl01 + zahl02.
Wie Sie sehen, ist die Anweisung nur länger, und die Lesbarkeit
wird nicht unbedingt erhöht. Glücklicherweise ist das Schlüsselwort
COMPUTE optional und wird in der Praxis – außer für Recherchezwecke – kaum verwendet; die meisten Entwickler bevorzugen die
verkürzte Schreibweise, die intern vom System exakt gleich behandelt
wird, und auch wir arbeiten im Folgenden ohne das Schlüsselwort
COMPUTE:
ergebnis = zahl01 + zahl02.
Gut zu wissen …
Es gibt allerdings einen Fall, in dem es notwendig ist zu wissen, dass es
die COMPUTE-Anweisung gibt: Falls Sie im System die Dokumentation zu
selten benötigten Funktionen suchen, finden Sie diese nämlich nur bei
der COMPUTE-Anweisung.
Ab SAP NetWeaver 7.0 EHP 2 bzw. SAP NetWeaver 7.3 erlaubt die
COMPUTE-Anweisung den Zusatz EXACT, was bei Berechnungen mit dezimalen Gleitpunktzahlen ein besonderes Verhalten bewirkt. Dieser Zusatz ist nur im Zusammenhang mit dem ausgeschriebenen Schlüsselwort
COMPUTE verfügbar.
121
COMPUTE
4.3
4
Felder und Berechnungen
4.3.3
Verschiedene Fälle
Besonderheiten bei der Division
Für Berechnungen in ABAP stellen Addition, Subtraktion und Multiplikation kein weiteres Problem dar; nur die Division sollten wir uns
noch etwas genauer ansehen. Es gibt Fälle, in denen Sie ein Divisionsergebnis mit Nachkommastellen wünschen, aber auch Fälle, in denen
Sie ganzzahlig ohne Rest teilen möchten. Vielleicht interessiert uns
aber auch nur der Rest einer solchen Division. Für diese verschiedenen Varianten gibt es in ABAP auch verschiedene Anweisungen.
Der einfachste Fall einer Division wird – wie bereits erläutert – durch
den Schrägstrich (/) dargestellt:
DATA zahl01
TYPE p DECIMALS 2 VALUE '4.56'.
DATA zahl02
LIKE zahl01
VALUE '5.67'.
DATA ergebnis LIKE zahl01.
ergebnis = zahl02 / zahl01.
Rechengenauigkeit
DIV
Wenn Sie das Ergebnis mit dem Taschenrechner ausrechnen, erhalten
Sie die Zahl 1,243421053. Wie verhält sich ABAP? Alle Variablen
sind gleichlautend deklariert. Eine gepackte Zahl hat maximal 16
Bytes, dies bedeutet 32 Stellen, inklusive Vorzeichen. Das System
würde das genaue Ergebnis liefern (bei ABAP liegt die Rechengenauigkeit von gepackten Zahlen bei maximal 14 Nachkommastellen), es
aber auf zwei Nachkommastellen in der Zielvariable runden, die wir
selbst mit zwei Dezimalstellen deklariert haben. Diese erhält, durch
ABAP kaufmännisch gerundet, den Wert 1.24.
Falls Sie das Ergebnis einer ganzzahligen Division erhalten möchten,
müssten Sie die Anweisung umschreiben und statt des Schrägstrichs
den Operator DIV einsetzen:
ergebnis = zahl02 DIV zahl01.
Unter sonst gleichen Voraussetzungen ergibt die ganzzahlige Division
für den Quotienten den Wert 1. Da die Zielvariable zwei Dezimalstellen hat, steht dort nach dem Ausführen der Anweisung als Inhalt 1.00.
MOD
Im dritten Fall interessiert uns der Rest der Ganzzahldivision. Für diesen Fall verwenden wir den Operanden MOD, und die Anweisung lautet:
ergebnis = zahl02 MOD zahl01.
122
Codebeispiel zu Feldern und Berechnungen
Wieder unter der Annahme, dass alle übrigen Faktoren gleichbleiben,
ergibt die ganzzahlige Division 1, Rest 1,11. Dieser Rest wird mit
zwei Dezimalstellen in die Zielvariable übertragen, und sie erhält
dementsprechend als Inhalt den Wert 1.11.
1,5 Stunden
Möglicherweise fragen Sie sich jetzt, ob solche Berechnungen überhaupt
praxisrelevant sind: Aber denken Sie nur daran, dass Stunden, Tage oder
Jahre in vielen Systemen nicht in Stunden und Minuten erfasst werden,
sondern mit Dezimalwerten wie »1,5 Stunden«. Um diese Dezimalwerte
auf Stunden und Minuten umzurechnen, kommen Sie um die genannten
Divisionsmöglichkeiten nicht herum. Weitere Beispiele finden Sie in Kapitel 5, »Modifikation von Zeichenketten«, und Kapitel 8, »Rechnen mit
Datum und Zeit, Mengen und Währungen«.
4.4
Codebeispiel zu Feldern und Berechnungen
Schauen wir uns die verschiedenen Berechnungsmöglichkeiten nun
anhand unseres vorbereiteten Reports an:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
*&---------------------------------------------*
*& Report Z_TEILNEHMERLISTE02
*
*&
*
*&---------------------------------------------*
*&
*
*&
*
*&---------------------------------------------*
REPORT
z_teilnehmerliste02
.
* Variable deklarieren
DATA zahl01
TYPE p DECIMALS 2 VALUE '4.56'.
DATA zahl02
LIKE zahl01
VALUE '5.67'.
DATA ergebnis_addition LIKE zahl01.
DATA ergebnis_subtraktion LIKE zahl01.
DATA ergebnis_multiplikation LIKE zahl01.
DATA ergebnis_division_genau LIKE zahl01.
DATA ergebnis_division_ganzzahl LIKE zahl01.
DATA ergebnis_division_rest LIKE zahl01.
123
4.4
4
Felder und Berechnungen
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
* Verarbeitungsteil
zahl01 = zahl01 + 1.
zahl02 = zahl01 + 2.
ergebnis_addition = zahl01 + zahl02.
ergebnis_subtraktion = zahl01 - zahl02.
ergebnis_multiplikation = zahl01 * zahl02.
ergebnis_division_genau = zahl02 / zahl01.
ergebnis_division_ganzzahl = zahl02 DIV zahl01.
ergebnis_division_rest = zahl02 MOD zahl01.
* Ausgabeteil
WRITE: / 'zahl01', zahl01,
/ 'zahl02', zahl02,
/ 'ergebnis_addition:',
ergebnis_addition,
/ 'ergebnis_subtraktion:',
ergebnis_subtraktion,
/ 'ergebnis_multiplikation:',
ergebnis_multiplikation,
/ 'ergebnis_division_genau:',
ergebnis_division_genau,
/ 'ergebnis_division_ganzzahl:',
ergebnis_division_ganzzahl,
/ 'ergebnis_division_rest:',
ergebnis_division_rest.
Listing 4.1 Report Z_TEILNEHMERLISTE02
Codebeispiel zu Feldern und Berechnungen
Zeile 12
Die Variable ZAHL01 wird als gepackte Zahl mit zwei Nachkommastellen deklariert, und sie erhält als Startwert die Zahl 4,56.
Zeile 13
Die Variable ZAHL02 erhält als Startwert die Zahl 5,67 und die gleichen Eigenschaften wie ZAHL01.
Zeile 14 bis 19
Die Ergebnisfelder werden deklariert; für jedes Ergebnis wird ein
eigenes Feld angelegt. Natürlich hätte man nur das Feld ERGEBNIS
anlegen und immer wieder überschreiben können, aber es hängt von
der Art der Weiterverarbeitung ab, ob man einen Feldinhalt später
vielleicht wieder benötigt oder nicht – und Sie möchten gleich die
verschiedenen Berechnungsergebnisse ausgeben.
Nicht mit Variablen geizen
Arbeitsspeicher und Hardware sind kein Argument mehr, um mit Variablen zu knausern, sondern Lesbarkeit und Transparenz sind heute die
wesentlicheren Qualitätsfaktoren. Wenn es der Qualität dient, sollten Sie
deshalb nicht mit Variablen geizen.
Zeile 21
Der Verarbeitungsteil beginnt.
Anmerkungen zum Quellcode
Nach den Kommentarzeilen gliedert sich unser Report in drei Teile,
die im Folgenden kurz beschrieben sind.
Zeile 22
Der Wert des Feldes ZAHL01 wird um 1 erhöht. Vor der Anweisung
war der Inhalt 4.56, danach ist er 5.56.
Zeile 1 bis 8
Diese Zeilen werden vom System wieder automatisch als Kommentarzeilen generiert.
Zeile 11
Der Quellcode wird in übersichtliche Abschnitte eingeteilt, die der
Lesbarkeit dienen. In Listing 4.1 werden diese Abschnitte mit drei
Kommentarzeilen gebildet: Variable deklarieren (Zeile 11 bis 19),
Verarbeitungsteil (Zeile 21 bis 29) und Ausgabeteil (Zeile 31 bis 39).
124
4.4
Zeile 23
Das Feld ZAHL02 erhält den Inhalt aus der Addition von ZAHL01 und
der Zahl 2. Der alte Inhalt von ZAHL02 war 5.67, der neue Inhalt ist
7.56.
Zeile 24
Das Feld ERGEBNIS_ADDITION erhält das Ergebnis der Operation
ZAHL01 plus ZAHL02, das ist 5.56 plus 7.56 und ergibt 13.12.
125
Frage der Weiterverarbeitung
4
Felder und Berechnungen
Codebeispiel zu Feldern und Berechnungen
4.4
Zeile 25
Das Ergebnis der Subtraktion von ZAHL01 und ZAHL02 ist die negative
Zahl 2. Sie wird im Ergebnisfeld ERGEBNIS_SUBTRAKTION als 2.00- dargestellt.
Zeile 26
Da ZAHL01 inzwischen den Wert 5.56 und ZAHL02 den Wert 7.56 hat,
lautet das Ergebnis der Multiplikation auf zwei Nachkommastellen
gerundet 42.03.
Zeile 27
Das Ergebnis der Division: 7.56 geteilt durch 5.56 ist gerundet 1.36 –
und gleichzeitig der neue Inhalt von ERGEBNIS_DIVISION_GENAU.
Zeile 28
Die ganzzahlige Division ergibt 1.00. Durch die Formatierung werden die eigentlich überflüssigen Dezimalstellen mitgezogen.
Abbildung 4.6 Listbild zum Beispiel der Grundrechenarten
Formal und logisch ist hier alles richtig – aber auch das Auge programmiert mit! Da hier die Literale am Zeilenanfang unterschiedlich
lang sind, stehen die ausgegebenen Variablen an unterschiedlichen
Spaltenpositionen und damit nicht spaltengerecht. Deshalb kümmern
wir uns im letzten Schritt noch um die optische Spaltenaufteilung.
Verbesserte Listaufbereitung
Zeile 31
Dieses kleine Problem lösen Sie, indem Sie dem WRITE-Kommando
bei der Ausgabe mitteilen, an welcher Position einer Zeile die Variable abgebildet werden soll. Möchten Sie die Variable ab Spalte 30
ausgeben, müssen Sie Zeile 32 von Listing 4.1 folgendermaßen
ändern:
Der Abschnitt für die Listerstellung beginnt.
WRITE: / 'zahl01', 30 zahl01,
Zeile 29
Der Rest der Ganzzahldivision beträgt 2.00. Dieser Wert wird in das
Feld ERGEBNIS_DIVISION_REST übertragen.
Zeile 32 bis 39
Die WRITE-Anweisung gibt in einer neuen Zeile in Spalte 1 ein Literal
als Text aus und anschließend mit einer Leerstelle den Inhalt der Variablen. Die WRITE-Anweisung ist als Kettensatz geschrieben, hinter
dem sich eigentlich 16 WRITE-Anweisungen verbergen. Hinter der
Anweisung WRITE steht ein Doppelpunkt; die einzelnen Anweisungen
sind durch Kommata getrennt, und nur die letzte Anweisung des Kettensatzes wird mit einem Punkt abgeschlossen.
Ausgabe des Quellcodes
Wenn Sie den Report wie eben editiert, gesichert, geprüft und aktiviert haben, können Sie ihn ausführen, und das Listbild sollte wie in
Abbildung 4.6 aussehen.
126
Verbesserungswürdige Optik
Vor die betreffende Variable schreiben Sie einfach die Spaltenposition der Druckzeile. Beachten Sie, dass zwischen Spaltenposition und
Variable mindestens eine Leerstelle bestehen bleiben muss.
Komplexe Listen
Die restlichen relevanten Zeilen könnten Sie entsprechend editieren,
indem Sie vor jede betroffene Variable die Ausgabeposition schreiben. Bei
kurzen und überschaubaren Ausgaben ist dieses Vorgehen auch vertretbar. Sollte eine Liste allerdings aufwendiger und komplexer zusammengesetzt sein, könnten Sie es auch mit der nachfolgend beschriebenen Möglichkeit versuchen – ähnlich des Verweises bei den Datendeklarationen mit
LIKE.
127
Felder einer Liste
spaltengerecht
ausgeben
4
Felder und Berechnungen
UNDER
Einen Verweis auf ein anderes Objekt können Sie auch bei der Druckposition verwenden, indem Sie einfach auf die Position einer anderen
Variablen verweisen. Sollte sich die Position der führenden Variablen
ändern, ziehen alle anderen referenzierenden Variablen automatisch
nach. Hierzu wird beim WRITE-Kommando die Aufbereitungsoption
UNDER verwendet. Editieren Sie die Zeilen 33 bis 39 wie folgt:
33
34
35
36
37
38
39
/ 'zahl02', zahl02 UNDER zahl01,
/ 'ergebnis_addition:',
ergebnis_addition UNDER zahl01,
/ 'ergebnis_subtraktion:',
ergebnis_subtraktion UNDER zahl01,
/ 'ergebnis_multiplikation:',
ergebnis_multiplikation UNDER zahl01,
/ 'ergebnis_division_genau:',
ergebnis_division_genau UNDER zahl01,
/ 'ergebnis_division_ganzzahl:',
ergebnis_division_ganzzahl UNDER zahl01,
/ 'ergebnis_division_rest:',
ergebnis_division_rest UNDER zahl01.
Nach dem Sichern, Prüfen, Aktivieren und Ausführen des Reports
sollte das Listbild wie in Abbildung 4.7 aussehen.
Abbildung 4.7 Listbild mit spaltengerechter Ausgabe
128