So läuft Abap-Code auch in Japan

07.04.2006
Von Gert Holz
In SAPs Programmiersprache geschriebene Software auf Unicode umzustellen ist kein leichtes Unterfangen.

Was sind die Auswirkungen, wenn ein SAP-System auf Unicode umgestellt wird? Da jedes Zeichen in Unicode nicht durch ein Byte, sondern durch zwei oder mehr Bytes dargestellt wird, erhöhen sich die Anforderungen an die Hardware.

Hier lesen Sie …

Zusätzlicher Leistungsbedarf

CPU +30 Prozent

Speicherplatz für die Datenbank +40 bis +70 Prozent

Hauptspeicher +50 Prozent

Die Zunahme des benötigten Speicherplatzes für die Datenbank hängt von der internen Zeichensatzcodierung ab. UTF-8 (8-Bit Unicode Transformation Format) ist die am weitesten verbreitete Codierung; dabei wird jedem Unicode-Zeichen eine Bytekette von variabler Länge zugeordnet. Der Standard UTF-8 unterstützt bis zu 4 Byte, auf die sich wie bei allen UTF-Formaten jedes der gut 1,1 Millionen Unicode-Zeichen abbilden lässt.

Neben der Aufrüstung der Hardware müssen Anwender ihre kundeneigenen Programme auf Unicode-Verträglichkeit prüfen. Das kann aufwändig sein. Selbst einfache Wertzuweisungen, bei denen das System intern von einem in ein anderes Format konvertiert, funktionieren zum Teil nicht mehr wie gewohnt nach der Unicode-Migration und führen stattdessen zu einem Laufzeitfehler. Ferner müssen Anwender die meisten Schnittstellen zu anderen Systemen überarbeiten.

Ablauf einer Migration zu Unicode

Die Untersuchung und Umstellung der kundeneigenen Programme auf Unicode-Verträglichkeit erfolgt üblicherweise in einem internen Projekt, an dessen Beginn die Verwendung der SAP-Transaktion UCCHECK steht. Das SAP-System zur Abap-Migration kann dabei entweder schon ein echtes Unicode-System sein, oder aber die Unicode-Fähigkeit der Programme wird mit dem Setzen des Systemparameters ‘abap/unicode_check’ auf den Wert ‘on’ erzwungen. Im letzteren Fall muss die SAP-Applikation selbst noch nicht auf Unicode umgestellt sein.

SAP-Anwender, die den Aufbau eines Unicode-Systems erst für die Zukunft planen, aber jetzt schon sicherstellen wollen, dass alle Eigenentwicklungen später nicht mehr angepasst werden müssen, sollten den oben genannten Systemparameter setzen. Damit sind alle Entwickler gezwungen, ihre Programme jetzt schon im Einklang mit dem später zu erwartenden Systemzustand zu schreiben.

Unverträglichkeiten

Die Transaktion UCCHECK erlaubt eine feine Auswahl der zu untersuchenden Programme. Während der Prüfung auf statische Unicode-Verträglichkeit werden die unverträglichen Programmstellen sowie ein ausführlicher Fehlertext angezeigt. Die Analyse des Fehlertexts führt meist schnell zu einer Lösung.

<include image: Ergebnis UCCHECK.jpg>

Wenn die Programme weniger komplex sind und überwiegend mit vollständig getypten Datenstrukturen arbeiten, ist nach erfolgreichem Abarbeiten der UCCHECK-Ergebnisliste die Umstellung auf Unicode fast komplett. Anders sieht es jedoch aus, wenn die Programme viel mit internen und zum Teil unstrukturierten Puffern arbeiten oder aber benötigte Strukturen erst zur Laufzeit erzeugen oder zuweisen. In diesem Fall kann UCCHECK wirklich nur die Programmstellen finden, bei denen statische Fehler erwartet werden können.

Beispiel anhand des Lesens einer HR-Tabelle:

report zp_unicode_check.

data: itab type standard table of prel_db, tabname type tabname value ‘PA0002’, i_pernr type persno value 1000.

start-of-selection.

* Die folgende Anweisung ist nicht-unicode-verträglich und wird von

* UCCHECK entsprechend abgewiesen.

select * into table itab from pa0002 where pernr = i_pernr.

* Die folgende Anweisung wird von UCCHECK nicht beanstandet,

* führt aber zu einem Laufzeitfehler

select * into table itab from (tabname) where pernr = i_pernr.

