Dieses Dokument beschreibt, wie die Ausführung eines Statements von einem Gruppenwechsel abhängig gemacht werden kann, und wie Gruppenwechsel für die Auswertung von Natural-Systemfunktionen benutzt werden können.
Folgende Themen werden behandelt:
Ein Gruppenwechsel (Break) findet statt, wenn der Wert eines Kontrollfeldes sich ändert.
Die Ausführung von Statements kann von einem solchen Gruppenwechsel abhängig gemacht werden.
Ein Gruppenwechsel kann auch zur Auswertung von Natural-Systemfunktionen verwendet werden.
Systemfunktionen werden im Abschnitt Systemvariablen und Systemfunktionen behandelt. Genauere Beschreibungen der verfügbaren Systemfunktionen System finden Sie in der Systemfunktionen-Dokumentation.
Mit dem Statement AT
BREAK können Sie eine Verarbeitung angeben, die immer dann
ausgeführt werden soll, wenn ein Gruppenwechsel erfolgt, d.h. wenn der Wert
eines Kontrollfeldes, das Sie im AT BREAK-Statement angeben, sich
ändert. Als Kontrollfeld können Sie ein Datenbankfeld oder eine
Benutzervariable verwenden.
In diesem Abschnitt werden folgende Themen behandelt:
Das Feld, welches als Kontrollfeld in einem
AT BREAK-Statement
angegeben wird, ist üblicherweise ein Datenbankfeld.
Beispiel:
... AT BREAK OF DEPT statements END-BREAK ...
In diesem Beispiel ist das Datenbankfeld DEPT das
Kontrollfeld; wechselt der Wert des Feldes, beispielsweise von
SALE01 auf SALE02, würde dies die Ausführung der im
AT BREAK-Statement angegebenen Statements auslösen.
Es ist auch möglich, statt eines ganzen Feldes nur einen Teil eines
Feldes als Kontrollfeld zu nehmen. Mit der Notation /n/ können Sie
festlegen, dass nur die ersten /n/
Stellen eines Feldes auf einen Wertwechsel überprüft werden sollen.
Beispiel:
... AT BREAK OF DEPT /4/ statements END-BREAK ...
In diesem Beispiel würden die angegebenen Statements nur
ausgeführt, wenn sich der Wert der ersten 4 Stellen des Feldes
DEPT ändern würde, beispielsweise von SALE auf
TECH; ein Wechsel von SALE01 auf SALE02
hingegen würde ignoriert und der AT BREAK-Block nicht ausgeführt
werden.
** Example 'ATBREX01': AT BREAK OF (with database field)
************************************************************************
DEFINE DATA LOCAL
1 MYVIEW VIEW OF EMPLOYEES
2 NAME
2 CITY
2 COUNTRY
2 JOB-TITLE
2 SALARY (1:1)
END-DEFINE
*
READ (5) MYVIEW BY CITY WHERE COUNTRY = 'USA'
DISPLAY CITY (AL=9) NAME 'POSITION' JOB-TITLE 'SALARY' SALARY(1)
/*
AT BREAK OF CITY
WRITE / OLD(CITY) (EM=X^X^X^X^X^X^X^X^X^X^X^)
5X 'AVERAGE:' T*SALARY AVER(SALARY(1)) //
COUNT(SALARY(1)) 'RECORDS FOUND' /
END-BREAK
/*
AT END OF DATA
WRITE 'TOTAL (ALL RECORDS):' T*SALARY(1) TOTAL(SALARY(1))
END-ENDDATA
END-READ
END
Im obigen Programm wird das erste WRITE-Statement ausgeführt, wenn
der Wert des Feldes CITY sich ändert.
Im AT BREAK-Statement werden die Systemfunktionen
OLD,
AVER und
COUNT
ausgewertet (und in dem WRITE-Statement ausgegeben).
In dem AT END OF
DATA-Statement wird die Systemfunktion
TOTAL
ausgewertet.
Das Programm ATBREX01 erzeugt folgende Ausgabe:
Page 1 04-12-14 14:07:26
CITY NAME POSITION SALARY
--------- -------------------- ------------------------- ----------
AIKEN SENKO PROGRAMMER 31500
A I K E N AVERAGE: 31500
1 RECORDS FOUND
ALBUQUERQ HAMMOND SECRETARY 22000
ALBUQUERQ ROLLING MANAGER 34000
ALBUQUERQ FREEMAN MANAGER 34000
ALBUQUERQ LINCOLN ANALYST 41000
A L B U Q U E R Q U E AVERAGE: 32750
4 RECORDS FOUND
TOTAL (ALL RECORDS): 162500
Auch eine Benutzervariable
kann als Kontrollfeld in einem AT
BREAK-Statement verwendet werden.
Im folgenden Programm wird die Benutzervariable #LOCATION
als Kontrollfeld verwendet.
** Example 'ATBREX02': AT BREAK OF (with user-defined variable and
** in conjunction with BEFORE BREAK PROCESSING)
************************************************************************
DEFINE DATA LOCAL
1 MYVIEW VIEW OF EMPLOYEES
2 CITY
2 COUNTRY
2 JOB-TITLE
2 SALARY (1:1)
*
1 #LOCATION (A20)
END-DEFINE
*
READ (5) MYVIEW BY CITY WHERE COUNTRY = 'USA'
BEFORE BREAK PROCESSING
COMPRESS CITY 'USA' INTO #LOCATION
END-BEFORE
DISPLAY #LOCATION 'POSITION' JOB-TITLE 'SALARY' SALARY (1)
/*
AT BREAK OF #LOCATION
SKIP 1
END-BREAK
END-READ
END
Ausgabe des Programms ATBREX02:
Page 1 04-12-14 14:08:36
#LOCATION POSITION SALARY
-------------------- ------------------------- ----------
AIKEN USA PROGRAMMER 31500
ALBUQUERQUE USA SECRETARY 22000
ALBUQUERQUE USA MANAGER 34000
ALBUQUERQUE USA MANAGER 34000
ALBUQUERQUE USA ANALYST 41000
Mit der Notation /n/ können
Sie, wie oben erläutert,
den Teil eines Feldes zum Kontrollfeld eines Gruppenwechsels machen. Sie können
auch mehrere AT
BREAK-Statements miteinander kombinieren, wobei bei einem
Gruppenwechsel ein ganzes Feld und bei einem anderen ein Teil dieses Feldes
Kontrollfeld ist.
In diesem Fall muss der übergeordnete Gruppenwechsel (ganzes Feld) vor
dem untergeordneten (Teil des Feldes) angegeben werden, d.h. im ersten AT
BREAK-Statement muss das ganze Feld, im zweiten das Teilfeld als
Kontrollfeld angegeben werden.
Das folgende Beispielprogramm zeigt dies anhand des Feldes
DEPT und den ersten 4 Stellen dieses Feldes (DEPT
/4/).
** Example 'ATBREX03': AT BREAK OF (two statements in combination)
************************************************************************
DEFINE DATA LOCAL
1 MYVIEW VIEW OF EMPLOYEES
2 NAME
2 JOB-TITLE
2 DEPT
2 SALARY (1:1)
2 CURR-CODE (1:1)
END-DEFINE
*
READ MYVIEW BY DEPT STARTING FROM 'SALE40' ENDING AT 'TECH10'
WHERE SALARY(1) GT 47000 AND CURR-CODE(1) = 'USD'
/*
AT BREAK OF DEPT
WRITE '*** LOWEST BREAK LEVEL ***' /
END-BREAK
AT BREAK OF DEPT /4/
WRITE '*** HIGHEST BREAK LEVEL ***'
END-BREAK
/*
DISPLAY DEPT NAME 'POSITION' JOB-TITLE
END-READ
END
Ausgabe des Programms ATBREX03:
Page 1 04-12-14 14:09:20
DEPARTMENT NAME POSITION
CODE
---------- -------------------- -------------------------
TECH05 HERZOG MANAGER
TECH05 LAWLER MANAGER
TECH05 MEYER MANAGER
*** LOWEST BREAK LEVEL ***
TECH10 DEKKER DBA
*** LOWEST BREAK LEVEL ***
*** HIGHEST BREAK LEVEL ***
Im folgenden Programm wird jedesmal, wenn sich der Wert des Feldes
DEPT ändert, eine Leerzeile ausgegeben; und jedesmal, wenn sich
der Wert in den ersten 4 Stellen von DEPT ändert, wird über die Systemfunktion
COUNT die
Anzahl der verarbeiteten Datensätze ermittelt.
** Example 'ATBREX04': AT BREAK OF (two statements in combination)
************************************************************************
DEFINE DATA LOCAL
1 MYVIEW VIEW OF EMPLOYEES
2 DEPT
2 REDEFINE DEPT
3 #GENDEP (A4)
2 NAME
2 SALARY (1)
END-DEFINE
*
WRITE TITLE '** PERSONS WITH SALARY > 30000, SORTED BY DEPARTMENT **' /
LIMIT 9
READ MYVIEW BY DEPT FROM 'A' WHERE SALARY(1) > 30000
DISPLAY 'DEPT' DEPT NAME 'SALARY' SALARY(1)
/*
AT BREAK OF DEPT
SKIP 1
END-BREAK
AT BREAK OF DEPT /4/
WRITE COUNT(SALARY(1)) 'RECORDS FOUND IN:' OLD(#GENDEP) /
END-BREAK
END-READ
END
Ausgabe des Programms ATBREX04:
** PERSONS WITH SALARY > 30000, SORTED BY DEPARTMENT **
DEPT NAME SALARY
------ -------------------- ----------
ADMA01 JENSEN 180000
ADMA01 PETERSEN 105000
ADMA01 MORTENSEN 320000
ADMA01 MADSEN 149000
ADMA01 BUHL 642000
ADMA02 HERMANSEN 391500
ADMA02 PLOUG 162900
ADMA02 HANSEN 234000
8 RECORDS FOUND IN: ADMA
COMP01 HEURTEBISE 168800
1 RECORDS FOUND IN: COMP
Automatische Gruppenwechsel-Verarbeitung ist für eine
Verarbeitungsschleife aktiv, die ein AT
BREAK-Statement enthält. Dies gilt für die folgenden
Statements:
Hierbei wird der Wert des im AT
BREAK-Statement angegebenen Kontrollfeldes nur bei den
Datensätzen überprüft, die die WITH- und
WHERE-Auswahlkriterien
der Verarbeitungsschleife erfüllen.
Natural-Systemfunktionen (AVER,
MAX,
MIN usw.)
werden für jeden Datensatz ausgewertet, nachdem alle in der
Verarbeitungsschleife enthaltenen Statements ausgeführt worden sind.
Datensätze, die aufgrund des WHERE-Kriteriums
nicht verarbeitet werden, werden bei der Auswertung der Systemfunktionen nicht
berücksichtigt.
Die Abbildung auf der folgenden Seite veranschaulicht den Verarbeitungsablauf eines automatischen Gruppenwechsels.

Das folgende Beispiel zeigt die Verwendung der
Natural-Systemfunktionen
OLD,
MIN,
AVER,
MAX,
SUM und
COUNT in
einem AT
BREAK-Statement (und der Systemfunktion
TOTAL in
einem AT END OF
DATA-Statement).
** Example 'ATBREX05': AT BREAK OF (with system functions)
************************************************************************
DEFINE DATA LOCAL
1 MYVIEW VIEW OF EMPLOYEES
2 NAME
2 CITY
2 SALARY (1:1)
2 CURR-CODE (1:1)
END-DEFINE
*
LIMIT 3
READ MYVIEW BY CITY = 'SALT LAKE CITY'
DISPLAY NOTITLE CITY NAME 'SALARY' SALARY(1) 'CURRENCY' CURR-CODE(1)
/*
AT BREAK OF CITY
WRITE / OLD(CITY) (EM=X^X^X^X^X^X^X^X^X^X^X^X^X^X^X)
31T ' - MINIMUM:' MIN(SALARY(1)) CURR-CODE(1) /
31T ' - AVERAGE:' AVER(SALARY(1)) CURR-CODE(1) /
31T ' - MAXIMUM:' MAX(SALARY(1)) CURR-CODE(1) /
31T ' - SUM:' SUM(SALARY(1)) CURR-CODE(1) /
33T COUNT(SALARY(1)) 'RECORDS FOUND' /
END-BREAK
/*
AT END OF DATA
WRITE 22T 'TOTAL (ALL RECORDS):'
T*SALARY TOTAL(SALARY(1)) CURR-CODE(1)
END-ENDDATA
END-READ
END
Ausgabe des Programms ATBREX05:
CITY NAME SALARY CURRENCY
-------------------- -------------------- ---------- --------
SALT LAKE CITY ANDERSON 50000 USD
SALT LAKE CITY SAMUELSON 24000 USD
S A L T L A K E C I T Y - MINIMUM: 24000 USD
- AVERAGE: 37000 USD
- MAXIMUM: 50000 USD
- SUM: 74000 USD
2 RECORDS FOUND
SAN DIEGO GEE 60000 USD
S A N D I E G O - MINIMUM: 60000 USD
- AVERAGE: 60000 USD
- MAXIMUM: 60000 USD
- SUM: 60000 USD
1 RECORDS FOUND
TOTAL (ALL RECORDS): 134000 USD
Siehe folgendes Beispielprogramm:
Mit dem Statement BEFORE BREAK
PROCESSING können Sie Statements angeben, die unmittelbar vor
einem Gruppenwechsel ausgeführt werden sollen, d.h. bevor der Wert des
Kontrollfeldes geprüft wird, bevor die Statements im
AT BREAK-Block
ausgeführt werden und bevor Natural-Systemfunktionen ausgewertet
werden.
** Example 'BEFORX01': BEFORE BREAK PROCESSING
************************************************************************
DEFINE DATA LOCAL
1 MYVIEW VIEW OF EMPLOYEES
2 NAME
2 FIRST-NAME
2 SALARY (1:1)
2 BONUS (1:1,1:1)
*
1 #INCOME (P11)
END-DEFINE
*
LIMIT 5
READ MYVIEW BY NAME FROM 'B'
BEFORE BREAK PROCESSING
COMPUTE #INCOME = SALARY(1) + BONUS(1,1)
END-BEFORE
/*
DISPLAY NOTITLE NAME FIRST-NAME (AL=10)
'ANNUAL/INCOME' #INCOME 'SALARY' SALARY(1) (LC==) /
'+ BONUS' BONUS(1,1) (IC=+)
AT BREAK OF #INCOME
WRITE T*#INCOME '-'(24)
END-BREAK
END-READ
END
Ausgabe des Programms BEFORX01:
NAME FIRST-NAME ANNUAL SALARY
INCOME + BONUS
-------------------- ---------- ------------ -----------
BACHMANN HANS 56800 = 52800
+4000
------------------------
BAECKER JOHANNES 81000 = 74400
+6600
------------------------
BAECKER KARL 52650 = 48600
+4050
------------------------
BAGAZJA MARJAN 152700 = 129700
+23000
------------------------
BAILLET PATRICK 198500 = 188000
+10500
------------------------
Bei automatischer Gruppenwechsel-Verarbeitung werden die im AT
BREAK-Block angegebenen Statements jedesmal ausgeführt, wenn sich der Wert des
angegebenen Kontrollfeldes ändert, und zwar unabhängig von der Position des
AT BREAK-Statements
in der Verarbeitungsschleife.
Mit einem PERFORM BREAK
PROCESSING-Statement können Sie selbst festlegen, wo in einer
Verarbeitungsschleife eine Gruppenwechsel-Verarbeitung ausgeführt werden soll.
Das PERFORM BREAK PROCESSING-Statement wird dann ausgeführt, wenn
es im Verarbeitungsablauf des Programms angetroffen wird.
Unmittelbar nach dem PERFORM BREAK PROCESSING-Statement
geben Sie einen oder mehrere AT BREAK-Statement-Blöcke an:
...
PERFORM BREAK PROCESSING
AT BREAK OF field1
statements
END-BREAK
AT BREAK OF field2
statements
END-BREAK
...
Wenn ein PERFORM BREAK PROCESSING-Statement ausgeführt
wird, prüft Natural, ob ein Gruppenwechsel stattgefunden hat, d.h. ob der Wert
des angegebenen Kontrollfeldes sich geändert hat; ist dies der Fall, dann
werden die angegebenen Statements ausgeführt.
Bei PERFORM BREAK PROCESSING werden Systemfunktionen
ausgewertet, bevor Natural prüft, ob ein Gruppenwechsel stattgefunden
hat.
Die folgende Abbildung zeigt den logischen Ablauf einer programmabhängigen Gruppenwechsel-Verarbeitung:

** Example 'PERFBX01': PERFORM BREAK PROCESSING (with BREAK option
** in IF statement)
************************************************************************
DEFINE DATA LOCAL
1 MYVIEW VIEW OF EMPLOYEES
2 NAME
2 DEPT
2 SALARY (1:1)
*
1 #CNTL (N2)
END-DEFINE
*
LIMIT 7
READ MYVIEW BY DEPT
AT BREAK OF DEPT /* <- automatic break processing
SKIP 1
WRITE 'SUMMARY FOR ALL SALARIES '
'SUM:' SUM(SALARY(1))
'TOTAL:' TOTAL(SALARY(1))
ADD 1 TO #CNTL
END-BREAK
/*
IF SALARY (1) GREATER THAN 100000 OR BREAK #CNTL
PERFORM BREAK PROCESSING /* <- user-initiated break processing
AT BREAK OF #CNTL
WRITE 'SUMMARY FOR SALARY GREATER 100000'
'SUM:' SUM(SALARY(1))
'TOTAL:' TOTAL(SALARY(1))
END-BREAK
END-IF
/*
IF SALARY (1) GREATER THAN 150000 OR BREAK #CNTL
PERFORM BREAK PROCESSING /* <- user-initiated break processing
AT BREAK OF #CNTL
WRITE 'SUMMARY FOR SALARY GREATER 150000'
'SUM:' SUM(SALARY(1))
'TOTAL:' TOTAL(SALARY(1))
END-BREAK
END-IF
DISPLAY NAME DEPT SALARY(1)
END-READ
END
Ausgabe des Programms PERFBX01:
Page 1 04-12-14 14:13:35
NAME DEPARTMENT ANNUAL
CODE SALARY
-------------------- ---------- ----------
JENSEN ADMA01 180000
PETERSEN ADMA01 105000
MORTENSEN ADMA01 320000
MADSEN ADMA01 149000
BUHL ADMA01 642000
SUMMARY FOR ALL SALARIES SUM: 1396000 TOTAL: 1396000
SUMMARY FOR SALARY GREATER 100000 SUM: 1396000 TOTAL: 1396000
SUMMARY FOR SALARY GREATER 150000 SUM: 1142000 TOTAL: 1142000
HERMANSEN ADMA02 391500
PLOUG ADMA02 162900
SUMMARY FOR ALL SALARIES SUM: 554400 TOTAL: 1950400
SUMMARY FOR SALARY GREATER 100000 SUM: 554400 TOTAL: 1950400
SUMMARY FOR SALARY GREATER 150000 SUM: 554400 TOTAL: 1696400