このドキュメントでは、ステートメントの実行をコントロールブレイクに依存させる方法、および Natural システム関数の評価にコントロールブレイクを使用する方法について説明します。
次のトピックについて説明します。
コントロールブレイクは、コントロールフィールドの値が変わると発生します。
ステートメントの実行をコントロールブレイクに依存させることができます。
また、Natural システム関数の評価にコントロールブレイクを使用することもできます。
システム関数については、「システム変数とシステム関数」で説明します。 有効なシステム関数の詳細については、『システム関数』ドキュメントを参照してください。
AT BREAK
ステートメントでは、コントロールブレイクが起こるたび、つまり、AT BREAK
ステートメントに指定したコントロールフィールドの値が変わるたびに実行する処理を指定します。 コントロールフィールドとして、データベースフィールドまたはユーザー定義変数を使用できます。
以下では次のトピックについて説明します。
AT BREAK
ステートメントにコントロールフィールドとして指定されるフィールドは、通常はデータベースフィールドです。
例:
... AT BREAK OF DEPT statements END-BREAK ...
この例では、コントロールフィールドはデータベースフィールド DEPT
です。このフィールドの値が変わると(例:SALE01
から SALE02
へ)、AT BREAK
ステートメントに指定した statements が実行されます。
フィールド全体ではなく、フィールドの一部のみをコントロールフィールドとして使用することもできます。 /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 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
ユーザー定義変数を 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 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
上記の説明のとおり、/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 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 ***
以下のプログラムでは、フィールド 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 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