Die statische Prüfung in UCCHECK beanstandet die erste SELECT-Zeile, kann aber wegen des dynamischen Lesens via (tabname) in der zweiten Datenbankabfrage keinen Konflikt feststellen. Dieses Problem wird erst bei der Ausführung des Programms in einer Unicode-Umgebung zu einem Laufzeitfehler führen.

Anhand dieses kleinen Beispiels wird schon das eigentliche Problem der Umstellung erkennbar. Viele Fehler treten erst zur Laufzeit auf, wenn dynamisch verwendete Datenstrukturen nicht korrekt aufeinander projiziert werden können.

Da die Transaktion UCCHECK nur statische Prüfungen zulässt, schließt sich nach der ersten Überarbeitung der Programme üblicherweise ein ausführlicher Test aller Programmteile an. In diesem sollen Laufzeitfehler aufgespürt werden.

Nach unserer Erfahrung ist der Laufzeittest der schwierigere Teil der Migration, da es in vielen Fällen nicht für alle zu testenden Programmabschnitte entsprechende Testfälle gibt.

Laufzeittests

Ein Programm mit etwas mehr als 140000 Programmzeilen konnte innerhalb von zwei Tagen so weit überarbeitet werden, dass die statische Prüfung in UCCHECK keine Fehler mehr fand. Der anschließende Test des Laufzeitverhaltens und die notwendigen Korrekturen nahmen ungleich mehr Zeit in Anspruch, sicher auch deshalb, weil die getestete Software sehr viele Daten mit anderen Systemen über spezielle Schnittstellen austauscht.

Die folgenden Ausführungen beziehen sich immer auf das Verhalten von Abap-Programmen in einer Unicode-Umgebung, jedoch können alle dargestellten Erweiterungen auch in Programmen verwendet werden, die auf Non-Unicode-Systemen laufen. SAP garantiert, dass alle Programmänderungen, die für den Einsatz in Unicode-Umgebungen vorgenommen werden, ebenso in Non-Unicode-Umgebungen funktionieren. Unsere Erfahrungen bestätigen dies. Die folgenden Beispiele sind typisch für eine Migration zu einer komplett Unicode-fähigen Abap-Umgebung.

Verwendung von unstrukturierten Datenpuffern: Häufig werden in Programmen unstrukturierte Puffer beziehungsweise Container verwendet, um Daten zwischenzuspeichern und an andere Programmteile weiterzugeben. Gemäß Unicode-Richtlinien muss der Programmierer dem eigentlich unstrukturierten Puffer einen Typ "aufzwingen", bevor er ihn mit Daten befüllt. Nur so lassen sich Laufzeitfehler wegen Strukturunverträglichkeiten vermeiden.

Statt des einfachen Non-Unicode-Ablaufs

data: a0008 type pa0008, puffer type prel_db.

puffer = a0008.

bei dem das System die Quellstruktur byteweise in die Zielvariable überträgt, muß man in einer Unicode-Umgebung den aufwändigeren Weg nehmen und dem Puffer vor der Wertzuweisung die Struktur des Quellfeldes mittels CASTING "aufprägen". Dafür stellt SAP dem ASSIGN-Befehl umfangreiche Erweiterungen zur Verfügung, unter anderem die folgende:

data: a0008 type pa0008, puffer type prel_db.

field-symbols: <puffer> type any.

assign puffer to <puffer> casting like a0008.

<puffer> = a0008.

unassign <puffer>.

Probleme bei Anweisungen mit "DESCRIBE FIELD feld LENGTH len" und "DESCRIBE DISTANCE":Im Unicode-Umfeld ist für beide Anweisungen einer der beiden Zusätze ‘IN BYTE MODE’ oder ‘IN CHARACTER MODE’ zwingend erforderlich. Fallweise muß entschieden werden, welcher der beiden Zusätze der richtige ist. Wenn es beispielsweise um die Aufbereitung oder Positionierung eines Feldes in einer Ausgabeliste geht, ist der Zusatz ‘IN CHARACTER MODE’ der richtige. Will der Anwender aber die Anzahl der Zeilen berechnen lassen, die in einem Verarbeitungsschritt von der Datenbank gelesen werden dürfen, ohne eine bestimmte Puffergröße zu überschreiten (Stichwort ‘PACKAGE SIZE’), dann muss die Betrachtung in Bytes erfolgen.

