Die STRING-Anweisung

Mit Hilfe dieses Befehls kann man mehrere Datenfelder zu einem zusammenfassen. Vorraussetzung hierfür ist jedoch, daß es sich um ein alphanumerisches Datenfeld handelt, in den diese Zusammenfassung erfolgen soll. Dieses alphanumerische Empfangsfeld darf weder unter Verwendung von Druckaufbereitungszeichen noch der JUSTIFIED-Klausel beschrieben worden sein.
Nehmen wir an, es liegt eine Datenerfassung in Dialogform vor. Auf der Grundlage einer Bildschirmmaske sollen Daten eingegeben werden. Jedes Datenfeld (Name, Vorname etc.) hat dabei eine bestimmte vorgegebene Größe.
Neben einer weiteren Verarbeitung der eingegebenen Daten, soll jeweils eine Druckzeile aus den Daten erzeugt werden, die als Protokollzeile nach jeder Datenerfassung auf einer Liste am Drucker ausgegeben werden soll.
Legen wir in der WORKING-STORAGE SECTION die folgende Datenfelddefinition zugrunde:

            :
            :
01 Eingabefelder.
  05 Name    PIC X(15) VALUE SPACES.
  05 Vorname PIC X(15) VALUE SPACES.
  05 Strasse PIC X(20) VALUE SPACES.
  05 PLZ     PIC X(5)  VALUE SPACES.
  05 Ort     PIC X(20) VALUE SPACES.

01 Druckzeile PIC X(80) VALUE SPACES.

            :

Bei so einer Liste sollten alle Eintäge gleichen Inhaltes in Spalten schön untereinander stehen. Daher ist es hier angebracht, die Datenfelder in voller Länge an die Druckzeile zu übergeben. Zwischen die einzelnen Daten wird jeweils ein Stern (*) gesetzt. Die entsprechende STRING-Anweisung müßte dann so formuliert werden:
.
        :
        
STRING Name, "*",
      Vorname, "*",
      Strasse, "*",
      PLZ, "*",
      Ort, " "
      DELIMITED BY SIZE
      INTO Druckzeile
END-STRING.

        :

DELIMITED BY-Zusatz
Mit Hilfe dieses Zusatzes kann bestimmt werden, durch was die Übertagung begrenzt (delimitation=Abgrenzung) werden soll. In dem Beispiel werden die Sendefelder in voller Länge in das Empfangsfeld übertragen, da so Spalten entstehen. Es wurde also gesagt: Fasse die Sendefelder Name, Vorname, ... jeweils durch das Zeichen "*" getrennt im Empfangsfeld Druckzeile zusammen, wobei die Gesamtlänge (DELIMITED BY SIZE) der Sendefelder erhalten bleiben soll.
Verändern wir unser Beispiel so, daß die Druckzeile nichtmehr an den Drucker ausgegeben werden soll, sondern diese 'Protokollzeilen' sollen in einer sequentiellen Protokolldatei abgelegt werden. In einem solchen Fall ist es nicht wichtig, daß die Eintäge alle in Spalten untereinander stehen. Hier sollen die Daten kompakt hintereinander geschrieben werden, ohne daß dabei Platz für Leerzeichen verschwendet werden soll. Als Trenn-Kennzeichen wird wieder der Stern (*) verwendet. Man würde dann codieren:

WORKING-STORAGE SECTION.
           :
           
01 Eingabefelder.
  05 Name    PIC X(15) VALUE SPACES.
  05 Vorname PIC X(15) VALUE SPACES
  05 Strasse PIC X(20) VALUE SPACES.
  05 PLZ     PIC X(5)  VALUE SPACES.
  05 Ort     PIC X(20) VALUE SPACES.

01 Trenn-KZ   PIC XX    VALUE SPACES.

01 Druckzeile PIC X(80).

           :

           :
           
PROCEDURE DIVISION.

           :
           
  STRING Name, "*",
         Vorname, "*",
         Strasse, "*",
         PLZ, "*",
         Ort, " "
         DELIMITED BY Trenn-KZ
         INTO Druckzeile
  END-STRING.
  
           :

