コントロールブレイク

このドキュメントでは、ステートメントの実行をコントロールブレイクに依存させる方法、および Natural システム関数の評価にコントロールブレイクを使用する方法について説明します。

以下のトピックについて説明します。


コントロールブレイクの使用

コントロールブレイクは、コントロールフィールドの値が変わると発生します。

ステートメントの実行をコントロールブレイクに依存させることができます。

また、Natural システム関数の評価にコントロールブレイクを使用することもできます。

システム関数については、「システム変数とシステム関数」で説明します。有効なシステム関数の詳細については、『システム関数』ドキュメントを参照してください。

AT BREAK ステートメント

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 システム関数 OLDAVER、および 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 システム関数AVERMAXMIN など)は、処理ループ内のすべてのステートメントを実行した後に、レコードごとに評価されます。システム関数は、WHERE 条件で拒否されたレコードに対しては評価されません。

下の図は、自動ブレイク処理のフローロジックを示しています。

AT BREAK ステートメントとシステム関数の例

次の例は、AT BREAK ステートメント内の Natural システム関数 OLDMINAVERMAXSUM および 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    

AT BREAK ステートメントの他の例

次の例のプログラムを参照してください。

BEFORE BREAK PROCESSING ステートメント

BEFORE BREAK PROCESSING ステートメントを使用すると、コントロールブレイクの直前、つまり、コントロールフィールドの値のチェック前、AT BREAK ブロックに指定したステートメントの実行前、および、あらゆる Natural システム関数の実行前に、実行するステートメントを指定できます。

BEFORE BREAK PROCESSING ステートメントの例

** 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
                                ------------------------

ユーザー開始のブレイク処理 - PERFORM BREAK PROCESSING ステートメント

自動ブレイク処理では、処理ループ内の 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 では、ブレイクが起こったかどうかをチェックする前に、システム関数が評価されます。

以下の図は、ユーザー開始のブレイク処理のフローロジックを示しています。

graphics/pgflowbreak.png

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