Zugriffe und Zuweisungen mit Offset- und Längenangaben:Die Verwendung von Längen- und Offset-Angaben ist grundsätzlich kritisch, da die Länge von zeichenartigen Feldern im Unicode-Umfeld von der Systemplattform abhängt. Damit ist bei Zugriffen auf Strukturen, die aus Komponenten unterschiedlichen Typs bestehen, nicht eindeutig klar, in welcher Maßeinheit (Byte/Character) der Offset-Zugriff erfolgen soll. Bei einer Definition einer Struktur wie:

data: begin of struc1,

c1(3) type c,

n1(8) type n,

f1 type f,

d1 type d,

end of struc1.

werden die Daten der Struktur in einem Unicode-System nicht fortlaufend im Hauptspeicher abgelegt. Vielmehr fügt das aus Gründen der Feldausrichtung bei Bedarf "leere" Bytes ein. In der Beispielstruktur würde zwischen den Komponenten N1 und F1 eine Ausrichtungslücke eingeschoben. Ausgeschlossen sind daher Zugriffe auf die Struktur mit der Anweisung:

data: var(12) type c. var = struc1+8(12).

Grundsätzlich kennzeichnet SAP Zugriffe auf strukturierte Felder mit Offset- und Längenangaben mit dem Attribut "unerwünscht" - das gilt auch für Non-Unicode-Systeme.

Das folgende Beispiel versucht den gleichen Zugriff, aber mit dem Trick, dass Offset und Längenangabe erst zur Laufzeit bekannt sind. Das ist zwar syntaktisch korrekt und führt zu keinem Laufzeitfehler - aber auch nicht zum gewünschten Ergebnis.

data: len type i value 12,

offset type i value 5,

var(12) type c.

field-symbols: var type any.

assign struc1+offset(len) to var.

if sy-subrc = 0 and var is assigned.

var = var.

endif.

Kann die Zuweisung an das Feldsymbol nicht erfolgen, weil die Offset- oder Längenangabe den zulässigen Bereich überschreiten, wird das Feldsymbol auf UNASSIGNED gesetzt, aber kein Laufzeitfehler ausgelöst. Deswegen muss in einem solchen Fall abgefragt werden, ob das Feldsymbol wirklich zugewiesen wurde ("is assigned").

Datenaustausch mit der lokalen Arbeitsstation:Häufig senden Abap-Programme Daten an die Arbeitsstation des Benutzers, um zum Beispiel die Daten in Microsoft Excel grafisch aufzubereiten. Umgekehrt lassen sich Daten aus lokalen Listen oder Tabellen per Programm zur weiteren Verarbeitung in das SAP-System laden. Bisher wurden dazu die Funktionsbausteine WS_DOWNLOAD und WS_UPLOAD verwendet. Diese sind aber nicht Unicode-verträglich und durch die Funktionsbausteine GUI_DOWNLOAD und GUI_UPLOAD zu ersetzen. Mit ihnen ist es auch möglich, Unicode-Daten auf die lokale Arbeitsstation zu laden oder von dort zu lesen.

Datenaustausch mit anderen SAP-Systemen: Der Online-Datenaustausch mit anderen SAP-Sytemen ist in der Abap-Programmierung durch RFC-Funktionsbausteine realisiert. Der Begriff "RFC" steht dabei in der SAP-Welt für "Remote Function Call" und meint einen Aufruf eines Abap-Funktionsbausteins in einem anderen SAP-System. Zuerst die gute Nachricht: Auch wenn das rufende Programm ein Unicode-System ist und das gerufene nicht (oder umgekehrt), dann brauchen sich Anwender nicht um die Konvertierung der Übergabeparameter zu kümmern, denn das erledigen die beiden beteiligten SAP-Systeme selbst.

Ein Problem beim RFC-Datenaustausch zwischen Unicode- und Non-Unicode-Systemen entsteht, wenn Zeichen übergeben werden, die das empfangende System aufgrund der dort installierten Codepages nicht korrekt interpretieren kann. In einem solchen Fall droht ein Informationsverlust, wie das folgende Beispiel zeigt: Daten einer japanischen Adresse werden per RFC-Aufruf an ein System übertragen, in dem nur westeuropäische Zeichensätze installiert sind. Dann werden zwar Zeichen übertragen, das Zielsystem aber kann die Adresse nicht mehr korrekt darstellen, weil ihm die benötigten Zeichen fehlen.

Dateischnittstellen: Beim Datenaustausch mit anderen Systemen über Dateischnittstellen müssen die Abap-Befehle zum Öffnen von Dateien auf einem Applikations-Server überarbeitet werden.

