Anforderungen an ABAP-Programme in Unicode

Werbung
Anforderungen an ABAP-Programme in
Unicode-Systemen
Version: 3. Mai 2007
Inhalt
Seite
1. Codes
3
2. ABAP-Entwicklung unter Unicode
4
3. Bezeichnungen und Vereinbarungen
5
3.1
3.2
3.3
3.4
Datentypen
Datenlayout von Strukturen
Unicode-Fragmentsicht
Zulässige Zeichen
5
6
7
7
4. Einschränkungen in Unicode-Programmen
4.1
4.2
4.3
4.4
4.5
4.6
4.7
4.8
4.9
Zeichenartige und numerische Operanden
Zugriffe mit Offset- und Längenangaben
Zuweisungen
Vergleiche
Verarbeitung von Zeichenketten
Typprüfung und Typkompatibilität
Änderungen bei Datenbank-Operationen
Längen- und Abstandsermittlung
Sonstige Änderungen
5. Neue ABAP-Anweisungen für Unicode
5.1
5.2
5.3
5.4
5.5
5.6
5.7
5.8
5.9
5.10
5.11
8
8
9
11
14
15
16
17
18
19
21
Stringverarbeitung für Bytefolgen
Längen- und Abstandsermittlung
Zuweisungen an Feldsymbole
Includes mit Gruppennamen
Dynamische Erzeugung von Datenobjekten
Dynamische Feldzuweisungen
Ablage von Daten als Cluster
Dateischnittstelle
Up- und Download von Dateien
Generische Typen für Feldsymbole und Parameter
Aufbereitung von Listen
6. Neue Klassen für Unicode
21
22
23
26
27
28
29
30
32
32
32
35
6.1 Ermittlung von Feldeigenschaften
6.2 Konvertierung von Daten
35
37
7. RFC und Unicode
38
8. Abrundungsmaßnahmen
38
9. Weitere Beispielprogramme zur Unicode-Umstellung
40
10. Glossar
59
11. Index der Schlüsselworte
60
2
1. Codes
Bisher werden bei SAP verschiedene Codes für die Verschlüsselung von Zeichen
verschiedener Schriften verwendet, zum Beispiel ASCII, EBCDI oder Double Byte
Codepages.
·
ASCII (American Standard Code for Information Interchange) verschlüsselt jedes
Zeichen durch 1 Byte = 8 Bit. Damit lassen sich höchstens 28 = 256 Zeichen
darstellen, denen die Kombinationen [00000000, 11111111] zugeordnet werden.
Gebräuchliche Codepages sind zum Beispiel ISO88591 für westeuropäische oder
ISO88595 für kyrillische Schriften.
·
EBCDIC (Extended Binary Coded Decimal Interchange) verschlüsselt ebenfalls
jedes Zeichen durch 1 Byte, womit sich wiederum 256 Zeichen abbilden lassen.
EBCDIC 0697/0500 ist ein altes IBM Format, das zum Beispiel auf AS400 für
westeuropäische Schriften verwendet wird.
·
Double Byte Codepages benötigen 1 bis 2 Byte je Zeichen. Damit können 216 =
65536 Kombinationen gebildet werden, wobei in der Regel nur 10000 - 15000
Zeichen belegt sind. Als Codepages werden zum Beispiel SJIS für japanische und
BIG5 für traditionelle chinesische Schrift verwendet.
Mit diesen Zeichensätzen kann jede für SAP interessante Sprache einzeln abgedeckt
werden. Schwierigkeiten ergeben sich allerdings, wenn man in einem zentralen
System Texte aus verschiedenen inkompatiblen Zeichensätzen mischen möchte.
Auch der Austausch von Daten zwischen Systemen mit inkompatiblen Zeichensätzen
kann zu völlig undefinierten Situationen führen.
Die Lösung des Problems ist die Verwendung eines Codes, der alle Zeichen dieser
Erde umfaßt. Dieser Code heißt Unicode (ISO/IEC 10646) und besteht mindestens
aus 16 Bit = 2 Byte, alternativ aus 32 Bit = 4 Byte je Zeichen. Obwohl der
Umstellungsaufwand für SAP-Kernel und Anwendungen enorm ist, ergeben sich
langfristig durch die Einführung von Unicode große Vorteile:
·
·
·
·
·
Das gesamte Internet (www) und damit auch mySAP.com basieren auf Unicode,
der damit Grundvoraussetzung für internationale Wettbewerbsfähigkeit ist.
Mit Unicode können alle SAP-Anwender ein zentrales System installieren, das
die Geschäftsprozesse der gesamten Welt abdeckt.
Auch Firmen mit verschiedenen verteilten Systemen wollen meist weltweite
Konzerndaten verdichtet aufbereiten. Dies ist ohne Unicode nur bedingt
möglich.
Unter Unicode können gleichzeitig mehrere Sprachen auf einem Frontend
verwendet werden.
Unicode wird benötigt für einen anwendungsübergreifenden Datenaustausch
ohne Datenverlust durch inkompatible Zeichensätze. Als mögliche Form der
Darstellung von Dokumenten im World Wide Web (www) kann dabei zum
Beispiel XML verwendet werden.
ABAP-Programme müssen überall dort geändert werden, wo eine explizite oder
implizite Annahme über die interne Länge eines Zeichens gemacht wird. Dadurch
3
wird eine neue Abstraktionsebene erreicht, die es erlaubt, dieselben Porgramme
sowohl in einem herkömmlichen als auch in einem Unicode System ablaufen zu
lassen. Außerdem hält man sich damit die Möglichkeit offen, bei einer weiteren
Vergrößerung des Unicode-Zeichenvorrates eine interne Darstellung der UnicodeZeichen mit 2 oder 4 Byte zu wählen.
Die Beispiele in den nachfolgenden Kapiteln unterstellen einen Unicode mit einer
Verschlüsselung von 2 Byte je Zeichen.
2. ABAP-Entwicklung unter Unicode
Ein Unicode-fähiges ABAP-Programm (UP) ist ein Programm, bei dem alle UnicodePrüfungen wirksam sind. Ein solches Programm liefert in einem Nicht-UnicodeSystem (NUS) dieselben Ergebnisse wie in einem Unicode-System (US). Um die
entsprechenden Syntaxprüfungen durchzuführen, muß das Unicodeflag in den
Dynpros der Programm- und Klasseneigenschaften aktiviert werden.
In einem US können nur Programme ausgeführt werden, die das Unicodeflag gesetzt
haben. Für alle SAP-Programme muß zukünftig das Unicodeflag gesetzt sein, damit
sie auf Unicode-Systemen laufen können. Ist das Unicodeflag für ein Programm
gesetzt, erfolgt die syntaktische Prüfungen und die Programmausführung gemäß
den Regeln, die in diesem Dokument beschriebenen sind. Dies ist unabhängig
davon, ob es sich um ein US oder ein NUS handelt. Das Unicodeflag wird zukünftig
für alle Programme und Klassen gesetzt, die neu angelegt werden.
Ist das Unicodeflag nicht gesetzt, kann das Programm nur in einem NUS ausgeführt
werden. Für solche Programme sind die nachfolgend beschriebenen Syntax- und
Semantikänderungen nicht wirksam. Es können jedoch alle Spracherweiterungen
benutzt werden, die im Zusammenhang mit der Unicode-Umstellung eingeführt
wurden.
Die mit dem Unicodeflag verbundenen Änderungen und Einschränkungen bewirken,
daß Programme in US und NUS weitestgehend mit gleicher Semantik ausgeführt
werden, wobei in wenigen Fällen dennoch Unterschiede auftreten können.
Programme, die in beiden Systemen laufen sollen, müssen daher auch auf beiden
Plattformen getestet werden.
Zusätzlich wurden im Rahmen der Unicode-Einführung folgende Umstellungen in
der Syntaxprüfung an das Unicode-Flag gebunden:
1. Nicht erreichbare Anweisungen führen in UP zu einem Syntaxfehler. In NUP gab
dies bisher nur eine Syntaxwarnung.
2. Der Aufruf eines Funktionsbausteins, dessen Parameternamen statisch als Literal
oder als Konstante angegeben werden, führt in UP zu einer behandelbaren
Ausnahme, wenn ein falscher Parametername angegeben wird. Dies gilt nur für
Funktionsbausteine, die nicht via Remote Function Call aufgerufen werden. In
NUP wurde ein falscher Name bisher ignoriert.
4
Für die Umstellung von Programmen auf US wird folgendes Vorgehen empfohlen:
·
Zuerst sollte die Transaktion uccheck im NUS gestartet werden, welche die
Unicode-relevanten Syntaxfehler für eine kleine Programmenge ermittelt. Sind
Syntaxfehler für eine größere Programmenge zu ermitteln, dann kann ein
entsprechender SAMT-Scan mit dem Hauptprogramm RSUNISCAN_FINAL und der
Unterroutine SAMT_SEARCH eingeplant werden.
·
Bevor im NUS das Unicodeflag in den Eigenschaften des betreffenden
Programmes angekreuzt wird, müssen sämtliche Syntaxfehler beseitigt werden.
·
Nach Aktivierung des Unicodeflags im NUS wird immer die UnicodeSyntaxprüfung für dieses Programm durchgeführt. Dazu besteht im Editor unter
Hilfsmittel -> Einstellungen -> Editor die Möglichkeit, maximal 50 Syntaxfehler
gleichzeitig durch Ankreuzen des entsprechenden Feldes aufzulisten.
Wenn alle syntaktischen Anforderungen im NUS erfüllt sind, muß dasselbe
Programm anschließend im NUS und im US getestet werden. Testziele sind die
Erkennung von Laufzeitfehlern und die Korrektheit der Ergebnisse in beiden
Systemen. Um Laufzeitfehler im Vorfeld auszuschließen, sollten Feldsymbole
und Parameter immer typisiert werden, damit problematische Stellen bereits
von der Syntaxprüfung erkannt werden.
·
X
ABAP: Programmeigenschaften VER00778 ändern
Titel
Doku-Check
Origibalsprache
DE
Deutsch
Erstellt
09.06.1999
Schröder
Letzte Änderung
15.01.2000
Schröder
Status
aktiv
Attribute
Typ
Ausführbares Programm
Status
Produktives SAP-Standardprogramm
Anwendung
Basis (System)
Berechtigungsgruppe
Paket
SABP
Logische Datenbank
Selektionsbildversion
Editorsperre
Festpunktarithmetik
Unicodeprüfungen aktiv
Start über Variante
Sichern
3. Bezeichnungen und Vereinbarungen
3.1 Datentypen
Zu den Datentypen, die in UP als zeichenartig interpretiert werden, gehören:
5
·
·
·
·
·
·
C
N
D
T
STRING
Zeichenartige Strukturen
Character (Buchstaben, Ziffern, Sonderzeichen)
Numerisch Character (Ziffern)
Datum
Zeit
Zeichenkette
Strukturen, die direkt oder in Unterstrukturen nur
Felder der Typen C, N, D oder T enthalten
Ein Zeichen dieses Typs ist im NUS 1 Byte und im US so lang, wie es der Länge eines
Zeichens auf der jeweiligen Plattform entspricht. Nicht mehr unterstützt wird der
Datentyp W.
Als byteartig werden Variable der Typen X und XSTRING bezeichnet. Strukturen
werden nach folgenden Merkmalen unterschieden:
·
·
·
·
Flache Struktur enthalten nur Felder der Elementartypen C, N, D, T, F, I, P und
X oder wiederum Strukturen mit diesen Typen.
Tiefe Strukturen enthalten zusätzlich zu den Elementartypen Strings, interne
Tabellen und Feld- oder Objektreferenzen.
Geschachtelte Strukturen sind Strukturen, die wiederum Unterstrukturen als
Komponenten enthalten.
Nicht geschachtelte Strukturen bezeichnen Strukturen, die keine weiteren
Strukturen enthalten.
3.2 Datenlayout von Strukturen
Für einige Datentypen wie I, F oder Objektreferenzen gibt es bestimmte
Ausrichtungsanforderungen, die von der jeweiligen Plattform abhängen. Felder mit
einem solchen Typ müssen im Speicher auf Adressen beginnen, die durch 4 oder 8
teilbar sind. Zeichenartigen Typen stehen an Speicheradressen, die je nach
Unicode-Darstellung durch 2 oder 4 teilbar sind.
Innerhalb einer Struktur werden vor Komponenten mit Ausrichtungsanforderungen
gegebenenfalls Bytes eingefügt, um die notwendige Ausrichtung zu erreichen. Diese
Bytes werden als Alignment (A) bezeichnet. Grundsätzlich wird eine Unterstruktur
gemäß der größten Alignmentanforderung eines der enthaltenen Felder
ausgerichtet. Dabei gilt eine enthaltene Unterstruktur als Feld. Includes in
Strukturen gelten in diesem Sinne als Unterstruktur.
Bei dem folgenden Beispiel einer Struktur mit drei Feldern werden weder in NUS
noch in US Alignments gebildet:
BEGIN OF struc1,
a(1) TYPE X,
b(1) TYPE X,
c(6) TYPE C,
END OF struc1.
Dagegen werden im nächsten Beispiel in US Alignments gebildet, in NUS jedoch
nicht. Die erste Alignment-Lücke wird wegen der Ausrichtung der Struktur struc3,
6
die zweite wegen der Ausrichtung des C-Feldes c und die dritte wegen der
Adressierung der Intergerzahl d gebildet.
BEGIN OF struc2,
a(1) TYPE X,
BEGIN OF struc3,
b(1) TYPE X,
c(6) TYPE C,
END OF struc3,
d
TYPE I,
END OF struc2.
NUS
a b
c
US
a A b A
d
c
|
A
struc3
d
|
3.3 Unicode-Fragmentsicht
Für Prüfungen in UP, zum Beispiel für die Zulässigkeit von Zuweisungen und
Vergleichen, ist das Datenlayout von Strukturen relevant, das sich in der UnicodeFragmentsicht niederschlägt. Diese Sicht zerlegt die Struktur in Alignmentlücken, in
byte- und zeichenartige Bereiche und alle übrigen Typen wie P, I, F, Strings,
Referenzen oder interne Tabellen.
Nebeneinander liegende zeichenartige Komponenten einer Struktur mit Ausnahme
von Strings werden intern genau dann zu einer Gruppe zusammengefaßt, wenn
zwischen diesen Komponenten keine Alignment-Lücken liegen. Dabei werden alle
möglichen Ausrichtungsanforderungen für Zeichen berücksichtigt. In gleicher Weise
werden auch nebeneinander liegende byteartige Komponenten zusammengefaßt.
BEGIN OF struc,
a(2) TYPE C,
b(4) TYPE N,
c
TYPE D,
d
TYPE T,
e
TYPE F,
f(2) TYPE X,
g(4) TYPE X,
h(8) TYPE C,
i(8) TYPE C,
END OF struc.
Im folgenden Beispiel zeigen F1 - F6 die einzelnen Fragmente der Struktur struc:
a
|
b
c
d
F1
A
e
f
| F2 |
F3
| F4
7
g
A
h
| F5 |
F6
i
|
3.4 Zulässige Zeichen
In einem Unicode-System werden auch alle ABAP-Programmquellen als Unicode
abgelegt. Wie in ABAP Objects sind in Programmen mit Unicode-Flag nur folgende
Zeichen für Bezeichner erlaubt:
1. Die Buchstaben a - z und A - Z ohne Umlaute
2. Die Ziffern 0 - 9
3. Der Unterstrich _
Aus Kompatibilitätsgründen sind auch noch die Zeichen %, $, ?, -, #, * und /
erlaubt, die aber nur in begründeten Ausnahmefällen verwendet werden sollten.
Der Schrägstrich ist allerdings nur zum Abtrennen von Namensräumen in der Form
/name/ möglich, wobei zwischen zwei Schrägstrichen mindestens drei Zeichen
stehen müssen.
Damit Programme ohne Konvertierungsverluste von einem US in ein NUS
transportiert werden können, sollten auch in einem US für Kommentare und
Literale keine Zeichen verwendet werden, die in einem NUS nicht darstellbar sind.
4. Einschränkungen in Unicode-Programmen
Die für Unicode erforderlichen Anpassungen und Restriktionen wurden seitens der
ABAP-Entwicklung auf das Wesentliche beschränkt, um den Aufwand für die
Umstellungen der ABAP-Anwender möglichst gering zu halten. Dies hat in einigen
Fällen jedoch zu komplexeren Regeln geführt, beispielsweise bei Zuweisungen und
Vergleichen zwischen inkompatiblen Strukturen.
4.1 Zeichenartige und numerische Operanden
Bisher galt in ABAP die Regel, daß flache Strukturen als Argumente von ABAPAnweisungen auch überall dort verwendet werden können, wo Einzelfelder vom Typ
C erwartet wurden. In UP ist dies nicht mehr generell erlaubt. In UP kann bei einer
beliebigen Anweisung, die nur ein Einzelfeld erwartet, genau dann ein
strukturiertes Feld verwendet werden, wenn dieses aus zeichenartigen
Elementartypen oder aus rein zeichenartigen Unterstrukturen besteht. Die Struktur
wird wie ein Einzelfeld vom Typ C behandelt.
Einschränkungen im Vergleich zu NUS ergeben sich hauptsächlich dadurch, daß
flache Strukturen nur noch eingeschränkt und Felder vom Typ X oder XSTRING
niemals als zeichenartig betrachtet werden. Flache Strukturen werden auch nur
noch dann als numerisch aufgefaßt, wenn sie rein zeichenartig sind. Numerische
Argumente sind zum Beispiel Offset- oder Indexangaben wie bei READ TABLE ...
INDEX i. Die Zeichenartigkeit von Strukturen zeigen die beiden folgenden Beispiele:
8
BEGIN OF struc1,
a(2) TYPE C,
b(2) TYPE C,
x(1) TYPE X,
i
TYPE I,
END OF struc.
BEGIN OF struc2,
a(2) TYPE C,
n(6) TYPE N,
d
TYPE D,
t
TYPE T,
END OF struc.
Nicht
zeichenartig
Zeichenartig
Ein weiteres Beispiel ist der Gruppenwechsel bei internen Tabellen, veranlaßt
durch das Schlüsselwort AT. In NUS werden Felder vom Typ X, die sich rechts vom
Gruppenschlüssel befinden, als zeichenartig behandelt und daher mit einem Stern
aufgefüllt. Dagegen erhält derselbe Typ in US seinen Initialwert.
4.2 Zugriffe mit Offset- und Längenangaben
Allgemein sind Offset/Längenangaben kritisch, weil die Länge der einzelnen
Zeichen plattformabhängig ist und damit zunächst nicht geklärt ist, ob gerade bei
gemischten Strukturen die Einheit Byte oder Zeichen gemeint ist. Zum Teil wurden
daher erhebliche Einschränkungen erforderlich, jedoch ist ein Offset/Längenzugriff
auch weiterhin in dem Umfang möglich, wie er nachfolgend dargestellt wird. Von
dieser Regelung betroffen sind Zugriffe auf Einzelfelder und Strukturen, die
Übergabe von Parametern an Unterprogramme und schließlich das Arbeiten mit
Feldsymbolen.
·
Zugriffe auf Einzelfelder
Zugriffe mit Offset/Länge sind auf zeichenartige Einzelfelder, auf Strings und
auf Einzelfelder der Typen X und XSTRING zulässig. Offset und Länge werden bei
zeichenartigen Feldern und Feldern vom Typ STRING zeichenweise interpretiert.
Nur bei den Typen X und XSTRING werden die Werte für Offset und Länge in
Byte angenommen.
·
Zugriffe auf Strukturen
Der Zugriff mit Offset und Länge auf strukturierte Felder wird als unerwünschte
Programmiertechnik angesehen. Ein solcher Zugriff führt zu Fehlern, wenn in
dem mit Offset und Länge überstrichenen Bereich sowohl zeichen- als auch
nicht zeichenartige Komponenten liegen.
Offset/Längenzugriffe auf Strukturen sind in UP nur zulässig, wenn sie flach sind
und die Offset- und Längenangabe nur zeichenartige Felder ab dem
Strukturbeginn einschließt. Das nachfolgende Beispiel zeigt eine Struktur mit
zeichen- und nicht zeichenartigen Feldern. Ihre Definition im ABAP-Programm
und die daraus resultierende Belegung im Hauptspeicher gestaltet sich so:
9
BEGIN OF STRUC,
a(3) TYPE C,
b(4) TYPE N,
c
TYPE D,
d
TYPE T,
e
TYPE F,
f(26) TYPE C,
g(4) TYPE X,
END OF STRUC.
a
|
b
c
F1
"Länge 3 Zeichen
"Länge 4 Zeichen
"Länge 8 Zeichen
"Länge 6 Zeichen
"Länge 8 Byte
"Länge 28 Zeichen
"Länge 2 Byte
d
A
e
| F2 |
F3
|
f
g
F4
|F5|
Intern weist die Fragmentsicht fünf Bereiche [F1, F5] auf, wobei hier ein OffsetLängenzugriff nur im Anfangsstück F1 möglich ist. Anweisungen wie struc(21)
oder struc+7(14) werden seitens ABAP-Interpreter akzeptiert und wie ein
Einzelfeld vom Typ C behandelt. Dagegen ist ein Zugriff struc+57(2) nur noch in
NUP zulässig. Ist ein Offset/Längenzugriff auf eine Struktur erlaubt, dann
werden in UP sowohl Offset- als auch Längenangaben stets als Zeichen
interpretiert.
·
Parameterübergabe an Formroutinen
Die Parameterübergabe bei PERFORM erlaubte bisher, feldübergreifende Offsetund Längenangaben zu verwenden. Das wird zukünftig in UP verboten. Vielmehr
führen hier Offset- und Längenzugriffe über Feldgrenzen hinaus zu einem
Syntax- oder Laufzeitfehler. Zum Beispiel würden für ein zehnstelliges C-Feld c
Zugriffe der Art c+15 oder c+5(10) einen solchen Fehler auslösen.
Wird bei einem Parameter nur ein Offset, aber keine Länge angegeben, so
wurde bisher die gesamte Länge des Feldes und nicht die Restlänge als Länge
für den Zugriff verwendet. Damit sind Parameterangaben nur mit Offset
feldübergreifend und lösen daher in UP einen Syntaxfehler aus. Ein PERFORM
test USING c+5 ist daher verboten.
Auch in UP kann weiterhin bei Parametern in der Form feld+off(*) die Restlänge
ab Offset off spezifiziert werden.
·
Ranges für Offset- und Längenzugriffe bei Feldsymbolen
In UP wird sichergestellt, daß Offset/Längenzugriffe bei ASSIGN nur innerhalb
eines vorgegebenen Bereichs (Range) zulässig sind. Im Normalfall stimmt der
Range bei elementaren Feldern mit den Feldgrenzen und bei flachen Strukturen
mit dem rein zeichenartigen Anfangsstück überein. Durch einen speziellen
RANGE-Zusatz bei ASSIGN kann der Range auch über diese Grenzen hinaus
erweitert werden.
Feldsymbolen wird ein für Offset/Längenangaben zulässiger Range zugeordnet.
Wird die Quellangabe einer ASSIGN-Anweisung mit einem Feldsymbol
angegeben, so übernimmt das Ziel-Feldsymbol den Range der Quelle. Sofern
nicht explizit angegeben wird, bestimmt sich der RANGE wie folgt:
10
ASSIGN feld TO <f>.
In UP erhält <f> die Feldgrenzen von feld als Range, wobei feld kein Feldsymbol
ist.
ASSIGN <g> TO <f>.
<f> übernimmt den Range von <g>.
ASSIGN elfeld+off(len) TO <f>.
In UP erhält <f> die Feldgrenzen des Elementarfeldes elfeld als Range.
ASSIGN <elfld>+off(len) TO <f>.
<f> übernimmt den Range des elemtaren Feldes elfeld.
ASSIGN struc+off(len)
TO <f>.
ASSIGN <struc>+off(len) TO <f>.
In UP bestimmt das rein zeichenartige Anfangsstück der flachen Strukturen struc
oder <struc> die Range-Grenzen.
Kann die Zuweisung an das Feldsymbol nicht erfolgen, weil die Offset- oder
Längenangabe den zulässigen Range überschreitet, wird das Feldsymbol in UP
auf UNASSIGNED gesetzt. Andere Prüfungen wie zum Beispiel Typ- oder
Alignmentprüfungen führen in UP zu einem Laufzeitfehler. Generell werden
Offset- und Längenangaben bei den Datentypen C, N, D und T sowie bei flachen
Strukturen in Zeichen und sonst in Bytes gezählt.
·
Offset ohne Längenangabe bei Feldsymbolen
Bisher hatte ASSIGN feld+off TO <f> das Sonderverhalten, daß die
Feldlänge und nicht die Restlänge von feld genommen wurde, wenn nur ein
Offset, aber keine Länge angegeben wurde. Somit ist ein ASSIGN mit
feldübergreifendem Offset unter Unicode problematisch und es gelten daher für
diese Konstellation folgende Regeln:
1. Mit
ASSIGN feld+off(*)... kann weiterhin explizit die Restlänge
spezifiziert werden.
2. ASSIGN <f>+off TO <g> ist nur noch dann erlaubt, wenn der LaufzeitTyp von <f> flach und elementar ist, also C, N, D, T (Offset in Zeichen) oder
X (Offset in Bytes).
3. ASSIGN feld+off TO <g> wird generell syntaktisch verboten, weil hier
jeder Offset <> 0 eine Range-Überschreitung bewirken würde. Davon
ausgenommen sind Fälle, bei denen ein RANGE-Zusatz angegeben ist.
Mit diesen Regeln ist normalerweise das Weiterschalten eines Feldsymbols
mittels ASSIGN <f>+n TO <f> über ein elementares Feld, wie es zum
Beispiel in einer Schleife vorkommt, auch in Zukunft möglich.
11
4.3 Zuweisungen
Dieser Abschnitt behandelt impizite und explizite Typkonvertierungen mit dem
Gleichheitszeichen (=) oder der Anweisung MOVE. Zwei Felder sind konvertibel,
wenn der Inhalt des einen Feldes dem zweiten zugewiesen werden kann, ohne
einen Laufzeitfehler auszulösen.
Bei der Konvertierung zwischen strukturierten Feldern beziehungsweise zwischen
einem strukturierten Feld und einem Einzelfeld wurden flache Strukturen bisher
wie C-Felder behandelt. Dies ist mit der Einführung von Unicode zu fehleranfällig
geworden, da unsicher ist, ob Programme mit plattformunabhängiger Semantik
ablauffähig sind.
Zwei Felder sind kompatibel, wenn sie in Typ und Länge gleich sind. Bei der
Zuweisung von tiefen Strukturen müssen deshalb die Fragmentsichten
übereinstimmen. Bei Zuweisung und Vergleich von tiefen Strukturen wurde bisher
schon gefordert, daß Typkompatibilität zwischen den Operanden besteht, womit
beide Operanden strukturell gleich aufgebaut sein müssen. Diese Forderung wird
auch für Unicode-Systeme beibehalten.
·
Konvertierung zwischen flachen Strukturen
Zur Überprüfung, ob die Konvertierung überhaupt erlaubt ist, wird zunächst die
Unicode-Fragmentsicht der Strukturen gebildet, indem zeichen- und byteartige
Gruppen sowie Alignment-Lücken und sonstige Komponenten zusammengefaßt
werden. Wenn die Fragmente von Quell- und Zielstruktur mit Typ und Länge in
der Länge der kürzeren Struktur übereinstimmen, ist die Konvertierung erlaubt.
Die Zuweisung ist ebenfalls unter folgenden Annahmen zulässig:
1. Beide Strukturen stimmen in allen Fragmenten bis zum vorletzten der
kürzeren Struktur überein.
2. Das letzte Fragment der kürzeren Struktur ist eine zeichen- oder byteartige
Gruppe.
3. Das korrespondierende Fragment der längeren Struktur ist eine zeichen- oder
byteartige Gruppe größerer Länge.
Wenn die Zielstruktur länger als die Quellstruktur ist, werden die zeichenartigen
Komponenten des Rests mit Leerzeichen gefüllt. Alle anderen Komponenten des
Rests werden mit dem typgerechten Initialwert, Alignment-Lücken mit NullBytes gefüllt. Da längere Strukturen bisher generell mit Leerzeichen aufgefüllt
wurden, ist die Verwendung von Initialwerten bei nicht zeichenartigen
Komponententypen inkompatibel. Diese inkompatible Änderung hat allerdings
eher den Charakter einer Fehlerkorrektur. Bei zeichenartigen Komponenten
wurde aus Gründen der Kompatibilität darauf verzichtet, mit Initialwerten
aufzufüllen.
BEGIN OF struc1,
a(1) TYPE C,
x(1) TYPE X,
END OF struc1.
BEGIN OF struc2,
a(1) TYPE C,
b(1) TYPE C,
END OF struc2.
12
Die Zuweisung struc1 = struc2 ist unter Unicode nicht erlaubt, weil struc1-x im
Gegensatz zu struc2-b nur ein Byte belegt.
BEGIN OF struc3,
a(2) TYPE C,
n(6) TYPE N,
i
TYPE I,
END OF struc3.
BEGIN OF struc4,
a(8) TYPE C,
i
TYPE I,
f
TYPE F,
END OF struc4.
Diese Zuweisung struc3 = struc4 ist zulässig, weil die Fragmentsichten der
zeichenartigen Felder und der Integerzahl übereinstimmen.
BEGIN OF struc5,
a(1) TYPE X,
b(1) TYPE X,
c(1) TYPE C,
END OF struc5.
BEGIN OF struc6,
a(1) TYPE X,
BEGIN OF struc0,
b(1) TYPE X,
c(1) TYPE C,
END OF struc0,
END OF struc6.
struc5 = struc6 ist wiederum verboten, weil die Fragmentsichten der beiden
Strukturen durch die Alignment-Lücken vor struc0 und vor struc0-c abweichen.
BEGIN OF struc7,
p(8) TYPE P,
c(1) TYPE C,
END OF struc7.
BEGIN OF struc8,
p(8) TYPE P,
c(5) TYPE C,
o(8) TYPE P,
END OF struc8.
Die Zuweisung struc7 = struc8 funktioniert, weil die Fragmentsichten in der
Länge der Struktur struc7 übereinstimmen.
Bei tiefen Strukturen wird wie bisher die Typkompatibilität der Operanden
gefordert. Als Abrundungsmaßnahme wurde die Konvertibilität bei ObjektReferenzen und Tabellenkomponenten leicht verallgemeinert.
·
Konvertierung zwischen Strukturen und Einzelfeldern
Für die Konvertierung einer Struktur in ein Einzelfeld und umgekehrt gelten
folgende Regeln:
1. Ist eine Struktur rein zeichenartig, dann wird sie bei der Konvertierung wie
ein C-Feld behandelt.
2. Ist das Einzelfeld vom Typ C, die Struktur aber nur zum Teil zeichenartig,
dann ist die Konvertierung nur erlaubt, wenn die Struktur mit einer
zeichenartigen Gruppe beginnt und diese Gruppe mindestens so lang wie das
Einzelfeld ist. Die Konvertierung erfolgt nun zwischen der ersten
zeichenartigen Gruppe der Struktur und dem Einzelfeld. Wenn die Struktur
das Zielfeld ist, werden die zeichenartigen Anteile des Rests mit Leerzeichen
und alle anderen Komponenten mit dem typgerechten Initialwert aufgefüllt.
3. Die Konvertierung ist verboten, wenn die Struktur nicht rein zeichenartig
und das Einzelfeld nicht vom Typ C ist.
Analog zur Zuweisung zwischen Strukturen ist das Auffüllen nicht zeichenartiger
Komponenten mit dem Initialwert inkompatibel.
13
·
Konvertierung zwischen internen Tabellen
Tabellen sind dann konvertierbar, wenn ihre Zeilentypen konvertierbar sind. Die
oben beschriebenen Restriktionen wirken sich somit auch auf die Konvertierung
von Tabellen aus.
·
Implizite Konvertierungen
Für alle ABAP-Anweisungen, die implizite Konvertierungen entsprechend der
MOVE-Semantik verwenden, gelten ebenfalls die obigen Regeln. Dies ist zum
Beispiel bei folgenden Anweisungen für interne Tabellen der Fall:
APPEND wa TO itab.
APPEND LINES OF itab1 TO itab2.
INSERT wa INTO itab.
INSERT LINES OF itab1 INTO [TABLE] itab2.
MODIFY itab FROM wa.
MODIFY itab ... TRANSPORTING ... WHERE ... ki = vi ...
READ TABLE itab ...INTO wa.
READ TABLE itab ...WITH KEY ...ki = vi ...
LOOP AT itab INTO wa.
LOOP AT itab .... WITH KEY ... ki = vi ...
Die selben Einschränkungen wie bei der expliziten Konvertierung gelten auch für
die implizite Umwandlung von VALUE-Angaben.
4.4 Vergleiche
Prinzipiell gilt die Regel, daß Operanden, die einander mit der MOVE-Anweisung
zugewiesen werden können, auch miteinander vergleichbar sind. Abweichend
davon sind Objektreferenzen zwar vergleichbar, jedoch nicht immer zuweisbar.
·
Vergleiche zwischen flachen Strukturen
Ein Vergleich ist auch dann möglich, wenn die Strukturen nicht kompatibel sind.
Es muß aber analog zu MOVE gelten, daß die Fragmentsichten in der Länge der
kürzeren Struktur übereinstimmen. Sind die Strukturen verschieden lang, dann
wird die kürzere Struktur bis zur Länge der anderen Struktur aufgefüllt. Analog
wie bei der Zuweisung werden beim Auffüllen alle zeichenartigen Komponenten
mit Leerzeichen und alle anderen Komponenten mit typgerechtem Initialwert
gefüllt. Der Vergleich erfolgt fragmentweise entsprechend der Fragmentsicht.
·
Vergleiche zwischen Einzelfeldern und Strukturen
Bei Vergleichen zwischen Einzelfeldern und Strukturen gelten folgende Regeln:
1. Wenn eine Struktur rein zeichenartig ist, wird sie beim Vergleich wie ein CFeld behandelt.
2. Ist das Einzelfeld vom Typ C, die Struktur aber nur zum Teil zeichenartig,
dann ist der Vergleich nur erlaubt, wenn die erste zeichenartige Gruppe der
Struktur länger als das Einzelfeld ist. Für den Vergleich wird das Einzelfeld
zur Laufzeit auf die Länge der Struktur erweitert und mit Initialwerten
14
aufgefüllt. Der Vergleich erfolgt dann wie bei strukturierten Feldern, wobei
das Auffüllen selbst analog der MOVE-Anweisung vorgenommen wird.
c0(10)
TYPE C.
c0
BEGIN OF struc,
c1(15) TYPE C,
i
TYPE I,
c2(5) TYPE C,
n(7)
TYPE N,
END OF struc.
c1
0
i
c2
n
In diesem Beispiel wird c0 im Speicher auf die Länge von struc erweitert.
Alle Bereiche > 10 werden bei nicht zeichenartigen Komponenten mit
typgerechten Initialwerten belegt, ansonsten mit Leerzeichen.
·
Vergleich zwischen tiefen Strukturen
Wie bisher wird bei tiefen Strukturen für den Vergleich im wesentlichen die
Typkompatibilität der Operanden gefordert. Der Kompatibilitätstest für die
Vergleichbarkeit wurde zur Abrundung dahingehend verallgemeinert, daß analog
zu Einzelfeldern Strukturkomponenten mit Referenzen auf Klassen oder
Interfaces unabhängig von Klassenhierarchie und Implementierungsrelation
miteinander vergleichbar sind. Bei Tabellenkomponenten wird nur die
Vergleichbarkeit der Tabellentypen gefordert.
·
Vergleich zwischen internen Tabellen
Tabellen sind dann vergleichbar, wenn ihre Zeilentypen vergleichbar sind. Die
oben beschriebenen Restriktionen wirken sich somit auch auf den Vergleich von
Tabellen aus.
4.5 Verarbeitung von Zeichenketten
Die Zeichenkettenverarbeitung, bei der bisher alle Argumente implizit als Feld vom
Typ C interpretiert wurden, wird aufgeteilt in Stringverarbeitung für zeichenartige
und byteartige Argumente.
·
Anweisungen zur Zeichenkettenverarbeitung
CLEAR ... WITH
CONCATENATE
CONDENSE
CONVERT TEXT ... INTO SORTABLE CODE
OVERLAY
REPLACE
SEARCH
SHIFT
SPLIT
TRANSLATE ... TO UPPER/LOWER CASE
TRANSLATE ... USING
Bei diesen Anweisungen müssen die Argumente Einzelfelder der Typen C, N, D,
T oder STRING sein, zudem sind rein zeichenartige Strukturen erlaubt. Werden
15
Argumente eines anderen Typs übergeben, so wird ein Syntax- oder
Laufzeitfehler ausgelöst. Für die Verarbeitung von Bytefolgen, also Operanden
des Typs X oder X-STRING, wird eine Teilmenge dieser Funktionalität durch den
Zusatz IN BYTE MODE bereitgestellt. Eine Anweisung CONCATENATE a x b
INTO c ist genau dann nicht mehr möglich, wenn a, b, c zeichenartig sind, x
jedoch vom Typ X.
TRANSLATE ... CODEPAGE ...
TRANSLATE ... NUMBER FORMAT ...
Diese Anweisungen sind in UP verboten. Als Ersatz werden die neuen
Konvertierungsklassen angeboten, die auf Seite 37 näher beschrieben sind.
·
Vergleichsoperatoren für die Zeichenkettenverarbeitung
CO
CN
CA
NA
CS
NS
CP
NP
Wie bei den Anweisungen zur Stringverarbeitung erfordern diese Operatoren
Einzelfelder der Typen C, N, D, T oder STRING als Argumente, außerdem sind
wiederum rein zeichenartige Strukturen zugelassen. Für Bytefolgen werden
eigene Vergleichsoperatoren angeboten, die durch das Präfix BYTE- definiert
werden.
·
Funktionen zur Stringverarbeitung
Die Funktion STRLEN arbeitet nur mit zeichenartigen Feldern und liefert die
Länge in Zeichen zurück. Für die Länge von Bytefolgen steht die neue Funktion
XSTRLEN zur Verfügung.
Die Funktion CHARLEN lieferte unter NUS bisher den Wert 1 für ein Textfeld,
das mit einem Single-Byte-Zeichen beginnt. Für ein Textfeld, das mit einem
Double-Byte-Zeichen beginnt, wird der Wert 2 zurückgeliefert. Unter US wird
CHARLEN den Wert 1 liefern, falls text mit einem einfachen Unicode-Zeichen
beginnt. Falls text mit einem Unicode-Doppelzeichen aus der Surrogate Area
beginnt, wird 2 zurückgeliefert.
Die Funktion NUMOFCHAR liefert die Anzahl der Zeichen eines Strings oder
eines zeichenartigen Feldes. In Single-Byte Codepages verhält sich diese
Funktion wie STRLEN. In Multi-Byte Codepages werden Zeichen, die mehr als 1
Byte belegen, trotzdem mit der Länge 1 gezählt.
·
Ausgaben in Felder und Listen
Bei WRITE ... TO waren beliebige flache Datentypen als Ziel erlaubt, die wie CFelder behandelt wurden. In UP gilt nun für WRITE ... TO ... die Einschränkung,
daß das Zielfeld zeichenartig sein muß. Bei der Tabellenvariante WRITE ... TO
16
itab INDEX idx muß der Zeilentyp der Tabelle zeichenartig sein. Offset und
Längenangaben werden dabei zeichenweise gezählt.
Mit WRITE konnten bisher beliebige flache Strukturen ausgegeben werden.
Wenn das Quellfeld bei WRITE eine flache Struktur Ist, dann muß diese in UP
rein zeichenartig sein. Folgende Anweisungen sind davon betroffen:
WRITE
WRITE
WRITE
WRITE
WRITE
f.
f TO g[+off][(len)].
(name) TO g.
f TO itab[+off][(len)] INDEX idx.
(name) TO itab[+off][(len)] INDEX idx.
4.6 Typprüfung und Typkompatibilität
Aus historischen Gründen können Feldsymbole und Parameter von
Unterprogrammen oder Funktionsbausteinen mit dem Zusatz STRUCTURE typisiert
werden.
·
Wenn Feldsymbole mit FIELD-SYMBOLS <f> STRUCTURE s DEFAULT wa
typisiert sind und ihnen später mit ASSIGN wa TO <f> ... ein Datenobjekt wa
zugewiesen wird, dann wird in NUP in beiden Anweisungen nur geprüft, ob wa
mindestens so lang wie s ist und wa die Ausrichtungsanforderungen von s zur
Laufzeit erfüllt.
Wenn Parameter in Funktionsbausteinen oder Unterprogrammen mit FORM
form1 USING/CHANGING arg STRUCTURE s ... oder FORM form2 TABLES
itab_a STRUCTURE s ... typisiert sind und ihnen mit PERFORM form1
USING/CHANGING wa oder PERFORM form2 USING/CHANGING itab_b
Aktualparameter übergeben werden, wird in NUP ebenfalls nur geprüft, ob wa
oder der Zeilentyp von itab_b mindestens so lang wie s ist und wa
beziehungsweise der Zeilentyp von itab_b die Ausrichtungsanforderungen von s
erfüllt. Das Gleiche gilt für Parameter von Funktionsbausteinen, die mit
STRUCTURE typisiert sind.
In UP werden nach einer Typisierung mit STRUCTURE bei einer Zuweisung von
Datenobjekten, also beim DEFAULT-Zusatz der Anweisung FIELD-SYMBOLS, beim
ASSIGN und bei der Übergabe von Aktualparametern folgende zusätzliche Regeln
überprüft:
1. Ist wa beziehungsweise der Zeilentyp von itab_b eine flache oder tiefe
Struktur, dann müssen die Unicode-Fragmentsichten von wa beziehungsweise
von itab_b und s in der Länge von s übereinstimmen.
2. Ist wa ein Einzelfeld, dann sind nur die zeichenartigen Typen C, N, D oder T
erlaubt und die Struktur s muß rein zeichenartig sein.
Die Überprüfung dieser beiden Regeln erfordert zusätzliche Laufzeit. Deshalb
wird empfohlen, die Parameter nach Möglichkeit mit TYPE zu typisieren, weil
der Test auf echte Kompatibilität ungleich schneller ist.
17
·
Wurde bei einem Funktionsbaustein ein Argument mit ... LIKE struc typisiert,
wobei struc eine flache Struktur ist, so wird in NUP bei der Parameterübergabe
nur geprüft, ob das Argument eine flache Struktur gleicher Länge ist. In UP wird
zusätzlich geprüft, daß die Fragmentsichten des aktuellen und formalen
Parameters übereinstimmen. Aus Performancegründen wird wie im Abschnitt
zuvor die Typisierung mit TYPE empfohlen.
· Außerdem sind zwei Strukturen, von denen eine oder beide Includes enthalten,
nur noch dann kompatibel, wenn die durch Include verursachten AlignmentLücken auf allen Plattformen übereinstimmen. Im folgenden Beispiel sind struc1
und struc2 nicht zueinander kompatibel, weil vor dem INCLUDE im US eine
zusätzliche Alignment-Lücke auftritt:
BEGIN OF struc1,
a(1) TYPE X,
b(1) TYPE X,
c(1) TYPE C,
END OF struc1.
BEGIN OF struc2,
a(1) TYPE X.
INCUDE struc3.
END OF struc2.
BEGIN OF struc3,
b(1) TYPE X,
c(1) TYPE C,
END OF struc3.
Da sich die Typkompatibilität in UP und NUP unterscheiden kann, gelten in NUS
für die Prüfung der Parameter stets die Typkompatibilitätsregeln des Aufrufers.
Ruft also ein NUP ein UP auf, dann wird die Typkompatibilität wie im NUP
bestimmt. Umgekehrt wird die Unicode-Prüfung eingeschaltet, wenn ein UP ein
NUP aufruft.
4.7 Änderungen bei Datenbank-Operationen
Bei den nachfolgenden Anweisungen werden bisher in NUP die Daten entsprechend
der Struktur des Tabellenarbeitsbereichs dbtab in das Feld wa beziehungsweise in
die Tabellenzeile itab übertragen, ohne die Struktur derselben zu berücksichtigen.
Allein die Länge und die Ausrichtung werden geprüft.
SELECT * FROM dbtab ... INTO wa ...
SELECT * FROM dbtab ... INTO TABLE itab ...
SELECT * FROM dbtab ... APPENDING TABLE itab ...
FETCH NEXT CURSOR c ... INTO wa.
FETCH NEXT CURSOR c ... INTO TABLE itab.
FETCH NEXT CURSOR c ... APPENDING TABLE itab.
INSERT INTO dbtab ... FROM wa.
INSERT dbtab ... FROM wa.
INSERT dbtab ... FROM TABLE itab.
UPDATE dbtab ... FROM wa.
UPDATE dbtab ... FROM TABLE itab.
MODIFY dbtab ... FROM wa.
MODIFY dbtab ... FROM TABLE itab.
DELETE dbtab FROM wa.
DELETE dbtab FROM TABLE itab.
In UP gelten nun folgende Regelungen:
Ist der Arbeitsbereich beziehungsweise die Zeile der internen Tabelle eine Struktur,
dann wird zusätzlich geprüft, ob die Fragmentsichten von Arbeitsbereich und
18
Datenbanktabelle in der Länge der Datenbanktabelle übereinstimmen. Ist der
Arbeitsbereich ein Einzelfeld, so muß das Feld zeichenartig und die
Datenbanktabelle rein zeichenartig sein. Diese Anforderungen gelten für alle oben
aufgeführten Anweisungen.
Bei allen Anweisungen zum Bearbeiten von Datenbanktabellen (READ, MODIFY,
DELETE, LOOP), die den Zusatz VERSION verwenden, sind für das Versionsfeld nur
noch die Typen C, N, D, T und flache Strukturen derselben Typen zulässig. In NUS
wird eine Warnung, in US ein Syntaxfehler ausgelöst.
4.8 Längen- und Abstandsermittlung
Bei der Längen und Abstandsermittlung von Feldern darf die Anweisung DESCRIBE
DISTANCE nicht mehr verwendet werden und muß durch eine der neuen
Anweisungen DESCRIBE DISTANCE ... IN BYTE MODE
oder DESCRIBE
DISTANCE ... IN CHARACTERMODE ersetzt werden.
Auch die Anweisung DESCRIBE FIELD ... LENGTH ist obsolet und muß durch eine
der neuen Anweisungen DESCRIBE FIELD ... LENGTH ... IN BYTE MODE oder
DESCRIBE FIELD ... LENGTH ... IN CHARACTER MODE ersetzt werden.
Die Anweisung DESCRIBE FIELD ... TYPE feld lieferte bisher für flache
Strukturen den Typ C zurück. In Unicode-Programmen wird für flache Strukturen
jetzt der Typ u zurückgegeben, der im ABAP-Quellcode abgefragt werden kann.
Für die Anweisung DESCRIBE FIELD ... TYPE ... COMPONENTS ... ergeben sich
unter Unicode-Systemen keine Änderungen. Ebenfalls unverändert liefert die
Anweisung DESCRIBE ... OUTPUT LENGTH ... weiterhin die Ausgabelänge in
Zeichen zurück.
4.9 Sonstige Änderungen
Die folgenden Ausführungen betreffen die Dateischnittstelle, Schlüsselangaben bei
Tabellen sowie Bit- und Bitmaskenoperationen. Im einzelnen ergeben sich durch die
Einführung von Unicode folgende Änderungen:
·
In der Dateischnittstelle wurde der Befehl OPEN DATASET völlig überarbeitet.
In UP muß mindestens einer der Zusätze IN TEXT MODE ENCODING, IN
BINARY MODE, IN LEGACY MODE oder IN LEGACY BINARY MODE angegeben
werden.
Das Lesen und Schreiben von Dateien mittels READ DATASET und TRANSFER
kann in US nur noch vorgenommen werden, wenn die zu bearbeitende Datei
zuvor explizit geöffnet wurde. Ohne OPEN-Anweisung wird bei diesen
Anweisungen ein Laufzeitfehler ausgelöst.
Wurde die Datei im TEXT MODE geöffnet, sind bei READ DATASET dsn INTO f
für f nur zeichenartige Felder, Strings und rein zeichenartige Strukturen erlaubt,
wobei die Typprüfung erst zur Laufzeit erfolgt.
Der Zusatz LENGTH bestimmt im TEXT MODE die Länge des Datensatzes in
Zeichen, in allen anderen Fällen in Bytes.
19
·
Bei den obsoleten Anweisungen LOOP AT dbtab, READ TABLE dbtab und
READ TABLE itab wird in UP ein Syntaxfehler ausgelöst, wenn der Schlüssel
nicht rein zeichenartig ist.
Bei der Anweisung READ TABLE itab wird ein Syntax- oder Laufzeitfehler
ausgelöst, wenn der Standardschlüssel der internen Tabelle die Typen X oder
XSTRING enthält. Bei dieser READ-Variante wird der tatsächlich zu verwendende
Schlüssel durch Ausblenden aller mit Leerzeichen gefüllten Komponenten
ermittelt. Dazu muß in UP sichergestellt sein, daß der Vergleich mit SPACE
erlaubt ist.
Ein Syntax- oder Laufzeitfehler wird auch bei Datenbankzugriffen mit
generischem Schlüssel ausgelöst, wenn der Schlüssel nicht rein zeichenartig ist.
Davon betroffen sind folgende Befehle:
READ TABLE dbtab ...SEARCH GKEQ ...
READ TABLE dbtab ...SEARCH GKGE ...
LOOP AT dbtab ...
REFRESH itab FROM TABLE dbtab.
Bei diesen Anweisungen wird der tatsächliche Tabellenschlüssel dadurch
ermittelt, daß schließende Leerzeichen des Datenbankschlüssel abgeschnitten
werden. Dazu muß in UP sichergestellt sein, daß alle Bestandteile des Schlüssels
mit SPACE verglichen werden können.
·
Bisher wurde bei den Bitanweisungen SET BIT i OF f [TO g] und GET
BIT i OF f [INTO g] geprüft, ob das Feld f zeichenartig ist, wobei
üblicherweise auch X-Felder, X-Strings und flache Strukturen als zeichenartig
betrachtet wurden. Für UP ist dies nicht mehr sinnvoll, da einerseits die Typen
X und XSTRING nicht mehr als zeichenartig gelten, anderseits der bitweise
Zugriff auf zeichenartige Felder oder Strukturen nicht mehr unabhängig von der
Plattform ist. Deshalb muß bei diesen Operationen in UP das Feld f vom Typ X
oder XSTRING sein.
Bei den Bitmaskenoperationen f O x, f Z x und f M x waren bisher für
den linken Operanden f alle zahlartigen und damit auch alle characterartigen
Typen erlaubt. In UP muß der Operand f nun den Typ X oder XSTRING haben.
·
Bei der Addition von Feldfolgen sind in UP Einschränkungen für folgende
Anweisungen verbindlich:
ADD n1 THEN n2 UNTIL nz [ ACCORDING TO sel ] GIVING m ...
ADD n1 THEN n2 UNTIL nz TO m [ RANGE str ].
1. Die Operanden n1, n2 und nz müssen zueinander typkompatibel sein.
2. Die Distanz zwischen nz und n1 muß ein ganzzahliges Vielfaches der Distanz
zwischen n2 und n1 sein.
3. Ein Syntax- oder Laufzeitfehler erfolgt, wenn die Felder n1, n2 und nz nicht
in einer Struktur liegen. Diese muß entweder statisch erkennbar sein oder
deren zulässiger Bereich explizit durch den RANGE-Zusatz gekennzeichnet
werden.
4. Zur Laufzeit wird sichergestellt, daß der RANGE-Bereich nicht verlassen
wird.
20
ADD n1 FROM i1 GIVING m [ RANGE str ].
1. Feld n1 muß innerhalb einer Struktur liegen. Diese muß durch den RANGEZusatz explizit definiert werden, falls dies statisch nicht erkennbar ist.
2. Auch bei dieser Variante wird zur Laufzeit geprüft, ob n1 und die
angesprochenen Werte innerhalb der Struktur liegen.
·
Schleifen mit dem Zusatz VARY oder VARYING sind auch für Unicode
problematisch, weil einerseits ein typgerechter Zugriff auf Speicherinhalte nicht
sichergestellt ist, andererseits Seicher ungewollt überschrieben werden kann.
DO ... VARYING f FROM f1 NEXT f2.
Bei dieser Anweisung müssen die Felder f, f1 und f2 zueinander typkompatibel
sein. Um das Überschreiben von Speicherinhalten zu verhindern, wird bei den
folgenden Anweisungen implizit oder explizit ein RANGE für zulässige Zugriffe
eingeführt:
DO ... TIMES VARYING f FROM f1 NEXT f2 [ RANGE f3 ].
WHILE ... VARY f FROM f1 NEXT f2
[ RANGE f3 ].
Es wird wiederum ein Syntax- oder Laufzeitfehler ausgelöst, falls f1 oder f2
nicht von f3 umfaßt werden. Fehlt der Zusatz RANGE, dann wird dieser aus
FROM f1 NEXT f2 implizit so bestmmt:
1. Sind sowohl f1 und f2 statisch erkennbare Komponenten der gleichen
Struktur, dann wird der zulässige RANGE-Bereich aus der kleinsten Struktur
bestimmt, die f1 und f2 umfaßt.
2. Ein Syntaxfehler wird ausgelöst, wenn statisch erkennbar ist, daß f1 und f2
nicht zur gleichen Struktur gehören.
3. Ein zulässiger Bereich muß explizit mittels RANGE angegeben werden, falls
die Zusammengehörigkeit von f1 und f2 statisch nicht erkennbar ist.
Wird als RANGE-Zusatz eine tiefe Struktur angegeben, dann wird bei jedem
Schleifendurchlauf geprüft, daß innerhalb des gerade überstrichenen Bereiches
keine Feld- und Objektreferenzen, Tabellen oder Strings liegen.
·
Bei der automatischen Erzeugung von Unterprogrammen mittels Anweisung
GENERATE SUBROUTINE POOL itab NAME name erbt das generierte Programm
den Inhalt des Unicode-Flags des generierenden Programms.
·
Bei der Anweisung INSERT REPORT kann das Unicodeflag durch den Zusatz
UNICODE ENABLING uc explizit zur Laufzeit gesetzt werden. Ohne diesen
Zusatz wird folgendermaßen verfahren:
1.
2.
3.
4.
Ein UC-Programm erzeugt ebenfalls ein UC-Programm
Ein NUC-Programm erzeugt wiederum ein NUC-Programm
Ein NUC- wird ein UC-Programm nach Überschreiben durch ein UC-Programm
Ein UC- bleibt ein UC-Programm nach Überschreiben durch ein NUCProgramm
21
·
Bei den Anweisungen GET/SET PARAMETER ID pid FIELD f muß f
zeichenartig sein. Für die Ablage nicht zeichenartiger Felder und Strukturen
können EXPORT- und IMPORT-Anweisungen benutzt werden
5. Neue ABAP-Anweisungen für Unicode
5.1 Stringverarbeitung für Bytefolgen
·
Die String-Anweisungen für die Typen X und XSTRINGG werden durch den Zusatz
IN BYTE MODE von den Zeichenkettenbefehlen unterschieden. Für die Varianten
der Zeichenketten ist optional der Zusatz IN CHARACTER MODE möglich.
Ist der Zusatz IN BYTE MODE angegeben, sind als Argumente nur X-Felder und XStrings erlaubt. Werden Argumente eines anderen Typs übergeben, so wird ein
Syntax- oder ein Laufzeitfehler ausgelöst.
CLEAR ... WITH
IN BYTE MODE
CONCATENATE x1 ... xn INTO x IN BYTE MODE
FIND ...
IN BYTE MODE
REPLACE ...
IN BYTE MODE
REPLACE f WITH g INTO h
IN BYTE MODE
SEARCH x FOR x1
IN BYTE MODE
SHIFT x ...
IN BYTE MODE
SPLIT ...
IN BYTE MODE
Bei allen String-Befehlen für Bytefolgen werden X-Felder immer in ihrer vollen
Länge berücksichtigt, so daß Bytes mit Inhalt X'00' am Ende des Feldes niemals
abgeschnitten werden. Für die Anweisungen FIND, SEARCH und REPLACE mit
Zusatz IN BYTE MODE gibt es keine Varianten, die Suchmuster verwenden.
·
Die Stringlänge für Bytefolgen kann mit der Funktion XSTRLEN bestimmt
werden. XSTRLEN liefert für X-Strings die aktuelle Länge und für X-Felder die
definierte Länge in Bytes, wobei Nullbytes am Ende von Feldern mitgezählt
werden.
·
Die X-Varianten der Stringvergleichsoperationen werden durch das Präfix
BYTE- von den Zeichenkettenvarianten unterschieden. Als Argumente sind für
diese Operationen nur X-Felder und Felder vom Typ XSTRING erlaubt.
BYTE-CO
BYTE-CN
BYTE-CA
BYTE-NA
BYTE-CS
BYTE-NS
22
5.2 Längen- und Abstandsermittlung
Mit den Anweisungen DESCRIBE FIELD und DESCRIBE DISTANCE kann die
Feldlänge oder der Abstand zwischen zwei Feldern ermittelt werden. Bei
folgenden Varianten müssen unter Unicode die Zusätze IN BYTE/CHARACTER
MODE angegeben werden:
·
DESCRIBE FIELD f LENGTH len IN BYTE MODE.
Die Länge des Feldes f wird in Bytes ermittelt und in das Feld len übergeben.
Diese Variante liefert für alle intern referenzierten Datentypen (Strings, Feldund Objektreferenzen) die Länge der Referenz und nicht die Länge des Inhalts.
Für derartige Felder ist deshalb nur die Variante IN BYTE MODE erlaubt.
· DESCRIBE FIELD f LENGTH len IN CHARACTER MODE.
Hier wird die Länge des Feldes f in Zeichen zurückgegeben, falls das Argument
rein zeichenartig ist. f darf jedoch nicht vom Typ STRING sein. Die betreffende
Prüfung wird statisch und dynamisch durchgeführt und löst je nach Typ einen
Syntax- oder Laufzeitfehler aus.
·
·
DESCRIBE DISTANCE BETWEEN a AND b INTO x IN BYTE MODE.
Diese Anweisung liefert im Feld x den Abstand zwischen den Feldern a und b in
Bytes.
DESCRIBE DISTANCE BETWEEN a AND b INTO x IN CHARACTER MODE.
Diese Anweisung liefert den Abstand in Zeichen zurück, wobei das Ergebnis
stets auf die Feldanfänge bezogen ist. Nur zur Laufzeit wird geprüft, ob der
Abstand zwischen den Argumenten durch die plattformabhängige Länge eines
Zeichens teilbar ist und die beiden Felder a und b das richtige Alignment
besitzen. Anderenfalls wird ein Laufzeitfehler ausgelöst.
5.3 Zuweisungen an Feldsymbole
Die ASSIGN-Anweisung erlaubte es bisher, mit Offset/Längenangaben über
Feldgrenzen hinaus zu adressieren. Einen Laufzeitfehler gab es nur dann, wenn
über die Grenzen des Datensegments hinaus adressiert wurde. Feldübergreifende
Offset/Längenzugriffe bei ASSIGN konnten beispielsweise sinnvoll zur Bearbeitung
von Wiederholungsgruppen eingesetzt werden.
Mit Unicode ist dies allerdings problematisch, da nicht mehr sichergestellt ist, daß
feldüberschreitende Offset- oder Längenangaben sowohl unter US als auch in NUS
einheitlich und sinnvoll als Bytes oder Zeichen interpretiert werden können. Aus
diesem Grund wurde die ASSIGN-Anweisung um die Zusätze RANGE und INCREMENT
erweitert, während der Zusatz CASTING nunmehr alle Varianten dieser Anweisung
unterstützt. Der RANGE-Zusatz wird für alle gültigen Varianten von ASSIGN
angeboten und kann mit dem Zusatz CASTING kombiniert werden.
23
·
ASSIGN feld1
TO <fs> RANGE feld2.
Dieser Zusatz setzt explizit die Range-Grenzen. Dadurch ist es möglich, über
Feldgrenzen hinaus zu adressieren, um beispielsweise mit der Anweisung ASSIGN
INCREMENT Wiederholungsgruppen zu verarbeiten.
1. Als Range für <fs> werden die Feldgrenzen von feld2 genommen.
2. In UP müssen die durch die RANGE-Angabe spezifizierten Grenzen die RangeGrenzen umfassen, die sich sonst nach den oben beschriebenen Regeln
ergeben würden.
3. Ist der Speicherbereich von feld1 nicht ganz in feld2 enthalten, so wird ein
abfangbarer Laufzeitfehler ausgelöst.
4. Das Feld feld2, das den Range bestimmt, darf auch tief sein. Es können
somit auch Wiederholungsgruppen mit tiefen Typen verarbeitet werden.
·
ASSIGN feld INCREMENT n TO <fs>.
Das Feldsymbol wird ausgehend von der durch feld bestimmten Position um n
mal die Länge von feld weitergesetzt.
Zunächst wird aus der Länge von feld und der INCREMENT-Angabe der Bereich
für den Zugriff entsprechend ASSIGN fld+n*sizeof[feld] (sizeof[fld]) TO <fs>
bestimmt. Der angesprochene Bereich muß innerhalb der Range-Grenzen
liegen. Kann die Zuweisung nicht durchgeführt werden, weil die Range-Grenzen
verletzt wurden, so wird SY-SUBRC > 0 gesetzt und das Feldsymbol bleibt
unverändert.
Die Range-Grenzen für ASSIGN feld INCREMENT n TO <fs> werden genau so wie
bei ASSGIN feld TO <f> bestimmt. Die INCREMENT-Angabe hat daher keinen
Einfluß auf die Bestimmung der Range-Grenzen.
* Schleife über ein elementares Feld
DATA: c(10) TYPE C VALUE 'abcdefghij'.
FIELD-SYMBOLS: <cf> TYPE C.
ASSIGN c(2) TO <cf>.
"Range-Grenzen c =
DO 5 TIMES.
"Feldgrenzen von cf
WRITE / <cf>.
ASSIGN <cf> INCREMENT 1 TO <c>. "Gleiche Grenzen <c>
*
ASSIGN <c>+2 TO <cf>.
"Wie ASSIGN INCREMENT
ENDDO.
* Strukturierte Wiederholungsgruppe
TYPES: BEGIN OF comp,
f1 type string,
...
END OF comp.
DATA: BEGIN OF stru,
x1(1) TYPE x,
k1
TYPE comp,
k2
TYPE comp,
24
k3
TYPE comp,
k4
TYPE comp,
END OF stru.
FIELD-SYMBOLS: <comp> TYPE comp.
ASSIGN stru-k1 TO <comp> RANGE stru.
* Range-Grenzen feldübergreifend festlegen
DO 4 TIMES.
...
ASSIGN <comp> INCREMENT 1 TO <comp>.
ENDDO.
* Dynamischer Zugriff auf ein
* Element einer Wiederholungsgruppe
DATA: BEGIN OF stru,
x1(1) TYPE x,
k1
TYPE comp,
k2
TYPE comp,
k3
TYPE comp,
k4
TYPE comp,
END OF stru,
incr
TYPE i.
FIELD-SYMBOLS: <comp> TYPE comp.
incr = 4 - 1.
ASSIGN stru-k1 INCREMENT incr TO <comp> RANGE stru.
...
* <comp> steht jetzt auf stru-k4
·
Bei allen Varianten der Anweisung ASSIGN ist der Zusatz CASTING erlaubt:
ASSIGN
ASSIGN
ASSIGN
ASSIGN
ASSIGN
feld
feld
feld
feld
feld
TO
TO
TO
TO
TO
<fs>
<fs>
<fs>
<fs>
<fs>
CASTING.
CASTING TYPE type.
CASTING TYPE (typename)
CASTING LIKE fld.
CASTING DECIMALS dec.
Durch ASSIGN ... CASTING ist es möglich, den Inhalt eines Felds über ein
Feldsymbol als einen Wert eines anderen Typs zu betrachten. Eine Anwendung
dieser Anweisung besteht beispielsweise darin, durch Casts auf verschiedene
Typen unterschiedliche Sichten auf eine Struktur zur Verfügung zu stellen.
Eine verbreitete ABAP-Technik besteht darin, C-Felder oder Strukturen als
Container zum Speichern von Strukturen verschiedener, oft erst zur Laufzeit
bekannter Typen zu verwenden. Die Selektion von Teilkomponenten der Struktur
erfolgt dann durch Offset/Längenzugriffe auf den Container. Da diese Technik
mit Unicode nicht mehr funktioniert, kann alternativ ein vorhandener
Speicherbereich mittels ASSIGN ... CASTING über ein Feldsymbol als Container
mit passender Typisierung betrachtet werden. Im nachfolgenden Beispiel wird
ein bestimmtes Feld der Datenbanktabelle X031L gelesen, wobei Feld- und
Tabellenname erst zur Laufzeit angegeben werden.
25
* Lesen eines Feldes der Tabelle X031L
PARAMETERS:
TAB_NAME
LIKE
TAB_COMP
LIKE
ANZAHL
TYPE
DATA:
BEGIN OF BUFFER,
ALIGNMENT TYPE
C(8000)
TYPE
END OF BUFFER.
SY-TNAME,
X031L-FIELDNAME,
I DEFAULT 10.
"Tabellenname
"Feldname
"Zeilenanzahl
F,
C,
"Alignment
"Tabelleninhalt
FIELD-SYMBOLS: <WA>
TYPE ANY,
<COMP> TYPE ANY.
* Feldsymbol mit passender Typisierung
* auf Pufferbereich setzen
ASSIGN BUFFER TO <WA> CASTING TYPE (TAB_NAME).
SELECT * FROM (TAB_NAME) INTO <WA>
UP TO anzahl ROWS.
ASSIGN COMPONENT TAB_COMP OF STRUCTURE <WA> TO <COMP>.
WRITE: / TAB_COMP, <COMP>.
ENDSELECT.
In der Anweisung ASSIGN feld TO <f> CASTING ... wurde bisher geprüft,
daß feld mindestens so lang ist wie der Typ, der dem Feldsymbol <f> zugeordnet
ist, indem das Feldsymbol typisiert wurde oder durch eine direkte Typangabe
mittels CASTING TYPE. Die bisher schon durchgeführte Längenprüfung wird im
Syntaxcheck dahingehend verschärft, daß die Zuweisung nur noch erlaubt ist,
wenn das Feld feld sowohl in einem US als auch in einem NUS mindestens so lang
ist wie der Typ, der dem Feldsymbol <f> zugeordnet ist. Ist diese Bedingung
verletzt, erfolgt ein Syntaxfehler. Zur Laufzeit wird dagegen wie bisher nur
geprüft, ob die Längen im aktuellen System passen.
Ist der Typ von feld oder von <f> eine tiefe Struktur, dann wurde außerdem
geprüft, ob alle referenzartigen Komponenten bezüglich Offset und Typ im
Bereich von feld, der durch <f> überdeckt wird, übereinstimmen. Die Prüfung
der referenzartigen Komponenten wird im Syntaxcheck dahingehend verschärft,
daß diese auf allen Plattformen mit ein, zwei oder vier Byte langen Zeichen
passen müssen. Zur Laufzeit wird wiederum nur geprüft, ob die
Referenzkomponenten im aktuellen System passen.
Bei ASSIGN str TO <f> TYPE C/N und bei ASSIGN str TO <f> CASTING
TYPE C/N kann in Unicode-Systemen außerdem der Fall auftreten, daß die Länge
von str nicht ein Vielfaches der Zeichenlänge ist. In diesem Fall erfolgt ein
Laufzeitabbruch.
26
5.4 Includes mit Gruppennamen
Durch Redefinition von Strukturen unter Verwendung von INCLUDES mit Gruppennamen ist es möglich, Teile komponentenübergreifend auf symbolische Weise zu
selektieren. Neben der Vereinbarung im ABAP-Programm besteht auch die
Möglichkeit, Gruppennamen im Dictionary zu vergeben. Folgende Ausprägungen
sind im ABAP verfügbar:
INCLUDE TYPE
t1 AS grpname[RENAMING WITH SUFFIX suffix].
INCLUDE STRUCTURE s1 AS grpname[RENAMING WITH SUFFIX suffix].
Durch die Einführung eines Gruppennamens für ein Include im DDIC oder durch den
Zusatz AS grpname in ABAP kann der durch das Include definierte Teilbereich der
Struktur symbolisch über den Gruppennamen angesprochen werden. Das folgende
Beispiel faßt Teile einer ABAP-Struktur zu einer Gruppen zusammen, die an ein
Unterprogramm übergeben wird:
* Verwendung von Includes mit Gruppennamen
TYPES: BEGIN OF name,
vorname(20)
TYPE C,
nachname(30) TYPE C,
END OF name.
TYPES: BEGIN OF person,
geschlecht(1) TYPE X.
INCLUDE TYPE name AS pname.
TYPES:
alter
TYPE I,
gewicht
TYPE P,
END OF person.
DATA: s2 TYPE person.
PERFORM use_name USING s2-pname.
5.5 Dynamische Erzeugung von Datenobjekten
·
Mittels CREATE DATA ist es möglich, Felder eines vor- oder benutzerdefinierten
Datentyps zu erzeugen. Folgende Varianten werden angeboten:
CREATE
CREATE
CREATE
CREATE
CREATE
DATA
DATA
DATA
DATA
DATA
dref
dref
dref
dref
dref
TYPE typ.
TYPE (typname).
LIKE feld.
TYPE LINE OF itab.
LIKE LINE OF itab.
Im folgenden Beispiel wird wiederum ein bestimmtes Feld der Datenbanktabelle
X031L gelesen, wobei Feld- und Tabellenname erst zur Laufzeit bekannt sind.
27
*
Lesen eines Feldes der Tabelle X031L
PARAMETERS:
TAB_NAME
LIKE SY-TNAME,
TAB_COMP
LIKE X031L-FIELDNAME,
NUMBER
TYPE I DEFAULT 10.
FIELD-SYMBOLS: <WA>
TYPE ANY,
<COMP> TYPE ANY.
DATA: WA_REF TYPE REF TO DATA.
"Tabellenname
"Feldname
"Zeilenanzahl
CREATE DATA WA_REF TYPE (TAB_NAME).
"Passende Workarea
ASSIGN WA_REF->* TO <WA>.
SELECT * FROM (TAB_NAME) INTO <WA>
UP TO NUMBER ROWS.
ASSIGN COMPONENT TAB_COMP OF STRUCTURE <WA> TO <COMP>.
WRITE: / TAB_COMP, <COMP>.
ENDSELECT.
·
Mit einer weiteren Variante von CREATE DATA ist es möglich, zur Laufzeit
Tabellenobjekte zu erzeugen. Zeilentyp und Schlüssel der Tabelle können dabei
statisch oder dynamisch angegeben werden.
CREATE DATA dref (TYPE [STANDARD|SORTED|HASHED] TABLE
OF (LineType | (Name) |REF TO DATA | REF TO Obj))
| (LIKE [STANDARD|SORTED|HASHED] TABLE OF LineObj )
[ WITH (UNIQUE|NON-UNIQUE)
( KEY (k1 ... kn | (keytab) | TABLE_LINE )
| DEFAULT KEY ) ]
[ INITIAL SIZE m ]
Für diese Anweisung gelten die nachfolgende Einschränkungen:
1. m ist eine Variable oder eine Konstante ohne Vorzeichen, deren Inhalt zur
Laufzeit vom Typ NUMLIKE sein muß.
2. keytab ist eine nicht leere Tabelle des Typs CHARLIKE, deren Komponenten
keine Offset/Längen- oder überlappende Key-Angaben enthalten dürfen. Der
Zusatz TABLE_LINE ist erlaubt, wenn die Tabelle nur eine Zeile enthält.
3. Ein Syntaxfehler erfolgt, wenn entweder die Typ- oder die Zeilen- und die
Schlüsselangabe statisch sind.
4. Ist kein Schlüssel definiert, dann zieht der DEFAULT-KEY.
·
Bei CREATE DATA können auch die generischen Basistypen C, N, X und P
verwendet werden. Durch Zusätze kann die Länge und bei Typ P auch die Zahl
der Dezimalstellen spezifiziert werden.
CREATE DATA dref TYPE (t | (typeName))
[ LENGTH
len ]
[ DECIMALS dec ].
Der Zusatz LENGTH ist nur bei den Typen C, N, X und P erlaubt und muß stets
hinter dem Schlüsselwort TYPE stehen. Bei unsinniger Angabe von LENGTH oder
DECIMALS wird ein abfangbarer Laufzeitfehler ausgelöst.
28
5.6 Dynamische Feldzuweisungen
Bisher galt bei MOVE-CORRESPONDING struc1 TO struc2 die Einschränkung,
daß die Feldtypen der beiden Strukturen zum Zeitpunkt der Generierung bekannt
sein mussten. Diese Einschränkung wird unter Unicode aufgehoben.
In NUS war die Zuweisung von Strukturen unterschiedlicher Fragmentsichten mittels
MOVE bisher unproblematisch. Unter US führte eine solche Zuweisung jedoch trotz
typgleicher Anfangsstücke zu einem Laufzeitfehler.
BEGIN OF struc1,
a(2) TYPE C,
b
TYPE I,
c(1) TYPE C,
d(4) TYPE X,
END OF struc1.
BEGIN OF struc2,
a(2) TYPE C,
b
TYPE I,
c(1) TYPE C,
g(6) TYPE P,
f(2) TYPE X,
END OF struc2.
struc1
a
b
c
struc2
a
b
c
d
g
f
Wurde struc1 = struc2 zum Beispiel durchgeführt, um struc1 den Inhalt des
typgleichen Anfangsstückes struc2-[a,c] zuzuweisen, so genügte eine einfache
MOVE-Anweisung, wobei das Reststück von struc1 nach der Zuweisung
möglicherweise unsinnige Werte enthielt. Da dieselbe Zuweisung unter Unicode
aber wegen der unterschiedlichen Fragmentsichten zu einem Laufzeitfehler führt,
kann nun ersatzweise mit MOVE-CORRESPONDING struc2 TO struc1 gearbeitet
werden. Dasselbe Ergebnis wird unter Unicode genau dann erzielt, wenn die
Feldnamen der Anfangsstücke zur Laufzeit in beiden Strukturen namensgleich sind.
5.7 Ablage von Daten als Cluster
Zur Unterstützung heterogener Unicode-Umgebungen werden neue Varianten der
IMPORT- und EXPORT-Anweisung angeboten. Diese erlauben es, Daten unabhängig
vom Format der Plattform als Cluster in einem X-String abzulegen. Folgende
Varianten können benutzt werden:
·
EXPORT {pi = dobji | pi FROM dobji } TO DATA BUFFER dbuf.
EXPORT (itab) TO DATA BUFFER dbuf.
Die Objekte dobj1 ... dobjn (Felder, flache und komplexe Strukturen oder
Tabellen) werden als ein Cluster im Datenpuffer dbuf abgelegt, der vom Typ
XSTRING sein muß.
TYPES:
BEGIN OF ITAB_TYPE,
CONT TYPE C LENGTH 4,
END OF ITAB_TYPE.
29
DATA:
XSTR TYPE XSTRING,
F1 TYPE C LENGTH 4,
F2 TYPE P,
ITAB TYPE STANDARD TABLE OF ITAB_TYPE.
EXPORT P1 = F1
P2 = F2
TAB = ITAB TO DATA BUFFER XSTR.
·
Neuer Zusatz ... CODE PAGE HINT f1
Mit diesem Zusatz kann für EXPORT obj1 ... objn TO [ DATA BUFFER |
DATABASE | DATASET ] bei mehrdeutigen Codepages angeben werden, mit
welcher Codepage f1 die Importdaten zu interpretieren sind.
·
IMPORT {pi = dobji | pi FROM dobji } FROM DATA BUFFER dbuf.
IMPORT (itab) FROM DATA BUFFER dbuf.
Import der Datenobjekte dobj1 ... dobjn (Felder, flache und komplexe
Strukturen oder Tabellen) aus dem Datenpuffer dbuf, der wiederum vom Typ
XSTRING sein muß. Es werden alle Daten eingelesen, die zuvor über EXPORT ...
TO DATA BUFFER im Datenpuffer dbuf abgelegt wurden. Auch hier wird die
Übereinstimmung der Struktur bei EXPORT und IMPORT nicht geprüft.
Im dynamischen Fall wird die Parameterliste in der zweispaltigen Indextabelle
itab übergeben, deren Spalten vom Typ C oder STRING sein müssen. In der
ersten Spalte von itab müssen die Namen der Parameter, in der zweiten die
Datenobjekte aufgezählt werden. Falls die erste Spalte von itab leer ist, kommt
es zu einer unbehandelbaren Ausnahme mit dem Laufzeitfehler
DYN_IMEX_OBJ_NAME_EMPTY.
5.8 Dateischnittstelle
In der Dateischnittstelle wurde die Anweisungen OPEN DATASET komplett
überarbeitet und für US mit folgenden Ergänzungen versehen:
·
OPEN DATASET dsn IN TEXT MODE.
Die Datei wird zum zeilenweisen Lesen und Schreiben geöffnet. Schließende
Leerzeichen werden in diesem Modus abgeschnitten.
1. Zusatz ... ENCODING (DEFAULT | UTF-8 | NON-UNICODE)
Das Schlüsselwort ENCODING bestimmt den Zeichensatz, mit dem die Daten
bearbeitet werden. DEFAULT ist unter US stets UTF-8, unter NUS aber NONUNICODE. Die Angabe NON-UNICODE bewirkt, dass diejenige Nicht-UnicodeCodepage verwendet wird, die in einem NUS zu der Anmeldesprache oder der
durch die Anweisung SET LOCALE LANGUAGE gesetzten Sprache passt oder
passen würde.
30
2. Zusatz ... REPLACEMENT CHARACTER rc
Dieser Zusatz bestimmt das Ersatzzeichen, welches verwendet wird, wenn ein
Zeichen bei der Konvertierung im Zielzeichensatz nicht vorhanden ist. Ohne
diese Angabe wird die Raute # als Ersatzzeichen eingesetzt.
·
OPEN DATASET dsn IN BINARY MODE.
Die Datei wird ohne Zeilenumbruch zum Lesen und Schreiben geöffnet, wobei in
US und NUS genau der Speicherinhalt übernommen wird.
·
OPEN DATASET dsn IN LEGACY TEXT MODE [(LITTLE | BIG) ENDIAN ]
[ CODE PAGE cp ].
Die Datei wird zum zeilenweisen Lesen und Schreiben in einem Format geöffnet,
das zum TEXT MODE in NUS kompatibel ist.
Der optionale Zusatz ENDIAN bestimmt, in welcher Byte-Reihenfolge Zahlen der
Typen I oder F verarbeitet werden. Fehlt dieser Zusatz, dann legt das
Betriebssystem des Applikationsservers die Reihenfolge fest. Unterscheidet sich
die angegebene Byte-Reihenfolge von derjenigen des Applikationsservers, dann
werden bei den Anweisungen READ DATASET und TRANSFER entsprechende
Konvertierungen durchgeführt. Auch hier ist ein REPLACEMENT CHARACTER rc
möglich.
Der Zusatz CODE PAGE gibt die Codepage an, in der Texte der Datei dsn
dargestellt werden. Fehlt dieser Zusatz, wird diejenige Codepage genommen,
die beim Lesen oder Schreiben der Datei gesetzt ist.
·
OPEN DATASET dsn IN LEGACY BINARY MODE [(LITTLE|BIG) ENDIAN)]
[ CODE PAGE cp ].
Die Datei wird ohne Zeilenumbruch zum Lesen und Schreiben in einem Format
geöffnet, das zum BINARY MODE in NUS kompatibel ist, wobei für den Zusatz
ENDIAN und CODE PAGE die obigen Bestimmungen gelten. Der Zusatz
REPLACEMENT CHARACTER rc ist auch hier wiederum erlaubt.
Bei allen Varianten ist der Zusatz IGNORING CONVERSION ERRORS möglich, der
Laufzeitfehler beim Lesen oder Schreiben der Datei unterdrückt, falls ein
Konvertierungsfehler auftritt. Allgemein gilt, daß ein Lesen oder Schreiben einer
Datei einen Laufzeitfehler auslöst, wenn diese nicht zuvor mittels OPEN DATASET
geöffnet wurde.
5.9 Up- und Download von Dateien
Die bisherigen Funktionsbausteine WS_UPLOAD und WS_DOWNLOAD gehören zwar
nicht zum Standardbefehlssatz von ABAP, sie stellen aber die Dateischnittstelle auf
dem Präsentationsserver dar. WS_UPLOAD und WS_DOWNLOAD sind in einem US
nicht ablauffähig und werden daher ersetzt durch die Bausteine GUI_UPLOAD und
GUI_DOWNLOAD.
Die neuen Funktionsbausteine GUI_UPLOAD und GUI_DOWNLOAD besitzen eine
Schnittstelle, die es ermöglicht, auch Unicode-Formate auf die lokale Platte zu
schreiben. Eine Beschreibung der Schnittstellen enthält die Dokumentation zu
31
diesen Funktionsbausteinen, die unter SAP Easy Access -> Entwicklung -> Function
Builder -> Springen -> Dokumentation aufgerufen werden kann.
5.10 Generische Typen für Feldsymbole und Parameter
Für die Typisierung von Parametern und Feldsymbolen werden neue generische
Datentypen zur Verfügung gestellt:
·
SIMPLE ist kompatibel zu den Typen, die auch zu CLIKE, XSEQUENCE oder
NUMERIC kompatibel sind, also zu allen elementaren Typen einschließlich Cund X-Strings. Durch eine Typisierung mit SIMPLE ist sichergestellt, daß
Parameter oder Feldsymbole mit WRITE ausgegeben oder in arithmetischen
Operationen verwendet werden können. Bei der Verwendung in arithmetischen
Operationen kann es allerdings inhaltsabhängig zu Konvertierungsfehlern
kommen, wenn zum Beispiel ein C-Feld als aktueller Parameter übergeben wird
und der Feldinhalt nicht als Zahl interpretiert werden kann.
·
CLIKE ist kompatibel zu den Typen C, N, D, T und STRING sowie zu rein
zeichenartigen Strukturen. In NUP besteht außerdem Kompatibilität zu den
Elementartypen X und XSTRING. Durch eine Typisierung mit CLIKE ist
sichergestellt, daß Parameter oder Feldsymbole bei allen Operationen zur
Zeichenkettenverarbeitung verwendet werden können, zum Beispiel bei den
Anweisungen CONCATENATE, FIND oder REPLACE. Außerdem ist garantiert, daß
bei Offset- und Längenzugriffe in Zeichen gezählt wird. Zudem sind diese im
Bereich des gesamten Feldes und bei Typ STRING in der aktuellen Stringlänge
erlaubt.
·
CSEQUENCE ist kompatibel zu den Typen C und STRING
·
XSEQUENCE ist kompatibel zu den Typen X und XSTRING. Durch diese
Typisierung ist sichergestellt, daß Parameter oder Feldsymbole in Operationen
zur Bytefolgenverarbeitung verwendet werden können, zum Beispiel bei der
Anweisung CONCATENATE ... IN BYTE MODE.
·
NUMERIC ist kompatibel zu den Typen I, P, F und zu den nur im Dictionary
vorhandenen Typen INT1 (1-Byte-Integer) und INT2 (2-Byte-Integer). Es ist zu
beachten, daß Typ N nicht zu NUMERIC kompatibel ist. Durch die Typisierung
mit NUMERIC ist sichergestellt, daß Parameter und Feldsymbole in
arithmetischen Operationen verwendet werden können, ohne daß Typ- oder
Konvertierungsfehler auftreten.
5.11 Aufbereitung von Listen
· Einführung
Die Anweisung WRITE schreibt den Inhalt von Datenobjekten auf eine Liste. Beim
Schreiben mit der Anweisung WRITE wird die Ausgabe im Listenpuffer
gespeichert und von dort beim Aufruf der Liste zur Anzeige gebracht. Bei jeder
Ausgabe eines Datenobjekts mit WRITE wird implizit oder explizit eine
Ausgabelänge festgelegt, wobei die implizite Ausgabelänge vom Datentyp
abhängt. Mit der Ausgabelänge werden zwei Dinge definiert:
·
die Anzahl der im Listenpuffer für Zeichen zur Verfügung stehenden Stellen
(oder Speicherplätze)
32
·
die Anzahl der auf der eigentlichen Liste zur Verfügung stehenden Spalten
(oder Zellen)
Wenn die Ausgabelänge kleiner als die Länge des Datenobjekts ist, wird dessen
Inhalt beim Schreiben in den Listenpuffer nach bestimmten Regeln verkürzt,
wobei ein Wertverlust bei numerischen Feldern durch das Zeichen * angezeigt
wird. Bei Anzeige oder Ausdruck einer Liste werden die im Listenpuffer
abgelegten Inhalte wie folgt auf die Liste übertragen:
·
In NUS benötigt jedes Zeichen genau soviel Platz im Listenpuffer wie Spalten
auf der Liste. In Single-Byte-Systemen belegt ein Zeichen ein Byte im
Listenpuffer und eine Spalte auf der Liste, während ein Zeichen, das in
Multi-Byte-Systemen mehrere Bytes im Listenpuffer belegt, auch die gleiche
Anzahl an Spalten auf der Liste belegt. Deshalb werden in NUS alle im
Listenpuffer abgelegten Zeichen auf der Liste dargestellt.
·
In US belegt jedes Zeichen in der Regel eine Stelle im Listenpuffer. Ein
Zeichen kann aber auf der Liste mehr als eine Spalte belegen, was
insbesondere für ostasiatische Zeichen gilt. Da auf der Liste aber nur genau
so viele Spalten wie Stellen im Listenpuffer zur Verfügung stehen, können in
diesem Fall nur weniger Zeichen auf der Liste dargestellt werden als im
Listenpuffer abgelegt sind. Die Listenausgabe wird entsprechend verkürzt,
wobei sich die Seite nach der Ausrichtung richtet und mit einem der
Kennzeichen > oder < versehen wird. Auf einer angezeigten Liste kann dann
über die Auswahl von System -> Liste -> Unicode-Anzeige der gesamte Inhalt
zur Anzeige gebracht werden.
Aus diesen Gründen ist die horizontale Position des Listen-Cursors nur in NUS
gleichbedeutend zur Ausgabespalte einer dargestellten oder gedruckten Listen.
In US ist dies nur für die jeweils unteren und oberen Ausgabegrenzen der
einzelnen Ausgaben garantiert.
· Regeln für die WRITE-Anweisung
Um ungewolltes Abschneiden so weit wie möglich zu vermeiden, wurden die
Regeln für die WRITE-Anweisung in UP angepasst und erweitert.
1. WRITE-Anweisung mit impliziter Ausgabelänge
In UP verhält sich die WRITE-Anweisung ohne explizite Angabe der Ausgabelänge
für alle ausgebbaren Datenobjekte mit Ausnahme von Textfeldliteralen und von
Datenobjekten des Typs string wie in NUP. Dadurch kann es vorkommen, dass auf
der Liste weniger Zeichen dargestellt werden als im Listenpuffer abgelegt sind.
Bei Textfeldliteralen und bei Datenobjekten des Typs string wird davon
ausgegangen, dass alle Zeichen dargestellt werden sollen. Deshalb wird die
implizite Ausgabelänge anhand der im Datenobjekt enthaltenen Zeichen so
berechnet, dass sie der Anzahl der auf der Liste benötigten Spalten entspricht.
Wenn diese Ausgabelänge größer als die Länge des Datenobjekts ist, werden
überzählige Stellen beim Schreiben in den Listenpuffer mit Leerzeichen
aufgefüllt. Bei der Darstellung auf der Liste werden diese Leerzeichen wieder
abgeschnitten, da die Darstellung der Zeichen die Ausgabelänge genau ausfüllt.
33
2. WRITE-Anweisung mit expliziter Ausgabelänge
Wenn bei der WRITE-Anweisung ein numerisches Datenobjekt als explizite
Ausgabelänge hinter dem Zusatz AT angegeben ist, wird der Wert dieser Zahl
sowohl in US als auch in NUS als Ausgabelänge verwendet. In US kann sich die
Anzahl der auf der Liste dargestellten Zeichen von der Anzahl der im
Listenpuffer gespeicherten Zeichen unterscheiden. Seit Release 6.20 kann die
Ausgabelänge außer über numerische Datenobjekte wie folgt angegeben werden:
1. WRITE AT (*) ...
· Bei Datenobjekten der Typen c und string wird die Ausgabelänge auf die
Anzahl der Spalten gesetzt, die auf der Liste zur Darstellung des gesamten
Inhalts benötigt werden, wobei keine schließenden Leerzeichen bei Typ c
berücksichtigt werden. Bei Datenobjekten vom Typ string ist dies
gleichbedeutend zur impliziten Länge.
· Bei Datenobjekten der Typen d und t wird die Ausgabelänge auf 10 und 8
gesetzt.
· Bei Datenobjekten der numerischen Typen i, f und p wird die
Ausgabelänge auf den Wert gesetzt, der nötig ist, um den aktuellen Wert
einschließlich Tausendertrennzeichen auszugeben, wobei der Wert nach
Anwendung der eventuellen Zusätze CURRENCY, DECIMALS, NO-SIGN,
ROUND oder UNIT betrachtet wird.
· Bei Datenobjekten der Typen n, x und xstring wird die implizite
Ausgabelänge verwendet.
2. WRITE AT (**) ...
· Bei Datenobjekten der Typen c wird die Ausgabelänge auf die doppelte
Länge des Datenobjektes und bei Datenobjekten vom Typ string auf die
doppelte Anzahl enthaltener Zeichen gesetzt.
· Bei Datenobjekten der Typen d und t wird die Ausgabelänge auf 10 und 8
gesetzt.
· Bei Datenobjekten der numerischen Typen i, f und p wird die
Ausgabelänge auf den Wert gesetzt, der nötig ist, um die maximal
möglichen Werte dieser Typen einschließlich Vorzeichen und
Tausendertrennzeichen auszugeben, wobei der Wert nach Anwendung der
eventuellen Zusätze CURRENCY, DECIMALS, NO-SIGN, ROUND oder UNIT
betrachtet wird.
· Bei Datenobjekten der Typen n, x und xstring wird die implizite
Ausgabelänge verwendet.
· Zusätze bei GET/SET CURSOR FIELD/LINE
Die Zusätze DISPLAY OFFSET und MEMORY OFFSET berücksichtigen, dass
Datenobjekte bei der Darstellung auf einer Liste (Display) und bei der
Zwischenspeicherung im Listenpuffer (Memory) unterschiedliche Längen belegen
können. In Unicode-Codepages gibt es zum Beispiel Zeichen, die im Listenpuffer
nur eine Stelle belegen, bei der Anzeige aber zwei Ausgabespalten benötigen.
34
Dementsprechend wird der Cursor bei der Anweisung SET CURSOR { FIELD f |
LINE l } durch den Zusatz DISPLAY OFFSET off in der Ausgabe und durch den
Zusatz MEMORY OFFSET off im Listenpuffer gesetzt.
In gleicher Weise überträgt die Anweisung GET CURSOR { FIELD f | LINE l } bei
Verwendung des Zusatzes DISPLAY OFFSET off die Cursorposition innerhalb des
angezeigten Feldes in das Datenobjekt off. Dagegen wird bei Verwendung des
Zusatzes MEMORY OFFSET off die Cursorposition im Listenpuffer in das
Datenobjekt off übertragen. Der Zusatz DISPLAY ist die Standardeinstellung und
kann daher auch weggelassen werden.
· Klasse für die Aufbereitung von Listen
Für die Berechnung von Ausgabelängen, die Konvertierung von Werten aus dem
Listenpuffer und die Definition von Feldgrenzen wurde die Klasse
CL_ABAP_LIST_UTILITIES eingeführt. Mit den Rückgabewerten ihrer Methoden
kann eine korrekte Spaltenausrichtung auf ABAP-Listen programmiert werden,
auch wenn ostasiatische Schriften ausgegeben werden.
· Listeneinstellungen
Die Objekte einer Liste können in unterschiedlichen Ausgabelängen angezeigt
werden, indem die gewünschte Länge im Menü System -> Liste -> UnicodeAnzeige eingestellt wird. Dies ist für vor allem bei Bildschirmlisten in US
vorteilhaft, deren Ausgaben abgeschnitten wurden, was durch die Zeichen > oder
< angezeigt wird.
· Empfehlungen
Damit Listen sowohl in US als auch in NUS gleiches Aussehen und Funktionalität
besitzen, wird für die Programmierung von Listen die Einhaltung folgender
Regeln empfohlen:
·
·
·
·
Angabe einer ausreichenden Ausgabelänge
Kein Überschreiben von Teilen eines Feldes
Keine Verwendung von WRITE TO mit RIGHT-JUSTIFIED oder CENTERED mit
nachfolgender WRITE-Ausgabe
Bei selbstprogrammiertem horizontalen Blättern mit der Anweisung SCROLL
sollten nur die untere oder obere Grenze von ausgegebenen Datenobjekten
angegeben werden, da in US die Positionen im Listenpuffer und auf der
dargestellten Liste nur für diese Feldgrenzen garantiert übereinstimmen.
6. Neue Klassen für Unicode
6.1 Ermittlung von Feldeigenschaften
Die Klasse CL_ABAP_CHAR_UTILITIES bietet Attribute und Methoden an, die
Eigenschaften einzelner Zeichen betreffen. Die Komponenten dieser Klasse sind
alle statisch und öffentlich. Die Attribute sind schreibgeschützt und werden im
Klassenkonstruktor initialisiert.
35
·
Attribut CHARSIZE
CHARSIZE TYPE I.
Das Attribut CHARSIZE gibt die Länge eines C(1)-Feldes in Bytes an, also 1 Byte
in einem NUS und 2 oder 4 Byte in einem US.
·
Attribute MINCHAR, MAXCHAR
MINCHAR(1) TYPE C.
MINCHAR enthält in einem NUS das Zeichen mit der Hexadezimaldarstellung
X'00', in einem US das Unicodezeichen U+0000.
MAXCHAR(1) TYPE C.
MAXCHAR enthält in einem NUS das Zeichen mit der Hexadezimaldarstellung
X'FF', in einem US das Unicodezeichen U+FFFD.
Diese Werte dürfen nur in binären Vergleichen für folgende ABAP-Anweisungen
benutzt werden:
1. SORT ohne Zusatz AS TEXT
2. IF mit den Operatoren <, >, <=, >=
3. IF f1 BETWEEN f2 AND f3.
4. IF f in sel.
Bei binären Vergleichen ist allerdings darauf zu achten, daß die Ergebnisse von
der Plattform abhängen. So gilt zum Beispiel im Zeichensatz ISO-8859-1 die
Reihenfolge 1 < A < Z < a < Ä < ü, in EBCDIC jedoch Ä < a < A < ü < Z < 1.
CLEAR feld WITH CL_ABAP_CHAR_UTILITIES=>MAXCHAR kann benutzt werden,
um ein Feld mit einem Wert zu füllen, der größer oder gleich als alle
Zeichenketten ist. Dies funktioniert auch auf Multibyte-NUS.
MINCHAR und MAXCHAR sind im allgemeinen keine gültigen Zeichen des
gegenwärtigen Zeichensatzes. Insbesonders darf TRANSLATE f TO UPPER CASE
nicht auf diese Attribute angewendet werden, weil das Ergebnis undefiniert ist.
Die gleichen Einschränkungen gelten für alle Operationen wie zum Beispiel CS,
NS, CP, NP oder SEARCH, die implizit in Großbuchstaben wandeln. Außerdem
sind Zeichensatzkonvertierungen mit MINCHAR und MAXCHAR nicht zulässig.
Darüber hinaus ist nicht garantiert, daß MINCHAR auf Dynpros als Raute (#)
ausgegeben wird. In manchen Fällen wird MINCHAR als Ende eines Textfeldes
behandelt.
·
Byte Order
Die Konvertierung von Zahlentypen und Unicode zwischen Little Endian und Big
Endian wird durch die Konvertierungsklassen, die im Zusammenhang mit der
Dateischnittstelle eingeführt werden, abgedeckt. Die hier beschriebenen
Attribute dienen dazu, Byte-Order-Marks in X-Containern zu erkennen und zu
schreiben.
36
Attribut ENDIAN
ENDIAN(1) TYPE C.
Hier wie auch in der klassenbasierten Dateischnittstelle werden in US und NUS
die Werte B für Big Endian und L für Little Endian vergeben.
Konstanten BYTE_ORDER_MARK_
BYTE_ORDER_MARK_LITTLE(2)
BYTE_ORDER_MARK_BIG(2)
BYTE_ORDER_MARK_UTF8(3)
TYPE X
TYPE X
TYPE X
Die Werte dieser Konstanten sind für US und NUS dieselben, nämlich X'FFFE' für
Little Endian und X'FEFF' für Big Endian. BYTE_ORDER_MARK_UTF8 enthält die
UTF8-Darstellung von U+'FEFF'.
Die klassenbasierte Dateischnittstelle wird eine Byte-Order-Mark schreiben,
wenn eine UTF16- oder UCS2-Textdatei zum Schreiben geöffnet wird. Wenn eine
Textdatei zum Lesen oder Anfügen geöffnet wird, wird die Byte-Order-Mark
benutzt, um den Endian zu bestimmen. Dabei wird die Byte-Order-Mark beim
Einlesen jedoch nicht in die Zielfelder geschrieben.
·
Attribute NEWLINE, CR_LF und HORIZONTAL_TAB
NEWLINE(1)
TYPE C
CR_LF(2)
TYPE C
HORIZONTAL_TAB(1)
TYPE C
Diese Attribute enthalten die jeweiligen plattformspezifischen Steuerzeichen
6.2 Konvertierung von Daten
Diese Klassen dienen dazu, ABAP-Daten zwischen dem Systemformat und externen
Formaten zu konvertieren. Dabei werden zeichenartige Daten in einen anderen
Zeichensatz und numerische Daten möglicherweise in eine andere Bytereihenfolge
(Endian) konvertiert. Für Daten in einem externen Format müssen Container der
Typen X und XSTRING verwendet werden.
Zeichensatz- und Endiankonvertierung werden auch von der Dateischnittstelle
(OPEN DATASET mit neuen Zusätzen), dem RFC, den Funktionsbausteinen
GUI_DOWNLOAD oder GUI_UPLOAD durchgeführt. Für speziellere Fälle, in denen die
Möglichkeiten dieser Hilfsmittel nicht ausreichen, werden die hier beschriebenen
Klassen zur Verfügung gestellt. Da diese Klassen mit Containern der Typen X und
XSTRING arbeiten, können diese Container von der Dateischnittstelle, dem RFC und
den Funktionsbausteinen GUI_DOWNLOAD und GUI_UPLOAD unkonvertiert
übertragen werden. Die Klassen ersetzen die beiden folgenden Anweisungen:
TRANSLATE c ...FROM CODE PAGE
g1 ... TO CODE PAGE
g2
TRANSLATE f ...FROM NUMBER FORMAT n1 ... TO NUMBER FORMAT n2
Eine ausführliche Beschreibung befindet sich in der Klassendokumentation des Class
Builders. Im einzelner sind folgende Klassen sind verfügbar:
37
CL_ABAP_CONV_IN_CE:
Lesen von Daten aus einem Container und Konvertieren in das Systemformat. Es ist
auch möglich, Strukturen mit Daten zu füllen.
CL_ABAP_CONV_OUT_CE:
Konvertieren von Daten vom Systemformat in ein externes Format und Schreiben in
einen Container.
CL_ABAP_CONV_X2X_CE:
Konvertieren von Daten von einem externen Format in ein anderes externes
Format.
7. RFC und Unicode
Im Zusammenhang mit der ABAP Unicode Umstellung wird auch die RFCSchnittstelle geändert. Die folgenden Ausführungen skizzieren in aller Kürze die
allgemeinen Vorgaben.
Damit der Remote Function Call in US wie auch in NUS funktioniert, wird in der
Destination ein zusätzliches Attribut eingeführt, das beschreibt, ob der RFC in
einem US oder NUS laufen soll. Benutzt ein ABAP-Programm Funktionsbausteine,
die dynamisch Änderungen der RFC-Destination vornehmen, so muß diese neue
Eigenschaft in einem weiteren obligatorischen Parameter versorgt werden.
Bei der Übertragung von Textdaten in einem RFC-Aufruf können neue Ausnahmen
der folgenden Art auftreten:
·
Ein Text kann nicht von der Quellcode- in die Zielcodepage konvertiert werden,
weil die entsprechenden Zeichen in der Zielcodepage nicht vorhanden sind.
·
Das Feld im Zielsystem ist kürzer als das Feld im Quellsystem. Dies kann
vorkommen, wenn Daten von einem US in ein Multibyte-System übertragen
werden.
·
Grundsätzlich kann davon ausgegangen werden, dass Textdaten im sendenden
und empfangenden System unterschiedliche Länge haben. Aus diesem Grund
wird in erster Linie die Verwendung von Strings empfohlen. Wo immer die
Möglichkeit besteht, sollten Längenangaben für Textdaten ausgeschlossen
werden. Im Gegensatz dazu können binäre Daten ohne Probleme mit
Längenangeben gesendet werden.
8. Abrundungsmaßnahmen
Bisher wurde die Klassenhierarchie und die Interface-Implementierungsrelation bei
der Prüfung und Konvertierung von Datentypen nur bei Einzelfeldern mit Klassenund Interface-Referenzen berücksichtigt. Dagegen war dies bei Strukturen, die
Referenzen enthalten, nur sehr uneinheitlich geregelt. Bei der Konvertibilität und
der Typ- und Vergleichskompatibilität tiefer Strukturen wurden deshalb die
nachfolgenden Verallgemeinerungen vorgenommen.
38
1. Konvertibilität und Typkompatibilität für Importing-Parameter:
·
Elementare Komponenten von Strukturen müssen genau übereinstimmen.
·
Die Klassenhierarchie und die Interface-Implementierungsrelation werden
auch für Interface- und Klassenreferenzen als Teilkomponenten
berücksichtigt.
·
Tabellenkomponenten sind miteinander kompatibel, sofern der Zeilentyp
typkompatibel und konvertibel ist. Das bedeutet, daß sich die Zugriffsarten
der Tabellen unterscheiden dürfen und die Zeilentypen konvertibel sein
müssen. Beispielsweise ist eine Strukturkomponente Tabelle über Integer
mit einer Komponente Tabelle über Floats verträglich.
2. Vergleichskompatibilität:
·
Elementare Komponenten müssen genau übereinstimmen.
·
Beliebige Klassen- und Interface-Referenzkomponenten sind zueinander
vergleichskompatibel.
·
Tabellenkomponenten sind miteinander vergleichskompatibel, wenn der
Zeilentyp vergleichskompatibel ist.
39
9. Weitere Beispielprogramme zur Unicode-Umstellung
9.1 Zuweisung zwischen Strukturen: Umstellung durch Includes mit
Gruppenamen
Vor der Unicode-Umstellung:
types: begin of T_STRUC,
F1 type c,
F2 type c,
F3 type i,
F4 type p,
end of T_STRUC.
data: begin of STRUC1.
include type T_STRUC.
data:
F5 type x.
data: end of STRUC1.
data: begin of STRUC2.
include type T_STRUC.
data:
F6 type p.
data: end of STRUC2.
ß Unicode-Fehler!
STRUC1 = STRUC2.
Es sei vorausgesetzt, dass in diesem Fall nur der Inhalt des Includes, also die
Komponenten F1 bis F4 zugewiesen werden sollen. Es wurde bisher in Kauf
genommen, dass die Komponente F5 mit eine unsinnigen Wert überschrieben wird.
Nach der Unicode-Umstellung
Durch die Einführung von Gruppennamen für die Includes und der Verwendung
dieser Gruppennamen bei der Zuweisung kann diese Programmstelle einfach
umgestellt werden.
types: begin of T_STRUC,
F1 type c,
F2 type c,
F3 type i,
F4 type p,
end of T_STRUC.
data: begin of STRUC1.
include type T_STRUC as PART1.
data:
F5 type x.
data: end of STRUC1.
data: begin of STRUC2.
include type T_STRUC as PART1.
data:
F6 type p.
data: end of STRUC2.
40
STRUC1-PART1 = STRUC2-PART1.
ß ok
9.2 Zuweisung zwischen Strukturen: Umstellung durch Offset/LängenZugriffe
Vor der Unicode-Umstellung:
data: begin of STRUC1,
F1(10) type c,
F2(20) type c,
F3
type i,
F4
type p,
end of STRUC1,
begin of STRUC2,
C1(10) type c,
C2(20) type c,
C3
type x,
C4
type f,
end of STRUC2.
ß Unicode-Fehler!
STRUC1 = STRUC2.
In diesem Beispiel wird davon ausgegangen, dass nur der Inhalt der ersten beiden
Komponenten C1 und C2 bei der Zuweisung an F1 und F2 übertragen werden soll,
da die nachfolgenden Komponenten F3 und F4 sowieso durch unsinnige Werte
überschrieben werden.
Nach der Unicode-Umstellung
Da das Anfangsstück der Strukturen, das für die beabsichtigte Zuweisung relevant
ist, rein zeichenartig ist, können die Operanden der Zuweisung jeweils durch
Offset-/Längenzugriffe selektiert werden:
...
STRUC1(30) = STRUC2(30).
ß ok
9.3 Offset/Längen-Zugriff auf Strukturen bei Zuweisung: Verwendung
von Includes
Vor der Unicode-Umstellung
Durch Offset-/Längenzugriffe werden Teilbereiche von Strukturen selektiert, die
einander zugeweisen werden sollen. Da die Strukturen mit nicht zeichenartigen
Kompontenten beginnen, sind die Offset-/Längenzugriffe in unicodefähigen
Programmen nicht mehr erlaubt.
41
data: begin of STRUC1,
F0
type x,
F1(10) type c,
F2(20) type c,
F3
type i,
F4
type p,
end of STRUC1,
begin of STRUC2,
C0
type i,
C1(10) type c,
C2(20) type c,
C3
type x,
C4
type f,
end of STRUC2.
STRUC1+1(30) = STRUC2+4(30).
ß
Unicode-Fehler!
Nach der Unicode-Umstellung
Durch die Einführung von Includes mit Gruppennamen können die entsprechenden
Teilbereiche der Strukturen selektiert und einander zugewiesen werden.
types: begin of PART1,
F1(10) type c,
F2(20) type c,
end of PART1,
begin of PART 2,
C1(10) type c,
C2(20) type c,
end of PART 2.
data: begin of STRUC1,
F0
type x.
include type PART1 as PART.
data:
f3
type i,
f4
type p,
end of STRUC1,
begin of STRUC2,
C0
type i.
include type PART2 as PART.
data:
C3
type x,
C4
type f,
end of STRUC2.
STRUC1-PART = STRUC2-PART.
42
ß ok
9.4 Offset/Längen-Zugriff auf Strukturen bei Zuweisung: IncludesLösung nicht möglich
Vor der Unicode-Umstellung
data: begin of STRUC1,
F0(1) type x,
F1(10) type c,
F2(20) type c,
F3
type i,
F4
type p,
end of STRUC1,
begin of STRUC2,
C0(1) type c,
C1(10) type c,
C2(20) type c,
C3
type i,
C4
type f,
end of STRUC2,
begin of STRUC3,
G0(1) type c,
G1(10) type c,
G2(20) type c,
end of STRUC3.
STRUC1+1(35) = STRUC2+1(35).
STRUC3
= STRUC2.
ß Unicode-Fehler
Umstellungsversuch: Einführung von INCLUDEs mit Gruppennamen
types: begin of PART1,
F1(10) type c,
F2(20) type c,
F3
type i,
end of PART1,
begin of PART2,
C1(10) type c,
C2(20) type c,
C3
type i,
end of PART2.
data:
data:
data:
begin of STRUC1,
F0(1)
type x.
include type PART1 as PART.
F4
type p,
end of struc1.
begin of STRUC2,
C0(1)
type c.
43
include type PART2 as PART.
C4
type f,
end of STRUC2,
data:
begin of STRUC3,
G0(1) type c,
G1(10) type c,
G2(20) type c,
end of STRUC3.
STRUC1-PART = STRUC2-PART.
STRUC3
= STRUC2.
ß Neuer Unicode-Fehler!
Durch die Einführung der Includes kann zwar die ursprüngliche Problemstelle
Unicode-fähig umgestellt werden, es wird aber bei der danach folgenden
Zuweisung ein neues Unicode-Problem erzeugt: Die Zuweisung von STRUC2 an
STRUC3 ist nicht mehr möglich, da durch das Include in STRUC2 eine
Alignmentlücke vor der Komponente C1 entsteht. Dies führt dazu, daß die UnicodeFragmentsichten von STRUC2 und STRUC3 nicht mehr zusammenpassen.
Nach der Umstellung
In diesem Fall bleibt nichts anderes mehr übrig, als die betroffenen Komponenten
der Strukturen einzeln einander zuzuweisen:
data: begin of STRUC1,
F0(1) type x,
F1(10) type c,
F2(20) type c,
F3
type i,
F4
type p,
end of STRUC1,
begin of STRUC2,
C0(1) type c,
C1(10) type c,
C2(20) type c,
C3
type i,
C4
type f,
end of STRUC2,
begin of STRUC3,
G0(1) type c,
G1(10) type c,
G2(20) type c,
end of STRUC3.
STRUC1-F1 = STRUC2-C1.
STRUC1-F2 = STRUC2-C2.
STRUC1-F3 = STRUC2-C3.
STRUC3
= STRUC2.
44
9.5 Zuweisung zwischen Struktur und Einzelfeld vom Typ N
In Unicode-Programmen ist die Zuweisungen zwischen einen nicht zeichenartigen
Struktur und einem Einzelfeld vom Typ N nicht mehr zulässig.
Vor der Unicode-Umstellung
data: begin of STRUC,
NUMBER(20) type n,
F2
type p,
end of STRUC,
NUMBER(20)
type n.
ß Unicode-Fehler!
NUMBER = STRUC.
Nach der Unicode-Umstellung
Da hier die erste Komponenten der Struktur an das Einzelfeld zugewiesen werden
soll, kann die Programmstelle einfach umgestellt werden, indem die Zuweisung der
ganzen Struktur durch eine Zuweisung der ersten Strukturkomponente ersetzt wird.
...
NUMBER = STRUC-NUMBER.
9.6 Zuweisung zwischen Struktur und Einzelfeld vom Typ D
Vor der Unicode-Umstellung
data: begin of STRUC,
YEAR(4) type
MONTH(2) type
DAY(2)
type
F4
type
end of STRUC,
DATE
n,
n,
n,
p,
type d.
DATE = STRUC.
ß Unicode-Fehler!
In Unicode-Programmen ist die Zuweisungen zwischen einen nicht zeichenartigen
Struktur und einem Einzelfeld vom Typ D nicht mehr zulässig.
Nach der Unicode-Umstellung
Durch einen Offset-/Längenzugriff auf das zeichenartige Anfangsstück der Struktur
kann die Problemstelle einfach Unicode-fähig umgestellt weden.
DATE = STRUC(8).
ß ok!
45
9.7 Zuweisung zwischen Struktur und Einzelfeld: ASCII-Codes
Zuweisungen zwischen Strukturen mit Komponenten vom Typ X und Einzelfeldern
wurden früher auch dazu verwendet, um trickreich, z.B. wie in folgendem Beispiel,
Zeichen zu einem ASCII-Code zu berechnen.
Vor der Unicode-Umstellung
data: begin of TAB,
X(1) type x value '09', “ASCII horizontal tab
end of TAB,
C(10)
type c.
C+5(1) = TAB.
ß Unicode-Fehler
In Unicode-Programmen funktioniert dieser Trick nicht mehr. Durch die neuen
vordefinierten Konstanten in Klasse CL_ABAP_CHAR_UTILITIES ist aber nun eine
einfache und saubere Lösung möglich, die auf allen Plattformen funktioniert.
Nach der Unicode-Umstellung
class cl_abap_char_utilities definition load.
c+5(1) = cl_abap_char_utilities=>horizontal_tab.
Anmerkung: Sollte das verwendete Zeichen nicht als Konstante vordefiniert sein,
kann man sich mit der Methode CL_ABAP_CONV_IN_CE=>UCCP beziehungsweise
CL_ABAP_CONV_IN_CE=>UCCPI) zu einem Unicode-Codepoint das entsprechende
Zeichen geben lassen. Es kann dabei die Eigenschaft ausgenützt werden, dass die
Zeichen mit den ASCII-Codes 00 bis 7F den ersten 127 Unicode-Codepoints, also
U+0000 bis U+007F) entsprechen.
9.8 Zuweisung zwischen Struktur und Einzelfeld: Containerfelder (1)
Häufig wurden lange Felder vom Typ C als "Container" verwendet, in dem Daten
unterschiedlicher Strukturen abgelegt werden. Zum Ablegen und Auslesen der
Daten konnte direkt die Zuweisung zwischen Struktur und Einzelfeld verwendet
werden. In Unicode-Programmen sind diese Zuweisungen nur noch erlaubt, wenn
die Struktur rein zeichenartig aufgebaut ist.
Vor der Unicode-Umstellung
data: begin of STRUC,
F1(3) type x,
F2(8) type p,
end of STRUC,
CONTAINER(1000) type c.
“Daten im Container ablegen
46
ß Unicode-Fehler
CONTAINER = STRUC.
”Daten aus dem Container auslesen
STRUC
= CONTAINER.
ß Unicode-Fehler
Die Verwendung von C-Feldern als Container zur Speicherung nicht vollständig
zeichenartiger Strukturen funktioniert nur noch dann, wenn sichergestellt ist, dass
der Inhalt nur temporär innerhalb eines Applikationsservers verwendet wird. Daher
darf der Inhalt des Containerfelds weder in der Datenbank abgelegt noch per RFC
verschickt oder auf ein File geschrieben werden1. Außerdem darf nicht mit Offset
oder Länge auf das Containerfeld zugegriffen werden, um Komponenten einer
Struktur zu selektieren2.
Sind diese Voraussetzungen erfüllt, kann das Füllen und Lesen der Daten
folgendermaßen umgestellt werden, indem durch Casts Feldsymbole vom Typ X auf
das Containerfeld und die Struktur gesetzt werden und danach die Zuweisung
zwischen den Feldsymbolen erfolgt. Die Zuweisung bewirkt nun, daß der Rest des
Containers mit Hex-00-Werten statt mit Leerzeichen aufgefüllt wird. Wenn das CFeld nur als Datenablage verwendet wird, sollte das aber kein Problem sein.
Nach der Unicode-Umstellung
field-symbols: <X_CONTAINER> type x,
<X_STRUC>
type x.
assign CONTAINER to <X_CONTAINER> casting.
assign STRUC
to <X_STRUC>
casting.
“Daten im Container ablegen
<X_CONTAINER> = <X_STRUC>.
ß ok!
”Daten aus dem Container auslesen
<X_STRUC>
= <X_CONTAINER>.
ß ok!
Anmerkung: Es gibt die Klasse CL_ABAP_CONTAINER_UTILITIES, die generische
Möglichkeiten bietet, um Strukturen in Containern vom Typ C oder STRING
abzulegen. Bei Verwendung dieser Klassen ist aber zu berücksichtigen, daß durch
die Klassenverschalung und die generische Lösung möglicherweise . PerformanceEinbußen in Kauf genommen werden müssen.
Beim Ablegen auf beziehungsweise Lesen von der Datenbank oder beim RFC
werden eventuell, abhängig von der Bytereihenfolge (little endian/big endian) der
Applikationsserver-Hardware, automatisch die Bytes des Zeichenfelds vertauscht.
Werden innerhalb des Zeichenfelds nicht zeichenartige Daten abgelegt, dann führt
diese automatische Vertauschung dazu, dass der Inhalt verstümmelt wird.
1
2
Ein Zugriff mit Offset/Länge ist nicht mehr sinnvoll möglich, da die Offset- und
Längenwerte auf Nicht-Unicode- und Unicode-Plattformen unterschiedlich sein
können. Außerdem wird bei Zugriffen auf C-Felder immer in Zeichen gezählt, in
den Strukturen aber auch Komponenten vorkommen können, die auf UnicodeSystemen ungerade Längen oder Offsets besitzen.
47
...
class CL_ABAP_CONTAINER_UTILITIES definition load.
call method CL_ABAP_CONTAINER_UTILITIES =>FILL_CONTAINER_C
exporting IM_VALUE
= STRUC
importing EX_CONTAINER
= CONTAINER
exceptions ILLEGAL_PARAMETER_TYPE = 1
others
= 2.
call method CL_ABAP_CONTAINER_UTILITIES =>READ_CONTAINER_C
exporting IM_CONTAINER
= CONTAINER
importing EX_VALUE
= STRUC
exceptions ILLEGAL_PARAMETER_TYPE = 1
others
= 2.
9.9 Zuweisung zwischen Struktur und Einzelfeld; Containerfelder (2)
Ist sichergestellt, dass die Gesamtlänge der Strukturen, die im C-Container
abgelegt werden, immer ein Vielfaches der Länge eines Zeichens ist - das ist dann
der Fall, wenn die Struktur mindestens eine Komponente vom Typ C, N, D, T, I oder
F enthält – dann kann die folgende, einfachere Lösung verwendet werden, die mit
nur einem Feldsymbol auskommt.
Vor der Unicode-Umstellung
data: begin of STRUC,
F1(3) type x,
F2(8) type p,
F3(10) type c
end of STRUC,
CONTAINER(1000) type c.
“Daten im Container ablegen
CONTAINER = STRUC.
ß Unicode-Fehler!
”Daten aus dem Container auslesen
STRUC
= CONTAINER.
ß Unicode-Fehler!
Nach der Unicode-Umstellung
field-symbols: <C_STRUC>
assign STRUC
type c.
to <C_STRUC>
“Daten im Container ablegen
CONTAINER = <C_STRUC>.
casting.
ß ok
”Daten aus dem Container auslesen
<C_STRUC>
= CONTAINER.
ß ok
48
9.10 Zuweisung zwischen Struktur und Einzelfeld: Nicht lokaler
Container
In diesem Beispiel wird zunächst eine Tabelle gefüllt, die pro Zeile jeweils den
Namen einer DDIC-Struktur und den Inhalt einer solchen Struktur – abgelegt in
einem Containerfeld - enthält. An einer anderen Programmstelle wird dann diese
Tabelle weiterverarbeitet: Es werden die Werte der Strukturkomponenten
ausgegeben, indem über einen Funktionsbaustein die Offsets und Längen der
Strukturkomponenten bestimmt werden und dann durch Offset-/Längenzugriffe auf
den Container die Komponenten selektiert werden.
Vor der Unicode-Umstellung
types: begin of T_VALUE_WA,
TABNAME(30)
type c,
DUMMY_ALIGN
type f,
CONTAINER(1000) type c,
end of T_VALUE_WA,
T_VALUE_LIST type table of T_VALUE_WA.
data:
L_VALUES
L_VALUE_WA
L_D010SINF
L_CO2MAP
type
type
type
type
T_VALUE_LIST,
T_VALUE_WA,
D010SINF,
CO2MAP.
“Ablegen von verschiedenen Strukturen in einer Tabelle:
L_VALUE_WA-TABNAME
= 'D010SINF'.
L_D010SINF-DATALG
= 41.
L_VALUE_WA-CONTAINER = L_D010SINF.
ß Unicode-Fehler
append L_VALUE_WA to L_VALUES.
L_VALUE_WA-TABNAME
L_CO2MAP-ID
L_VALUE_WA-CONTAINER
append L_VALUE_WA to
= 'CO2MAP'.
= 42.
= L_CO2MAP.
L_VALUES.
ß Unicode-Fehler
“Verarbeitung der Tabelle L_VALUES an einer
“anderen Programmstelle: Generische Ausgabe der
“Strukturkomponenten.
data: L_DFIES_TAB type table of DFIES.
field-symbols: <DT>
type DFIES,
<VALUE_WA> type T_VALUE_WA,
<f>.
clear L_VALUES_WA.
loop at L_VALUES assigning <VALUE_WA>.
“Komponenten mit Offset- und Länge bestimmen
call function 'DDIF_NAMETAB_GET'
49
exporting
tabname = <VALUE_WA>-TABNAME
tables
DFIES_TAB = L_DFIES_TAB.
“Inhalt der Komponenten ausgeben
loop at L_DFIES_TAB assigning <DT>.
assign <VALUE_WA>-CONTAINER+<DT>-OFFSET(<DT>-INTLEN)
to <F> type <DT>-INTTYPE.
write <F>.
endloop.
endloop.
Der Offset-/Längenzugriffe führen zwar nicht zu einem Syntax- oder Laufzeitfehler,
würde aber in einem Unicode-System falsche Daten liefern, da die vom
Funktionsbaustein zurückgelieferten Offsets und Längen in Bytes angegeben sind,
beim Zugriff auf den C-Container aber in Zeichen gezählt wird.
Mit den seit Release 4.6 zur Verfügung stehenden Möglichkeiten, Datenobjekte
dynamisch zu erzeugen, kann das Programm deutlich vereinfacht und unicodefähig
umgeschrieben werden.
Als Container für den Inhalt der Stukturen wird hier ein X-String verwendet, der
jeweils mit EXPORT ... TO DATA BUFFER ... gefüllt und mit IMPORT … FROM DATA
BUFFER… ausgelesen wird. Damit ist sichergestellt, dass die Daten auch
applikationsserverübergreifend verwendet werden können.
Nach der Unicode-Umstellung
types: begin of T_VALUE_WA,
TABNAME(30)
type c,
XCONTAINER
type xstring,
end of T_VALUE_WA,
T_VALUE_LIST type table of T_VALUE_WA.
data:
L_VALUES
L_VALUE_WA
L_D010SINF
L_CO2MAP
type
type
type
type
T_VALUE_LIST,
T_VALUE_WA,
D010SINF,
CO2MAP.
“Ablegen von verschiedenen Strukturen in einer Tabelle:
L_D010SINF-DATALG = 41.
L_VALUE_WA-TABNAME = 'D010SINF'.
export
VALUE from L_D010SINF
to data buffer L_VALUE_WA-XCONTAINER.
append L_VALUE_WA to L_VALUES.
L_CO2MAP-ID
= 42.
L_VALUE_WA-TABNAME = 'CO2MAP'.
50
export
VALUE from L_CO2MAP
to data buffer L_VALUE_WA-XCONTAINER.
append L_VALUE_WA to L_VALUES.
“Verarbeitung der Tabelle L_VALUES an einer
“anderen Programmstelle: generische Ausgabe der
“Strukturkomponenten.
data: DREF
type ref to data,
L_NUMBER type i,
L_TYPE
type c.
field-symbols: <STRUC>
type any,
<COMP> type any.
loop at L_VALUES into L_VALUE_WA.
“Erzeugen eines passenden Datenobjekts
create data DREF type (L_VALUE_WA-TABNAME).
assign DREF->* to <STRUC>.
“Datenobjekt mit Inhalt aus dem Container füllen
import VALUE to <STRUC>
from data buffer L_VALUE_WA-XCONTAINER.
“Komponenten der Struktur ausgeben
describe field <STRUC> type L_TYPE components L_NUMBER.
do L_NUMBER times.
assign component SY-INDEX
of structure <STRUC> to <COMP>.
write <COMP>.
enddo.
endloop.
9.11 Zeichenverarbeitung
Im folgenden Beispiel werden Komponenten vom Typ X verwendet, um Zeichen
abzulegen. In Unicode-Programmen ist dies nicht mehr möglich.
Vor der Unicode-Umstellung
data: begin of L_LINE,
TEXT1(10) type
MARK1(1)
type
TEXT2(10) type
MARK2(1)
type
TEXT3(10) type
MARK3(1)
type
BLANK(100) type
end of L_LINE,
c,
x value '00',
c,
x value '00',
c,
x value '00',
c,
51
HEX0(1) type x value '00',
CRLF(2) type x value '0D0A'.
L_LINE-TEXT 1 = 'SYSTEM:
L_LINE-TEXT 2 = 'USER:
L_LINE-TEXT 3 = 'CLIENT:
'.
'.
'.
replace: HEX0 with SY-SYSID into L_LINE, ß Unicode-Fehler
HEX0 with SY-UNAME into L_LINE, ß Unicode-Fehler
HEX0 with SY-MANDT into L_LINE. ß Unicode-Fehler
condense
L_LINE.
concatenate L_LINE CRLF into L_LINE.
ß Unicode-Fehler
ß Unicode-Fehler
*Weiterverarbeitung von L_LINE.
Nach der Unicode-Umstellung
Durch die Verwendung der Konstanten aus Klasse CL_ABAP_CHAR_UTILITIES kann
die Verwendung von X-Feldern vollständig vermieden werden.
class CL_ABAP_CHAR_UTILITIES definition load.
data:
begin of L_LINE,
TEXT1(10) type c,
MARK1(1)
type c
value CL_ABAP_CHAR_UTILITIES=>MINCHAR,
TEXT2(10) type c,
MARK2(1)
type c
value CL_ABAP_CHAR_UTILITIES=>MINCHAR,
TEXT3(10) type c,
MARK3(1)
type c
value CL_ABAP_CHAR_UTILITIES=>MINCHAR,
BLANK(100) type c,
end of L_LINE,
HEX0(1) type c,
CRLF(2) type c.
HEX0 = CL_ABAP_CHAR_UTILITIES=>MINCHAR.
CRLF = CL_ABAP_CHAR_UTILITIES=>CR_LF.
L_LINE-TEXT1 = 'SYSTEM:
L_LINE-TEXT2 = 'USER:
L_LINE-TEXT3 = 'CLIENT:
'.
'.
'.
replace: HEX0 with SY-SYSID into L_LINE,
HEX0 with SY-UNAME into L_LINE,
HEX0 with SY-MANDT into L_LINE.
52
condense L_LINE.
concatenate L_LINE CRLF into L_LINE.
*Weiterverarbeitung von L_LINE.
Anmerkung: Das vorgestellt Programm, das in ähnlicher Weise in einer "echten"
Anwendung gefunden wurde, ist unnötig kompliziert und sicher kein Beispiel für
einen guten Programmierstil. Eine viel klarere Lösung könnte folgendermaßen
aussehen:
class CL_ABAP_CHAR_UTILITIES definition load.
data: L_LINE(133) type c.
concatenate `SYSTEM: ` SY-SYSID
` USER: `
SY-UNAME
` CLIENT: ` SY-MANDT
CL_ABAP_CHAR_UTILITIES=>CR_LF
into L_LINE.
9.12 Öffnen von Dateien
Vor der Unicode-Umstellung
data: begin of STRUC,
F1 type c,
F2 type p,
end of STRUC,
DSN(30) type c value 'TEMPFILE'.
STRUC-F1 = 'X'.
STRUC-F2 = 42.
* Daten auf Datei schreiben
open dataset DSN in text mode.
transfer STRUC to DSN.
close dataset DSN.
Read from file
* Daten aus Datei einlesen
clear STRUC.
open dataset DSN in text mode.
read dataset DSN into STRUC.
close dataset DSN.
write: / STRUC-F1, STRUC-F2.
ß Unicode-Fehler
ß Unicode-Fehler
Das Programmbeispiel ist aus zwei Gründen nicht ablauffähig in Unicode. Zum
einen muss in Unicode-Programmen bei OPEN DATASET das Dateiformat genauer
spezifiziert werden, zum anderen dürfen nur noch rein zeichenartige Strukturen
auf Text-Dateien geschrieben werden.
53
Je nachdem, ob das alte Dateiformat weiterhin gelesen werden können muß oder
ob es möglich ist, die Daten in einem anderen, neuen Format abzulegen, sind
verschiedene Umstellungsvarianten möglich, von denen zwei vorgestellt werden.
Nach der Unicode-Umstellung - Fall 1: Neue textuelle Ablage im UTF-8-Format
...
data: begin of STRUC2,
F1
type c,
F2(20) type c,
end of STRUC2.
* Daten in Textform bringen
move-corresponding STRUC to STRUC2.
* Daten auf Datei schreiben
open dataset DSN in text mode for output encoding utf-8.
transfer STRUC2 to DSN.
close dataset DSN.
* Daten aus Datei einlesen
clear STRUC.
open dataset DSN in text mode for input encoding utf-8.
read dataset DSN into STRUC2.
close dataset DSN.
move-corresponding STRUC2 to STRUC.
write: / STRUC-F1, STRUC-F2.
Durch die textuelle Ablage im UTF8-Format wird sichergestellt, dass die erzeugten
Dateien plattformunabhängig sind.
Nach der Unicode-Umstellung - Fall 2: Altes Nicht-Unicode-Format muss
beibehalten werden
...
* Daten auf Datei schreiben
open dataset DSN in legacy text mode for output.
transfer STRUC to DSN.
close dataset DSN.
* read from file
clear STRUC.
open dataset DSN in legacy text mode for input.
read dataset DSN into STRUC.
close dataset DSN.
write: / STRUC-F1, STRUC-F2.
Durch die Verwendung von des LEGACY TEXT MODE ist sichergestellt, daß die Daten
im alten Nicht-Unicode-Format abgelegt und gelesen werden. In diesem Modus ist
es auch erlaubt, nicht zeichenartige Strukturen zu lesen oder zu schreiben. Es ist
aber zu beachten, dass es in echten Unicode-Systemen zu Datenverlust und
54
Konvertierungsfehlern kommen kann, wenn in der Struktur Zeichen enthalten sind,
die in der Nicht-Unicode-Codepage nicht repräsentiert werden können.
9.13 Ausgabe von Listen
Nachträgliches überschreibendes Positionieren von SY-VLINE
Schlechtes Coding:
WRITE / AT 2 '일이삼'.
WRITE
AT 1 sy-vline.
WRITE
AT 4 sy-vline.
WRITE
AT 7 sy-vline.
WRITE
AT 10 sy-vline.
Soll |일|이|삼|
Ist:
|일| >| |
Empfohlene Lösung:
WRITE AT 1 sy-vline.
WRITE AT 2 '일'.
WRITE AT 4 sy-vline.
WRITE AT 5 '이'.
WRITE AT 7 sy-vline.
WRITE AT 8 '삼'.
WRITE AT 10 sy-vline.
Rechtsbündige Ausgabe mit RIGHT-JUSTIFIED:
Schlechtes Coding:
DATA text(10) TYPE c.
text = '일이삼'.
WRITE text TO text RIGHT-JUSTIFIED.
WRITE text.
Soll:
xxxx일이삼
Ist:
xxxxxxx일>
Empfohlene Lösung:
DATA text(10) type c.
text = '일이삼'.
WRITE text RIGHT-JUSTIFIED.
55
Ausgabe des vollständigen Inhaltes
Schlechtes Coding:
DATA text(10) TYPE c.
text = 'OTTOS MOPS'.
WRITE / text.
text = '가갸거겨고교구규그기'.
WRITE / text.
Soll: OTTOS MOPS
가갸거겨고교구규그기
Ist:
OTTOS MOPS
가갸거겨>x
Empfohlene Lösung:
DATA text(10) TYPE c.
text = 'OTTOS MOPS'.
WRITE / (*) text.
text = '가갸거겨고교구규그기'.
WRITE / (*) text.
Blättern:
Schlechtes Coding:
TYPES t_line(100)
DATA: line
tab
PARAMETERS scrolcol
TYPE
TYPE
TYPE
TYPE
c.
t_line,
table of t_line.
i DEFAULT 14.
line = '이름1: xxxxxx 이름2: yyyyyy'.
APPEND line TO tab.
line = '이름1: 남명희 이름2: 조홍우'.
APPEND line TO tab.
LOOP AT tab INTO line.
WRITE / line+scrolcol.
ENDLOOP.
Soll: 이름2: yyyyyy
이름2: 조홍우
Ist:
2: yyyyyy
조홍우
Empfohlene Lösung:
56
TYPES t_line(100)
DATA: line
tab
PARAMETERS scrolcol
TYPE
TYPE
TYPE
TYPE
c.
t_line,
table of t_line.
i DEFAULT 14.
line = '이름1: xxxxxx 이름2: yyyyyy'.
APPEND line TO tab.
line = '이름1: 남명희 이름2: 조홍우'.
APPEND line TO tab.
LOOP AT tab INTO line.
WRITE / line.
ENDLOOP.
SCROLL LIST TO COLUMN scrolcol.
Vermischen von Ausgabe- und Pufferlänge
Das Beispiel bezieht sich auf die Datenbanktabelle ZCHNUMBERS im ABAP
Dictionary, die als Inhalt die Bezeichnungen der Zahlen 1 bis 5 in Englisch und
Koreanisch enthält.
Schlechtes Coding:
SELECT * FROM zchnumbers INTO wa ORDER BY num lang.
WRITE wa-lang TO line(2).
WRITE sy-vline TO line+2(1).
WRITE wa-name TO line+3(5).
WRITE sy-vline TO line+8(1).
WRITE wa-num
TO line+9(3) RIGHT-JUSTIFIED.
WRITE / line.
ENDSELECT.
Soll: KO|하나 | 1
Ist
KO|하나 | 1
EN|one | 1
EN|one | 1
KO|둘 | 2
KO|둘
EN|two | 2
EN|two | 2
KO|셋 | 3
EN|two | 2
EN|three| 3
KO|셋
KO|넷 | 4
EN|three| 3
EN|four | 4
KO|넷
KO|다섯 | 5
EN|four | 4
EN|five | 5
KO|다섯 | 5
|2
|3
|4
Empfohlene Lösung:
DATA: offset_tab TYPE abap_offset_tab,
57
disp_line
LIKE line.
APPEND 3 TO offset_tab.
APPEND 8 TO offset_tab.
SELECT * FROM zchnumbers INTO wa.
WRITE wa-lang TO line(2).
WRITE sy-vline TO line+2(1).
WRITE wa-name TO line+3(5).
WRITE sy-vline TO line+8(1).
WRIE wa-num
TO line+9(3) RIGHT-JUSTIFIED.
CALL METHOD cl_abap_list_utilities=>memory_to_display
EXPORTING memory_data = line
offset_tab
= offset_tab
IMPORTING display_data = disp_line.
WRITE / disp_line.
ENDSELECT.
Missbrauch des Systemfeldes SY-CUCOL als Puffer-Offset
Schlechtes Coding:
DATA: off type i.
AT LINE-SELECTION.
off = sy-staco + sy-cucol – 3.
sy-lisel+off(1) = '-'.
MODIFY CURRENT LINE.
START-OF-SELECTION.
WRITE / '한국'
WRITE at 50(14) '일-이-삼-사-오'.
SCROLL LIST TO COLUMN 20.
Wird der Cursor auf die Lücken zwischen den sichtbaren koreanischen Zeichen
gestellt und danach ein Doppelklick mit der linken Maustaste ausgeführt, dann
erscheint folgende Ausgabe:
Soll: 012345678901234567890123456789일-이-삼-사-오
Ist:
01234567890123456789012345
일 이 -사 - - -
Empfohlene Lösung:
DATA:
f TYPE string,
mo TYPE i.
AT LINE-SELECTION.
GET CURSOR FIELD f MEMORY OFFSET mo.
sy-lisel+mem_off(1) = '-'.
MODIFY CURRENT LINE.
58
...
59
10. Glossar
Byteartig
Die ABAP-Datentypen X und X-STRING
Code
Binäre Verschlüsselung von Buchstaben, Ziffern und Sonderzeichen
Codepage
Auswahl der verschlüsselten Zeichen für eine ausgewählte Umgebung
Datencluster
Zusammenstellung mehrerer Datenobjekte (Felder, Strukturen, Tabellen)
DDIC
ABAP Datenverzeichnis
Endian
Die Byte-Reihenfolge einer Zahl wird im Speicher mit abnehmenden Stellenwerten
von links nach rechts (Big Endian) oder von rechts nach links (Little Endian)
abgelegt.
Frontend
Präsentationsserver des
Kernel
In den Programmiersprachen C und C++ codierte Basisfunktionalität des
NUP
Nicht-Unicode-Programm: Programm, bei dem das Unicodeflag nicht gesetzt ist
NUS
Nicht-Unicode-System: -System, in dem Zeichen binär durch 1 Byte verschlüsselt
werden.
Restlänge
Die Restlänge eines Feldes oder einer zeichenartigen Struktur errechnet sich aus
der Differenz zwischen Gesamtlänge minus Offset.
Surrogate Area
Zeichenergänzung für alle Zeichen, die nicht im Standard-Unicode mit maximal 64
k Zeichen enthalten sind. Zu dem Bitmuster aus dem Standard-Unicode werden
zwei weitere Bytes aus dieser Area zugelesen.
Unicode-Fragmentsicht
Einteilung von Strukturen in gleichartige Datenbereiche
UP
Unicode-Programm: ABAP-Programm, bei dem das Unicodeflag gesetzt ist
US
Unicode-System: System, in dem Zeichen binär durch 2 oder 4 Byte verschlüsselt
werden.
UTF-8
Datenformat für Kommunikation und Datenaustausch
XML
Extensible Markup Language: Auszeichnungssprache zur Darstellung beliebiger
Dokumente im Internet
Zeichen
Buchstabe, Ziffer oder Sonderzeichen
Zeichenartig
Die ABAP-Datentypen C, N, D, T und STRING
60
11. Verzeichnis der Schlüsselbegriffe
Append
14
Assign
10, 11, 23, 24, 25
At
9
Byte-
22
Casting
25
Charlen
16
Clear
22
Concatenate
15, 22
Condense
15
Convert Text
15
Create Data
27, 28, 29
Datentypen
5
Describe
19, 23
Delete dbtab
18
Export
29, 30
Fetch
18
Field-Symbols
11, 17
Find
22
Generate
21
Gen. Datentypen
32
Get Bit
20
If
14, 15
Import
29
Include
18, 27
Increment
24, 25
Insert dbtab
18
Insert itab
14
Insert report
21
Loop at
14, 20
Modify dbtab
18
Modify itab
14
Move
12, 13, 14
61
Move-Corresponding
29
Numofchar
16
Offset
9, 10, 11
Open Dataset
19, 30
Operatoren
16
Overlay
15
Perform
10, 17
Range
10, 20, 24
Read Dataset
19
Read Table
20
Refresh
20
Replace
15, 22
Search
15, 22
Select
18
Set Bit
20
Shift
15, 22
Split
15, 22
Stringoperatoren
16
Strlen
16
Structure
17
Transfer
19
Translate
15
Update dbtab
18
Vary
21
Varying
21
Write
17
Write To
17
XStrlen
22
62
Herunterladen