Hier werden die Sendefelder auf das Vorkommen von zwei hintereinander liegenden Leerzeichen (Trenn-KZ) untersucht. Werden diese Leerzeichen entdeckt, so wird der Inhalt des entsprechenden Sendefeldes bis zu diesen zwei Leerzeichen in das Empfangsfeld übertragen. Hinter DELIMITED BY kann auch ein Literal angegeben werden.
Vorsicht: Der nicht gefüllte Teil des Empfangsfeldes wird nicht neu belegt. Wird das Feld 'Druckzeile' beim nächsten mal 'befüllt', so wird nur der Teil neu belegt, der benötigt wird. Wurden beim ersten 'befüllen' beispielsweise alle 80 Zeichen belegt und beim nächsten mal ergeben die Daten plus Trennzeichen (*) nur eine Länge von 55 Zeichen, so bleiben die letzten 25 Zeichen aus der ersten 'Befüllung' im Feld 'Druckzeile' erhalten. Es empfiehlt sich daher, das Empfangsfeld vor einer solchen Aktion mit Leerzeichen zu füllen oder sonstwie zu initialisieren.

WITH POINTER
Man kann mit Hilfe dieses Zusatzes bestimmen, ab wann der Übertrag in das Empfangsfeld beginnen soll. Wird der Zusatz weggelassen, so beginnt der Übertrag an der ersten Stelle. Der Pointer wird während der Aktion mitgezählt, sodaß man über das angegebene numerische Datenfeld die Anzahl der bisher übergebenen Zeichen abfragen kann.

WORKING-STORAGE SECTION.

            :
            
01 Eingabefelder.
  05 Name    PIC X(15) VALUE SPACES.
  05 Vorname PIC X(15) VALUE SPACES
  05 Strasse PIC X(20) VALUE SPACES.
  05 PLZ     PIC X(5)  VALUE SPACES.
  05 Ort     PIC X(20) VALUE SPACES.

01 Position  PIC 99.

01 Trenn-KZ   PIC XX    VALUE SPACES.

01 Druckzeile PIC X(80).

            :

            :
            
PROCEDURE DIVISION.

            :
            
  MOVE 1 TO Position.

  STRING Name, "*",
         Vorname, "*",
         Strasse, "*",
         PLZ, "*",
         Ort, " "
         DELIMITED BY Trenn-KZ
         INTO Druckzeile
         WITH POINTER Position
  END-STRING.
  
            :
            

Es ist darauf zu achten, daß nach der STRING-Anweisung der Pointer 'Position' auf der letzten übertragenen Stelle plus Eins steht. Will man also die Anzahl der bisher übertragenen Zeichen abfragen, so müßte man von 'Position', 1 abziehen.

OVERFLOW
Es ist natürlich möglich, daß das Empfangsfeld zu klein definiert ist, um alle Daten der Sendefelder aufzunehmen. Damit dann nicht das blanke Chaos losbricht, gibt es diesen Zusatz. Tritt ein Überlauf ein, so wird die Anweisung, die dann angegeben wurde, ausgeführt. Das geht natürlich nur, wenn man den OVERFLOW-Zusatz auch verwendet.

WORKING-STORAGE SECTION.

             :

01 Warten PIC X.

01 Eingabefelder.
  05 Name    PIC X(15) VALUE SPACES.
  05 Vorname PIC X(15) VALUE SPACES.
  05 Strasse PIC X(20) VALUE SPACES.
  05 PLZ     PIC X(5)  VALUE SPACES.
  05 Ort     PIC X(20) VALUE SPACES.

01 Position  PIC 99.
01 Trenn-KZ   PIC XX    VALUE SPACES.

01 Druckzeile PIC X(80).

             :

             :


PROCEDURE DIVISION.

             :

  MOVE 1 TO Position.

  STRING Name, "*",
         Vorname, "*",
         Strasse, "*",
         PLZ, "*",
         Ort, " "
         DELIMITED BY Trenn-KZ
         INTO Druckzeile
         WITH POINTER Position
         ON OVERFLOW 
            DISPLAY "Zu viele Zeichen!" AT 0520
            ACCEPT Warten AT 0538
            PERFORM Kuerzen
  END-STRING.

             :

Kuerzen SECTION.

             :

Hier würde also für den Fall eines Überlaufes das Unterprogramm Kuerzen ausgeführt, nachdem es zu einer entsprechenden Meldung kam. Man kann auch mit Hilfe von NOT ON OVERFLOW bestimmen, ob eine Anweisungsfolge bei erfolgreicher 'Befüllung' ausgeführt werden soll, bevor das Programm mit den, auf END-STRING folgenden Anweisungen, fortgesetzt wird.

...