Ein einfaches OPEN DATASET dataset FOR OUTPUT IN TEXT MODE. mit anschließender Weitergabe von Daten in die geöffnete Datei führt auf einem Unicode-System dazu, dass pro Zeichen zwei Bytes geschrieben werden. Das Schreiben einer Zeichenkette mit 80 Zeichen führt dann zu einer Dateigröße von 160 Bytes. Das Empfängersystem der Datei wird, wenn es nicht auch mit Unicode-fähigen Programmen operiert, beim Einlesen der vereinbarten 80 Zeichen nur unvollständige Informationen lesen, die zudem auch noch aus kryptischen Zeichen bestehen können.

Das gleiche Problem tritt auf, wenn das Unicode-System Daten aus einer Datei lesen soll. Nach dem Öffnen mit dem üblichen OPEN DATASET dataset FOR INPUT IN TEXT MODE. werden beim Lesen eines Zeichens statt eines Bytes immer zwei Bytes gelesen. Dies produziert unsinnige Ergebnisse, wenn ein Nicht-Unicode-System die gelesene Datei erstellt hat.

SAP hat deshalb mit der Einführung von Unicode den OPEN-DATASET-Befehl erweitert. Damit kann man dem System mitteilen, ob der Inhalt der Datei im "herkömmlichen" Format einzulesen oder zu schreiben ist. Zudem legt der Anwender den Zeichensatz und das Zahlenformat fest.

Im einfachsten Fall ergänzt man die bisherigen OPEN-DATASET-Anweisungen mit dem Zusatz ‘LEGACY’, dann werden alle Dateioperationen so ausgeführt wie bisher.

Zusatz "Legacy"

Neben LEGACY lässt sich der Zusatzbehelf ‘CODEPAGE cp’ verwenden. Damit wird gleich beim Lesen und Schreiben von Dateien eine interne Zeichensatzkonvertierung durch das SAP-System selbst vorgenommen. Dieser Zusatz ist umso wichtiger, wenn man weiß, dass der bisher zur Verfügung stehende Befehl TRANSLATE zeichenkette FROM CODE PAGE cp1 TO CODE PAGE cp2. im Unicode-Umfeld verboten ist.

Ebenso verhält es sich mit dem neuen Zusatz ‘BIG LITTLE ENDIAN’, mit dem sich in heterogenen Hardwarelandschaften Inkompatibilitäten wegen unterschiedlicher interner Darstellung der Zahlen vermeiden lassen. Der TRANSLATE-Befehl zum Umwandeln der Zahlenformate von Big Endian nach Little Endian und umgekehrt ist natürlich ebenso verboten.

Falls die beiden Zusätze zur internen Konvertierung von Zeichensatz und Zahlenformat nicht verwendet werden können, das Programm aber dennoch eine Konvertierung vornehmen soll, können Anwender auf Konverter-Methoden der SAP zurückgreifen.

Aufbereitung und Drucken von Listen:Die Darstellung eines Zeichens kann in Unicode-Systemen mehr als eine Spalte in einer Ausgabeliste belegen. Das gilt vor allem für ostasiatische Zeichen. Im internen Listenpuffer hingegen belegt jedes Zeichen, unabhängig von seiner tatsächlichen Ausgabelänge, aber nur eine Spalte. Das Problem in einem Unicode-System besteht nun darin, dass auf Listen nur genau so viele Spalten ausgegeben werden können, wie Stellen im Listenpuffer zur Verfügung stehen. Deshalb kann es zu abgeschnittenen Listenausgaben kommen. Eine verkürzte Darstellung wird dann mit einem der Zeichen oder gekennzeichnet. Der Benutzer kann den gesamten Listeninhalt mit dem Menüpunkt ‘System / Liste / Unicode-Anzeige’ ausgeben.

Üblicherweise ist es jedoch nicht erwünscht, dass das System Listeninhalte zunächst abschneidet und der Anwender sie dann sichtbar machen muss. Das ungewollte Abschneiden lässt sich mit Erweiterungen des WRITE-Befehls weitgehend vermeiden, mit denen der Programmierer gleich eine explizite Ausgabelänge vorgeben kann.

Nur wenige Drucker können west- und osteuropäische sowie ostasiatische Zeichen ausgeben. Auch solche Geräte können aber auch in einer Unicode-Umgebung weiterverwendet werden, wobei sie nur diejenigen Zeichen richtig ausgeben, die in ihrem eingebauten Zeichensatz enthalten sind. (fn)