SEPARATE
|
operand1 | |||||
SUBSTRING (operand1,operand2,operand3)
|
||||||
[[STARTING ]
FROM [POSITION ] operand8]
|
||||||
[LEFT [JUSTIFIED ]] INTO
operand4
|
||||||
IGNORE
|
||||||
REMAINDER
operand5
|
||||||
REMAINDER
POSITION operand9
|
||||||
WITH [RETAINED ]
|
[ANY ]
DELIMITERS
|
|||||
INPUT DELIMITERS
|
||||||
DELIMITERS
operand6
|
||||||
[[GIVING ]
NUMBER [IN ] operand7]
|
Dieses Dokument behandelt folgende Themen:
Eine Erläuterung der in dem Syntax-Diagramm verwendeten Symbole entnehmen Sie dem Abschnitt Syntax-Symbole.
Verwandte Statements: COMPRESS
|
COMPUTE
|
EXAMINE
|
MOVE
|
MOVE ALL
|
RESET
Gehört zur Funktionsgruppe: Arithmetische Funktionen und Datenzuweisungen
Das Statement SEPARATE
dient dazu, den Inhalt eines
alphanumerischen oder binären Operanden auf zwei oder mehr alphanumerische oder
binäre Operanden (oder auf mehrere Ausprägungen eines alphanumerischen oder
binären Arrays) zu verteilen.
Operanden-Definitionstabelle:
Operand | Mögliche Struktur | Mögliche Formate | Referenzierung erlaubt | Dynam. Definition | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
operand1
|
C | S | A | A | U | B | ja | nein | ||||||||||||
operand2
|
C | S | N | P | I | B* | ja | nein | ||||||||||||
operand3
|
C | S | N | P | I | B* | ja | nein | ||||||||||||
operand4
|
S | A | G | A | U | B | ja | ja | ||||||||||||
operand5
|
S | A | U | B | ja | ja | ||||||||||||||
operand6
|
C | S | A | U | B | ja | nein | |||||||||||||
operand7
|
S | N | P | I | ja | ja | ||||||||||||||
operand8 |
C | S | N | P | I | ja | nein | |||||||||||||
operand9 |
S | N | P | I | ja | yes |
* Format B von operand2 und operand3 können nur mit einer Länge von kleiner gleich 4 benutzt werden.
Syntax-Element-Beschreibung:
Syntax-Element | Beschreibung |
---|---|
operand1
|
Ausgangsoperand:
operand1 ist die alphanumerische/binäre Konstante oder Variable, deren Inhalt aufgeteilt werden soll. Nachgestellte Leerzeichen in operand1
werden entfernt, bevor der Wert verarbeitet wird (auch wenn das Leerzeichen als
Begrenzungszeichen verwendet wird; vgl. |
SUBSTRING
|
SUBSTRING-Option:
Normalerweise wird der ganze Inhalt des Feldes aufgeteilt, und zwar vom Anfang des Feldes an. Die Normalerweise wird der ganze Inhalt des Feldes aufgeteilt, und zwar vom Anfang des Feldes an. Anmerkung: |
STARTING FROM POSITION
operand8 |
STARTING FROM POSITION-Option:
Diese Option bestimmt die Startposition des aufzuteilenden
Ausgangsoperanden ( Weitere Informationen siehe Bereiche für STARTING FROM POSITION festlegen. |
LEFT
JUSTIFIED
|
LEFT JUSTIFIED-Option:
Diese Option bewirkt, dass den aufgeteilten Feldwertteilen vorangestellte Leerzeichen aus den Zieloperanden entfernt werden. |
operand4
|
Zieloperand:
operand4 enthält die Zieloperanden, die die Teile des Ausgangsoperanden aufnehmen sollen. Wird als Zieloperand ein Array verwendet, wird es Ausprägung für Ausprägung mit den übertragenen Feldwertteilen gefüllt. Die Anzahl der Zieloperanden entspricht der Anzahl der Begrenzungszeichen (einschließlich nachgestellter Begrenzungszeichen) in operand1, plus 1. Ist operand4 eine dynamische Variable,
kann deren Länge mit der Allgemeine Informationen zu dynamischen Variablen finden Sie im Abschnitt Dynamische und große Variablen benutzen im Leitfaden zur Programmierung. |
IGNORE /
|
IGNORE/REMAINDER-Optionen:
Wenn Sie nicht genug Zieloperanden angeben, um alle Feldwertteile aufzunehmen, erhalten Sie eine entsprechende Fehlermeldung. Um dies zu vermeiden, haben Sie zwei Möglichkeiten:
Siehe auch Regeln und operative Aspekte und Beispiel 3. |
REMAINDER POSITION
operand9 |
REMAINDER POSITION-Option:
Der von der Weitere Informationen siehe Regeln und operative Aspekte. |
DELIMITERS |
DELIMITERS-Option: Siehe
Delimiters-Option
weiter unten.
|
RETAINED
|
RETAINED-Option:
Normalerweise werden die Begrenzungszeichen selbst nicht mit in die Zieloperanden übertragen. Wenn Sie allerdings Beispiel: Das folgende ... MOVE '150+30' TO #A SEPARATE #A INTO #B #C #D WITH RETAINED DELIMITER '+' ... Siehe auch Beispiel 3. |
GIVING
NUMBER operand7
|
GIVING NUMBER-Option
Diese Option bewirkt, dass die Anzahl der Zieloperanden, die mit einem Wert gefüllt wurden (einschließlich der mit Leerzeichen gefüllten), in operand7 ausgegeben wird. Die Anzahl, die Sie erhalten, errechnet sich aus der Anzahl der Delimiterzeichen plus 1. Wenn Sie die Wenn Sie die REMAINDER-Option verwenden, enthält operand7 maximal die Anzahl der Zieloperanden (operand4) plus operand5. |
Begrenzungszeichen innerhalb von operand1 bestimmen die Stellen, an denen der Wert geteilt werden soll.
WITH [RETAINED ]
|
[ANY ]
DELIMITERS
|
||||
INPUT DELIMITERS
|
|||||
DELIMITERS operand6
|
Syntax-Element-Beschreibung:
Syntax-Element | Beschreibung |
---|---|
WITH [ANY]
DELIMITERS |
Falls Sie die DELIMITERS -Option
nicht angeben (oder WITH ANY DELIMITER angeben), wird jedes
Leerzeichen sowie jedes Zeichen, das weder ein Buchstabe noch eine Ziffer ist,
als Begrenzungszeichen interpretiert.
Die Definition des Begrenzungszeichens kann mit dem Profilparameter
|
WITH INPUT
DELIMITERS |
Bedeutet, dass das mit dem Session-Parameter
ID definierte
Zeichen sowie das Leerzeichen als Begrenzungszeichen gelten.
|
WITH
DELIMITERS operand6 |
Bedeutet, dass jedes der angegebenen Zeichen
(operand6) als Begrenzungszeichen interpretiert
wird.
Wenn operand6 nachgestellte Leerzeichen enthält, werden diese ignoriert. |
Nachgezogene Leerstellen in Ausgangsfeldern (und auch in einzelnen
Werten und Array-Ausprägungen) werden ignoriert, wenn der Aufteilungsvorgang
beginnt. Nachgezogene Leerstellen zählen nur dann, wenn der REMAINDER
POSITION
-Wert berechnet wird. Siehe auch
Rückgabewert der
REMAINDER POSITION-Klausel.
Ist das Ausgangsfeld (operand1
)
ein leeres dynamisches Feld (*LENGTH=0
) oder ein X-Array, das
nicht erweitert wird, beendet das SEPARATE
-Statement die
Ausführung nach Rücksetzen folgender Felder:
alle Zielfelder
(operand4
);
das Feld (operand7
), welches
die Anzahl der gefüllten Zielfelder zurückgibt;
das REMAINDER
-Datenfeld
(operand5
);
das REMAINDER POSITION
-Feld
(operand9
).
Dasselbe gilt, wenn das Ausgangsfeld nur Leerstellen enthält.
Der zulässige Wertebereich für
operand8
in der STARTING FROM
POSITION
-Klausel ist 1:n
. Dabei
ist n
das letzte Byte des
Ausgangsfeldes.
Falls es sich bei dem Ausgangsfeld
(operand1
) um ein Array handelt, werden
alle Ausprägungen, einschließlich der nachgezogenen Leerstellen, gezählt. Bei
einem dynamischen Arry wird die Länge jedes Einzelfeldes bis zur angegebenen
Position gezählt.
Beispiele für operand8
:
Position 63 in #A (A100) |
ist das the 63. Zeichen in
#A .
|
Position 63 in #B
(A20/1:10) |
ist das dritte Zeichen in
#B(4 ).
|
Position 63 in #C
(A10/1:3,1:4) |
ist das dritte Zeichen in
#C(2,3) .
|
Position 63 in |
ist das 23. Zeichen in
#D(4) .
|
Bei Angabe eines ungültigen Wertebereichs (ein negativer Wert oder ein
Null-Wert oder ein Wert, der größer als die tatsächliche Feldlänge ist) werden
die im Abschnitt Verarbeitung von Ausgangs- und
Zielfeldern aufgeführten Rückgabefelder zurückgesetzt,
jedoch tritt kein Laufzeitfehler auf. Da der STARTING FROM
-Wert
eine Position (und keinen Versatz) angibt, wird in
operand8
ein Mindestwert von
1
für die erste Ausführung benötigt.
Der von der REMAINDER POSITION
-Klausel zurückgegebene Wert
entspricht der Position, ab der ein REMAINDER
-Datenfeld gefüllt
wird.
Beispiel:
... SEPARATE 'AB CD' INTO #A REMAINDER #R ...
Dieses Statement gibt #A= 'AB'
und #R= ' CD'
zurück, weil der REMAINDER
nach dem Trennzeichen (hier:
Leerzeichen) unmittelbar nach AB
beginnt. Verwendet man
stattdessen die REMAINDER POSITION
-Option, wird der Wert
4
zurückgegeben.
Zwar werden nachgezogene Leerstellen während des Trennvorgangs
ignoriert, aber bei der Berechnung des REMAINDER POSITION
-Wertes
werden sie bei den Ausprägungen eines Array-Ausgangsfeldes berücksichtigt.
Wenn alle Ausgangsfeldabschnitte verarbeitet sind und das Ende des
Ausgangsfelds erreicht ist, gibt die REMAINDER POSITION
-Klausel
den Wert Null zurück, was besagt, dass keine weiteren Daten mehr vorhanden
sind.
Siehe auch Beispiel 6 - Verwendung eines Array-Ausgangsfeldes mit den Optionen STARTING FROM und REMAINDER POSITION.
Bei der Ausführung des SEPARATE
-Statements werden die
Ausgangsdaten normalerweise kopiert und aus einem Arbeitsfeld verarbeitet.
Deshalb ist das REMAINDER
-Ergebnis unabhängig von möglicherweise
überlappenden Ausgangs- und Ergebnis-(INTO-)Feldern
Solche Feld-Sicherungskopien werden bei Verwendung einer
REMAINDER POSITION
-Klausel nicht erstellt. Der gesamte
Trennvorgang arbeitet unabhängig davon, ob Sie den Ausgangs- und den
Zieloperanden trennen, mit dem ursprünglichen Ausgangsoperanden.
Operandenüberlappung werden weder beim Kompilieren noch bei der Ausführung
zurückgewiesen, können aber zu unerwünschten Ergebnissen führen.
Wenn Sie ein Feld mit einem einzelnen Wert aufteilen, begrenzt die Feldgrenze immer das letzte Wort. Dies gilt ebenfalls bei jeder einzelnen Ausprägung eines Array-Feldes. Das bedeutet, dass das folgende Einzel-Statement dasselbe bewirkt wie die Statement-Sequenz:
Bei Verwendung der RETAINED DELIMITERS
-Option werden die
Begrenzungszeichen ebenfalls in das Zielfeld gestellt. Dies gilt nur bei
Begrenzungszeichen innerhalb einer Array-Ausprägung und nicht bei aufeinander
folgenden Array-Ausprägungen, welche automatisch (ohne Begrenzungszeichen)
begrenzt werden, wenn eine Ausprägung endet.
Siehe auch Beispiel 4 - Verwendung eines Array-Ausgangsfeldes einer redefinierten Zeichenkette und Beispiel 5 - Verwendung eines Array-Ausgangsfeldes mit RETAIN-Option.
Beispiel 1 — Verschiedene Beispiele für den Gebrauch des SEPARATE-Statements
Example 4 - Beispiel 4 - Verwendung eines Array-Ausgangsfeldes einer redefinierten Zeichenkette
Beispiel 5 - Verwendung eines Array-Ausgangsfeldes mit RETAIN-Option
** Example 'SEPEX1': SEPARATE ************************************************************************ DEFINE DATA LOCAL 1 #TEXT1 (A6) INIT <'AAABBB'> 1 #TEXT2 (A7) INIT <'AAA BBB'> 1 #TEXT3 (A7) INIT <'AAA-BBB'> 1 #TEXT4 (A7) INIT <'A.B/C,D'> 1 #FIELD1A (A6) 1 #FIELD1B (A6) 1 #FIELD2A (A3) 1 #FIELD2B (A3) 1 #FIELD3A (A3) 1 #FIELD3B (A3) 1 #FIELD4A (A3) 1 #FIELD4B (A3) 1 #FIELD4C (A3) 1 #FIELD4D (A3) 1 #NBT (N1) 1 #DEL (A5) END-DEFINE * WRITE NOTITLE 'EXAMPLE A (SOURCE HAS NO BLANKS)' SEPARATE #TEXT1 INTO #FIELD1A #FIELD1B GIVING NUMBER #NBT WRITE / '=' #TEXT1 5X '=' #FIELD1A 4X '=' #FIELD1B 4X '=' #NBT * WRITE NOTITLE /// 'EXAMPLE B (SOURCE HAS EMBEDDED BLANK)' SEPARATE #TEXT2 INTO #FIELD2A #FIELD2B GIVING NUMBER #NBT WRITE / '=' #TEXT2 4X '=' #FIELD2A 7X '=' #FIELD2B 7X '=' #NBT * WRITE NOTITLE /// 'EXAMPLE C (USING DELIMITER ''-'')' SEPARATE #TEXT3 INTO #FIELD3A #FIELD3B WITH DELIMITER '-' WRITE / '=' #TEXT3 4X '=' #FIELD3A 7X '=' #FIELD3B * MOVE ',/' TO #DEL WRITE NOTITLE /// 'EXAMPLE D USING DELIMITER' '=' #DEL * SEPARATE #TEXT4 INTO #FIELD4A #FIELD4B #FIELD4C #FIELD4D WITH DELIMITER #DEL WRITE / '=' #TEXT4 4X '=' #FIELD4A 7X '=' #FIELD4B / 19X '=' #FIELD4C 7X '=' #FIELD4D * END
Ausgabe des Programms SEPEX1
:
EXAMPLE A (SOURCE HAS NO BLANKS) #TEXT1: AAABBB #FIELD1A: AAABBB #FIELD1B: #NBT: 1 EXAMPLE B (SOURCE HAS EMBEDDED BLANK) #TEXT2: AAA BBB #FIELD2A: AAA #FIELD2B: BBB #NBT: 2 EXAMPLE C (USING DELIMITER '-') #TEXT3: AAA-BBB #FIELD3A: AAA #FIELD3B: BBB EXAMPLE D USING DELIMITER #DEL: ,/ #TEXT4: A.B/C,D #FIELD4A: A.B #FIELD4B: C #FIELD4C: D #FIELD4D:
** Example 'SEPEX2': SEPARATE (using array variable) ************************************************************************ DEFINE DATA LOCAL 1 #INPUT-LINE (A60) INIT <'VALUE1, VALUE2,VALUE3'> 1 #FIELD (A20/1:5) 1 #NUMBER (N2) END-DEFINE * SEPARATE #INPUT-LINE LEFT JUSTIFIED INTO #FIELD (1:5) GIVING NUMBER IN #NUMBER * WRITE NOTITLE #INPUT-LINE // #FIELD (1) / #FIELD (2) / #FIELD (3) / #FIELD (4) / #FIELD (5) / #NUMBER * END
Ausgabe des Programms SEPEX2
:
VALUE1, VALUE2,VALUE3 VALUE1 VALUE2 VALUE3 3
** Example 'SEPEX3': SEPARATE (with REMAINDER, RETAIN option) ************************************************************************ DEFINE DATA LOCAL 1 #INPUT-LINE (A60) INIT <'VAL1, VAL2, VAL3,VAL4'> 1 #FIELD (A10/1:4) 1 #REM (A30) END-DEFINE * WRITE TITLE LEFT 'INP:' #INPUT-LINE / '#FIELD (1)' 13T '#FIELD (2)' 25T '#FIELD (3)' 37T '#FIELD (4)' 49T 'REMAINDER' / '----------' 13T '----------' 25T '----------' 37T '----------' 49T '------------------------------' * SEPARATE #INPUT-LINE INTO #FIELD (1:2) REMAINDER #REM WITH DELIMITERS ',' WRITE #FIELD(1) 13T #FIELD(2) 25T #FIELD(3) 37T #FIELD(4) 49T #REM * RESET #FIELD(*) #REM SEPARATE #INPUT-LINE INTO #FIELD (1:2) IGNORE WITH DELIMITERS ',' WRITE #FIELD(1) 13T #FIELD(2) 25T #FIELD(3) 37T #FIELD(4) 49T #REM * RESET #FIELD(*) #REM SEPARATE #INPUT-LINE INTO #FIELD (1:4) IGNORE WITH RETAINED DELIMITERS ',' WRITE #FIELD(1) 13T #FIELD(2) 25T #FIELD(3) 37T #FIELD(4) 49T #REM * RESET #FIELD(*) #REM * SEPARATE SUBSTRING(#INPUT-LINE,1,50) INTO #FIELD (1:4) IGNORE WITH DELIMITERS ',' WRITE #FIELD(1) 13T #FIELD(2) 25T #FIELD(3) 37T #FIELD(4) 49T #REM * END
Ausgabe des Programms SEPEX3
:
INP: VAL1, VAL2, VAL3,VAL4 #FIELD (1) #FIELD (2) #FIELD (3) #FIELD (4) REMAINDER ---------- ---------- ---------- ---------- ------------------------------ VAL1 VAL2 VAL3,VAL4 VAL1 VAL2 VAL1 , VAL2 , VAL1 VAL2 VAL3 VAL4
** Example 'SEPEX4': SEPARATE with source array ************************************************************************ * This example shows different results when separating a scalar string * or a string array redefining the scalar string. * * ************************************************************************ * * DEFINE DATA LOCAL 1 #TEXT (A24) INIT <'VAL1 VAL2 VAL3 VAL4 VAL5'> 1 REDEFINE #TEXT 2 #TEXTARRAY (A12/2) 1 #WORD1(A5/6) 1 #WORD2(A5/6) END-DEFINE * SEPARATE #TEXT INTO #WORD1(*) /* Redefinition may split original words into two parts SEPARATE #TEXTARRAY(*) INTO #WORD2(*) * DISPLAY #TEXT #WORD1(*) #TEXTARRAY(*) #WORD2(*) END
Ausgabe des Programms SEPEX4
:
#TEXT #WORD1 #TEXTARRAY #WORD2 ------------------------ ------ ------------ ------ VAL1 VAL2 VAL3 VAL4 VAL5 VAL1 VAL1 VAL2 VA VAL1 VAL2 L3 VAL4 VAL5 VAL2 VAL3 VA VAL4 L3 VAL5 VAL4 VAL5
** Example 'SEPEX5': SEPARATE with and without RETAINED DELIMITERS *********************************************************************** * This example shows different results with a source array * when using the option RETAINED DELIMITERS or not. * * *********************************************************************** * * DEFINE DATA LOCAL 1 #TEXT(A20) INIT <'VAL1,VAL2,VAL3,VAL4'> 1 #TEXTARRAY(A10/3) INIT <'VAL1,VAL2', 'VAL3', 'VAL4'> 1 #WORD1(A5/7) 1 #WORD2(A5/7) END-DEFINE * SEPARATE #TEXT INTO #WORD1(*) SEPARATE #TEXTARRAY(*) INTO #WORD2(*) DISPLAY #TEXT #WORD1(*) #TEXTARRAY(*) #WORD2(*) * SEPARATE #TEXT INTO #WORD1(*) WITH RETAINED DELIMITERS SEPARATE #TEXTARRAY(*) INTO #WORD2(*) WITH RETAINED DELIMITERS DISPLAY #TEXT #WORD1(*) #TEXTARRAY(*) #WORD2(*) * END
Ausgabe des Programms SEPEX5
:
#TEXT #WORD1 #TEXTARRAY #WORD2 -------------------- ------ ---------- ------ VAL1,VAL2,VAL3,VAL4 VAL1 VAL1,VAL2 VAL1 VAL2 VAL3 VAL2 VAL3 VAL4 VAL3 VAL4 VAL4 VAL1,VAL2,VAL3,VAL4 VAL1 VAL1,VAL2 VAL1 , VAL3 , VAL2 VAL4 VAL2 , VAL3 VAL3 VAL4 , VAL4
** Example 'SEPEX6': SEPARATE with STARTING FROM and REMAINDER POSITION ************************************************************************ * This example shows how the options STARTING FROM POSITION and * REMAINDER POSITION work together in a processing loop when * separating a source array. * ************************************************************************ * * DEFINE DATA LOCAL 1 #TEXT (A15/1:3) INIT <'VAL1 VAL2', 'VAL3', 'VAL4 VAL5 VAL6'> 1 #WORD (A5/1:4) 1 #POS (I1) INIT <1> END-DEFINE * WRITE '#TEXT(A15/1:3): (1) (2) (3)' / 16T #TEXT(*) / 16T '----+----1----+ ----2----+----3 ----+----4----+' // '#WORD (A5/1:4): (1) (2) (3) (4) : #POS' '(within #TEXT(*))' * REPEAT SEPARATE #TEXT(*) STARTING FROM POSITION #POS INTO #WORD(*) REMAINDER POSITION #POS WRITE 16T #WORD(*) 44T ': ' #POS UNTIL #POS = 0 END-REPEAT END
Ausgabe des Programms SEPEX6
:
#TEXT(A15/1:3): (1) (2) (3) VAL1 VAL2 VAL3 VAL4 VAL5 VAL6 ----+----1----+ ----2----+----3 ----+----4----+ #WORD (A5/1:4): (1) (2) (3) (4) : #POS (within #TEXT(*)) VAL1 VAL2 VAL3 VAL4 : 36 VAL5 VAL6 : 0