Die UNSTRING-Anweisung

Mit Hilfe dieser Anweisung kann eine Zeichenkette in einem Datenfeld in mehrere Datenfelder aufgeteilt werden. Das Feld, welches es aufzusplitten gilt (Sendefeld), muß ein Gruppenfeld oder ein alphanumerisches Datenfeld sein.
Die Empfangsfelder werden nach INTO angegeben. Es darf sich hierbei um:
- alphabethische Datenfelder ohne Druckaufbereitung
- alphanumerische Datenfelder
- Gruppenfelder oder - numerische Datenfelder die mit USAGE IS DISPLAY definiert wurden und das Symbol 'P' nicht in der Datenbeschreibung vorkommt.

Beispiel:
Nehmen wir an, wir haben ein Programm entwickelt, welches von verschiedenen Personen benutzt werden soll. Jede Person hat eine eigene Zugangsnummer. Diese Nummer ist wie folgt beschrieben:

Stellen Inhalt Code für
1-6 alphanum. Geb.-Dat.
7 - Trennz.
8-10 alphanum. 3 Buchst. v. Nachname
11 . Trennz.
12-20 alphanum. Pers.-Nr.
21 Leer Trennz.

Die Nummer von Boris Becker lautet: 221167-suh.6363414C0

Nach ihrer Eingabe (geschieht in Eingabe SECTION - interessiert hier nicht) soll unser Programm jetzt diese Nummer prüfen, analysieren und entweder den Zugang gewähren (zum Programmteil Bin-Drin gehen - vorher Anmeldezahl um 1 erhöhen) oder die Art des Eingabefehlers ausgeben. Man könnte dieses Problem wie folgt lösen:

             :
WORKING STORAGE SECTION.
             :
01 Personen-Nummer PIC X(21).
01 Geb-Code PIC X(8).
01 Nam-Code PIC X(3).
01 Pers-Code PIC X(9).
01 Tr1 PIC X.
01 Tr2 PIC X.
01 Tr3 PIC X.
01 Anz1 PIC 99.
01 Anz2 PIC 99.
01 Anz3 PIC 99.
01 Feldzahl PIC 9.
01 Fehler-Text PIC X(30).
01 Fehler-KZ PIC 9.

01 Warten PIC X.

01 Anmeldezahl PIC 9(5).
             :

PROCEDURE DIVISION.
             :

Eingabe SECTION.
             :

Eingabe-Pruefen SECTION.
   MOVE 0 TO Fehler-KZ.
   MOVE 0 TO Feldzahl.
   MOVE SPACES TO Fehler-Text.
   UNSTRING Personen-Nummer 
      DELIMITED BY ALL "-" OR ALL "." OR ALL " "
      INTO Geb-Code  DELIMITER IN Tr1 COUNT IN Anz1
           Nam-Code  DELIMITER IN Tr2 COUNT IN Anz2
           Pers-Code DELIMITER IN Tr3 COUNT IN Anz3
      TALLYING IN Feldzahl
      ON OVERFLOW 
         MOVE 1 TO Fehler-KZ
         MOVE "Angebene Nummer ist zu lang!" TO Fehler-Text
   END-UNSTRING

   IF Fehler-KZ = 0
      IF Tr1 NOT = "-" OR Tr2 NOT = "."
         MOVE 1 TO Fehler-KZ
         MOVE "Trennzeichenfehler." TO Fehler-Text
      END IF

      IF Anz1 NOT = 8
         MOVE 1 TO Fehler-KZ
         MOVE "Nummernanfang falsch angeben." TO Fehler-Text
      END IF

      IF Anz2 NOT = 3          MOVE 1 TO Fehler-KZ
         MOVE "Nummernmitte falsch angeben." TO Fehler-Text
      END IF

      IF Anz3 NOT = 9
         MOVE 1 TO Fehler-KZ
         MOVE "Nummernende falsch angeben." TO Fehler-Text
      END IF

      IF Feldzahl NOT = 3
         MOVE 1 TO Fehler-KZ
         MOVE "Nummernformat falsch." TO Fehler-Text
      END IF
   END IF

   IF Fehler-KZ  = 1
      DISPLAY Fehler-Text AT 0302.
      ACCEPT Warten AT 0332.
      GOTO Eingabe.
   ELSE
      ADD 1 TO Anmeldezahl
      GOTO Bin-Drin
   END IF

             :

Bin-Drin SECTION.
             :

Erklärung:
Wie man sieht, kann man verschiedene Zusätze anbringen. Im folgenden werden sie daher nach ihrem Auftreten bzw. nach dem Vorkommen im Syntax behandelt:

DELIMITED BY-Zusatz:
Hinter diesem Zusatz werden die Trennzeichen angegeben. Die Trennzeichen dürfen beliebig lang sein (auch wenn sie hier nur aus einem Zeichen bestehen). Damit man nicht nur ein Trennzeichen verwenden darf, kann man hinter OR noch weitere Trennzeichen definieren. Die Übertragung der Zeichen findet bis zum Auftreten eines der definierten Trennzeichen statt. Die Trennzeichen selber werden nicht übertragen.

ALL-Zusatz:
Wenn ALL angegeben wird, so werden alle direkt hintereinander liegenden Trennzeichen wie ein Trennzeichen behandelt. Fehlt dieser Zusatz, so wird jedes Trennzeichen dabei für sich betrachtet. Da zwischen den Trennzeichen dann nichts liegt, was übertragbar wäre, werden die entsprechenden Empfangsfelder mit Leerzeichen bzw. Null (je nach Feldtyp) aufgefüllt.

DELIMITER IN-Zusatz:
Wurde der DELIMITED BY-Zusatz vervendet, so kann hinter den einzelnen Empfangsfeldern mit Hilfe dieses Zusatzes ein Feld angegeben werden, in den der angetroffene Begrenzer (Trennzeichen) übertragen wird (im Beispiel Tr1 bis Tr3).

COUNT IN-Zusatz:
Wird dieser Zusatz verwendet, so wird die Anzahl der übertragenen Zeichen in das hinter diesem Zusatz angegebene Feld 'gezählt' (im Beispiel Anz1 bis Anz3).

WITH POINTER-Zusatz:
Hier kann eine Variable angegeben werden, die den Startpunkt innerhalb des Sendefeldes angibt. Eine Übertragung von Daten aus diesem Sendefeld beginnt dann erst ab der angegebenen Stelle.

TALLYING IN-Zusatz:
Wird dieser Zusatz verwendet, so wird mit jeder Übertragung eines Feldes der, hinter diesem Zusatz angegebene Zähler um 1 erhöht. Die UNSTRING-Anweisung nimmt keine Initialisierung dieses Zählers vor, daher wird er im Beispiel zu Anfang auch auf 0 gesetzt.

ON OVERFLOW-Zusatz:
Sind alle Empfangsfelder gemäß der UNSTRING-Anweisung gefüllt worden und im Sendefeld sind noch Zeichen übrig (aus welchen Gründen auch immer) so können hinter diesem Zusatz Anweisungen angegeben werden, die in diesem Fall zur Ausführung gelangen.
Anweisungen die hinter NOT ON OVERFLOW angegeben werden, werden dem entsprechend ausgeführt, wenn es bei der 'Operation' zu keinem Overflow kam.

...