このドキュメントでは、ステートメントの実行をコントロールブレイクに依存させる方法、および Natural システム関数の評価にコントロールブレイクを使用する方法について説明します。
以下のトピックについて説明します。
コントロールブレイクは、コントロールフィールドの値が変わると発生します。
ステートメントの実行をコントロールブレイクに依存させることができます。
また、Natural システム関数の評価にコントロールブレイクを使用することもできます。
システム関数については、「システム変数とシステム関数」で説明します。有効なシステム関数の詳細については、『システム関数』ドキュメントを参照してください。
AT
BREAK ステートメントでは、コントロールブレイクが起こるたび、つまり、AT BREAK ステートメントに指定したコントロールフィールドの値が変わるたびに実行する処理を指定します。コントロールフィールドとして、データベースフィールドまたはユーザー定義変数を使用できます。
以下では次のトピックについて説明します。
AT BREAK ステートメントにコントロールフィールドとして指定されるフィールドは、通常はデータベースフィールドです。
例:
... AT BREAK OF DEPT statements END-BREAK ...
この例では、コントロールフィールドはデータベースフィールド DEPT です。このフィールドの値が変わると(例:FROM SALE01 から SALE02 へ)、AT BREAK ステートメントに指定した statements が実行されます。
フィールド全体ではなく、フィールドの一部のみをコントロールフィールドとして使用することもできます。/n/ 表記 /n/ を使用して、フィールドの先頭の n 桁のみを使用して値の変更をチェックするように指定できます。
例:
... AT BREAK OF DEPT /4/ statements END-BREAK ...
この例では、指定した statements は、フィールド DEPT の先頭 4 桁の値が変わった場合(例:SALE から TECH へ)にのみ実行されます。ただし、フィールド値が SALE01 から SALE02 に変わっても、この変更は無視され、AT BREAK 処理は実行されません。
** 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
上記のプログラムでは、フィールド CITY の値が変わるたびに、最初の WRITE ステートメントが実行されます。
AT
BREAK ステートメントでは、Natural システム関数 OLD、AVER、および COUNT が評価され、その結果が WRITE ステートメントで出力されます。
AT END OF
DATA ステートメントでは、Natural システム関数 TOTAL が評価されます。
プログラム ATBREX01 の出力:
Page 1 14-01-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
ユーザー定義変数を AT BREAK ステートメントのコントロールフィールドとして使用することもできます。
以下のプログラムでは、ユーザー定義変数 #LOCATION が、コントロールフィールドとして使用されています。
** 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
プログラム ATBREX02 の出力:
Page 1 14-01-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
上記の説明のとおり、/n/ 表記を使用すると、フィールドの一部分をコントロールブレイクのためにチェックできます。フィールド全体をあるブレイクのコントロールフィールドとして使用し、同じフィールドの一部を別のブレイクのコントロールフィールドとして使用することにより、複数の
AT BREAK ステートメントを組み合わせることができます。
このような場合、下位レベル(フィールド全体)のブレイクは、上位レベル(フィールドの一部)のブレイクの前に指定する必要があります。つまり、最初の AT BREAK ステートメントでフィールド全体をコントロールフィールドとして指定し、2 番目のステートメントでフィールドの一部をコントロールフィールドとして指定する必要があります。
以下のプログラム例は、フィールド DEPT とその最初の 4 桁(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
プログラム ATBREX03 の出力:
Page 1 14-01-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 ***
以下のプログラムでは、フィールド DEPT の値が変わるたびに 1 行の空行が出力されます。また、DEPT の先頭 4 桁の値が変わるたびにシステム関数 COUNT が評価され、レコード件数が算出されます。
** 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
プログラム 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
自動ブレイク処理は、AT BREAK ステートメントが含まれている処理ループで実行されます。これは以下のステートメントに適用されます。
AT BREAK ステートメントに指定されているコントロールフィールドの値は、WITH 節および WHERE 節の選択条件を満たしているレコードに対してのみチェックされます。
Natural システム関数(AVER、MAX、MIN など)は、処理ループ内のすべてのステートメントを実行した後に、レコードごとに評価されます。システム関数は、WHERE 条件で拒否されたレコードに対しては評価されません。
下の図は、自動ブレイク処理のフローロジックを示しています。

次の例は、AT BREAK ステートメント内の Natural システム関数 OLD、MIN、AVER、MAX、SUM および COUNT(および AT END OF DATA ステートメント内のシステム関数 TOTAL)の使用方法を示しています。
** 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
プログラム 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
次の例のプログラムを参照してください。
BEFORE BREAK
PROCESSING ステートメントを使用すると、コントロールブレイクの直前、つまり、コントロールフィールドの値のチェック前、AT BREAK ブロックに指定したステートメントの実行前、および、あらゆる Natural システム関数の実行前に、実行するステートメントを指定できます。
** 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
プログラム 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
------------------------
自動ブレイク処理では、処理ループ内の AT BREAK ステートメントの位置に関係なく、指定したコントロールフィールドの値が変わるたびに、AT BREAK ブロックに指定したステートメントが実行されます。
PERFORM BREAK
PROCESSING ステートメントを使用すると、処理ループ内の特定の位置でブレイク処理を実行できます。PERFORM BREAK
PROCESSING ステートメントは、プログラムの処理フローの中で検出されると実行されます。
PERFORM BREAK PROCESSING の直後に、1 つ以上の AT BREAK ステートメントブロックを指定します。
...
PERFORM BREAK PROCESSING
AT BREAK OF field1
statements
END-BREAK
AT BREAK OF field2
statements
END-BREAK
...
PERFORM BREAK PROCESSING が実行されると、Natural によって、ブレイクが起こったかどうか、つまり、指定したコントロールフィールドの値が変わったかどうかがチェックされます。値が変わっている場合、指定したステートメントが実行されます。
PERFORM BREAK PROCESSING では、ブレイクが起こったかどうかをチェックする前に、システム関数が評価されます。
以下の図は、ユーザー開始のブレイク処理のフローロジックを示しています。

** 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
プログラム PERFBX01 の出力:
Page 1 14-01-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