記述した条件が満たされるまで、または一定の条件が有効である限り、処理ループはグループ化されたステートメントを繰り返し実行します。
このドキュメントでは、次のトピックについて説明します。
処理ループはデータベースループと非データベースループに分類できます。
データベース処理ループ
READ
、FIND
、または HISTOGRAM
の各ステートメントの結果としてデータベースから取得したデータを処理するために、Natural によって自動的に作成されます。 これらのステートメントの詳細については、「Adabas データベースのデータへのアクセス」を参照してください。
非データベース処理ループ
ステートメント REPEAT
、FOR
、CALL FILE
、CALL LOOP
、SORT
、および READ WORK FILE
によって開始されます。
複数の処理ループを同時にアクティブにできます。 ループは、アクティブな(開いている)他のループ内に埋め込んだり、ネストしたりできます。
処理ループは、対応する END-...
ステートメント(END-REPEAT
、END-FOR
など)で明示的に閉じる必要があります。
オペレーティングシステムのソートプログラムを呼び出す SORT
ステートメントは、すべてのアクティブな処理ループを閉じて、新しい処理ループを開始します。
以下では次のトピックについて説明します。
ステートメント READ
、FIND
、または HISTOGRAM
で開始した処理ループの繰り返し回数を制限するには、以下の 3 つの方法があります。
システムコマンド GLOBALS
には、セッションパラメータ LT
を指定できます。このパラメータを使用して、データベース処理ループで読み込むレコード件数を制限します。
GLOBALS LT=100
この制限は、セッション全体のすべての READ
、FIND
、および HISTOGRAM
の各ステートメントに適用されます。
プログラムでは、LIMIT
ステートメントを使用して、データベース処理ループで読み込むレコード件数を制限できます。
LIMIT 100
別の LIMIT
ステートメントまたはリミット表記によって上書きされるまで、LIMIT
ステートメントはプログラムの残りの部分に適用されます。
READ
、FIND
、または HISTOGRAM
の各ステートメント自体で、読み込むレコード件数をステートメント名の直後のカッコ内に指定できます。
READ (10) VIEWXYZ BY NAME
このリミット表記は、その他の有効なあらゆる制限を上書きします。ただし、リミット表記が適用されるのは、その表記が指定されているステートメントのみです。
LT
パラメータに設定されている制限が、LIMIT
ステートメントに指定されている制限またはリミット表記よりも小さい場合、LT
の制限はこれらの他の制限より優先されます。
非データベース処理ループは、論理条件基準、または他に指定された制限条件に基づいて開始および終了します。
ここでは、非データベースループステートメントとして、REPEAT
ステートメントについて説明します。
REPEAT
ステートメントを使用して、繰り返し実行する 1 つ以上のステートメントを指定します。 さらに、ある条件に一致するまで、または、ある条件に一致している間にのみステートメントが実行されるように、論理条件を指定できます。 この目的のためには、UNTIL
節または WHILE
節を使用します。
論理条件を指定する場合、以下のようにループは制御されます。
UNTIL
節を使用すると、論理条件が満たされるまで REPEAT
ループが続けられます。
WHILE
節を使用すると、論理条件が真である限り REPEAT
ループが続けられます。
論理条件を指定しない場合、以下のステートメントのいずれかを使用して、REPEAT
ループを抜ける必要があります。
** Example 'REPEAX01': REPEAT ************************************************************************ DEFINE DATA LOCAL 1 MYVIEW VIEW OF EMPLOYEES 2 NAME 2 SALARY (1:1) * 1 #PAY1 (N8) END-DEFINE * READ (5) MYVIEW BY NAME WHERE SALARY (1) = 30000 THRU 39999 MOVE SALARY (1) TO #PAY1 /* REPEAT WHILE #PAY1 LT 40000 MULTIPLY #PAY1 BY 1.1 DISPLAY NAME (IS=ON) SALARY (1)(IS=ON) #PAY1 END-REPEAT /* SKIP 1 END-READ END
プログラム REPEAX01 の出力:
Page 1 04-11-11 14:15:54 NAME ANNUAL #PAY1 SALARY -------------------- ---------- --------- ADKINSON 34500 37950 41745 33500 36850 40535 36000 39600 43560 AFANASSIEV 37000 40700 ALEXANDER 34500 37950 41745
ESCAPE
ステートメントは、論理条件に基づいて処理ループの実行を終了するために使用します。
ESCAPE
ステートメントは、IF
条件ステートメントグループのループ内、およびブレイク処理ステートメントグループ(AT END OF DATA
、AT END OF PAGE
、AT BREAK
)のループ内で指定できます。また、非データベースループの基本論理条件を実装している独立操作可能なステートメントとして指定できます。
ESCAPE
ステートメントには、ESCAPE
ステートメントで処理ループを抜けた後にどこから処理を継続するのかを指定するオプション TOP
と BOTTOM
が用意されています。
ESCAPE TOP
は、処理ループの先頭から処理を継続するために使用します。
ESCAPE BOTTOM
は、処理ループの後の最初のステートメントから処理を継続するために使用します。
同じ処理ループ内に複数の ESCAPE
ステートメントを指定できます。
ESCAPE
ステートメントの詳細と例については、『ステートメント』ドキュメントを参照してください。
別のデータベースステートメントによって開始されたデータベース処理ループ内にデータベースステートメントを指定できます。 データベースループ開始ステートメントがこの方法で埋め込まれていると、ループの "階層" が作成され、階層ごとに、選択条件を満たす各レコードが処理されます。
複数のレベルのループを埋め込むことができます。 例えば、非データベースループをデータベースループ内にネストできます。 また、データベースループを非データベースループ内にネストすることもできます。 データベースループおよび非データベースループは、条件付きステートメントグループ内でネストできます。
以下のプログラムは、2 つのループ階層を示しています。1 つの FIND
ループ内に別の FIND
ループがネスト、つまり埋め込まれています。
** Example 'FINDX06': FIND (two FIND statements nested) ************************************************************************ DEFINE DATA LOCAL 1 EMPLOY-VIEW VIEW OF EMPLOYEES 2 CITY 2 NAME 2 PERSONNEL-ID 1 VEH-VIEW VIEW OF VEHICLES 2 MAKE 2 PERSONNEL-ID END-DEFINE * FND1. FIND EMPLOY-VIEW WITH CITY = 'NEW YORK' OR = 'BEVERLEY HILLS' FIND (1) VEH-VIEW WITH PERSONNEL-ID = PERSONNEL-ID (FND1.) DISPLAY NOTITLE NAME CITY MAKE END-FIND END-FIND END
上記のプログラムでは、複数のファイルからデータを選択しています。 外側の FIND
ループでは、EMPLOYEES ファイルから、ニューヨークまたはビバリーヒルズに住んでいるすべての個人を選択しています。 内側の FIND
ループでは、外側のループで選択されたレコードごとに、VEHICLES ファイルからその個人の車のデータを選択しています。
プログラム FINDX06 の出力:
NAME CITY MAKE -------------------- -------------------- -------------------- RUBIN NEW YORK FORD OLLE BEVERLEY HILLS GENERAL MOTORS WALLACE NEW YORK MAZDA JONES BEVERLEY HILLS FORD SPEISER BEVERLEY HILLS GENERAL MOTORS
ステートメント参照表記は、以下の目的で使用します。
特定の範囲のデータに対する処理を指定するために、プログラム内で前に処理したステートメントを参照するため。
Natural のデフォルトの参照設定を上書きするため。
コードをわかりやすくするため。
処理ループの開始、またはデータベースのデータ要素へのアクセスを発生させる、あらゆる Natural ステートメントを参照できます。 例えば、以下のステートメントを参照できます。
プログラムで複数の処理ループを使用するときは、参照表記を使用して、データベースフィールドに最初にアクセスしたステートメントを参照することにより、処理対象のデータベースフィールドを一意に指定します。
このような方法でフィールドを参照できるかどうかは、『ステートメント』ドキュメントに記載されている、対応するステートメントの説明の「オペランド定義テーブル」の "ステートメント参照" 列を参照してください。 「ユーザー定義変数」の「表記 (r) を使用したデータベースフィールドの参照」を参照してください。
また、参照表記はいくつかのステートメントで指定できます。 次に例を示します。
参照表記を使用しないと、AT START OF DATA
、AT END OF DATA
、または AT BREAK
ステートメントは、最も外側のアクティブな READ
、FIND
、HISTOGRAM
、SORT
、または READ WORK FILE
の各ループに関連付けられます。 参照表記を使用すると、別のアクティブな処理ループに関連付けることができます。
参照表記を ESCAPE BOTTOM
ステートメントに指定すると、参照表記で指定した処理ループの後の最初のステートメントから処理が継続されます。
ステートメント参照表記は、ステートメント参照ラベル形式またはソースコード行番号形式で指定できます。
ステートメント参照ラベル
ステートメント参照ラベルはいくつかの文字で構成され、最後には必ずピリオド(.)を使用します。 ピリオドによって、そのエントリはラベルとして識別されます。
ステートメントが含まれる行の先頭にラベルを指定することにより、参照されるステートメントをラベルでマークします。 次に例を示します。
0030 ... 0040 READ1. READ VIEWXYZ BY NAME 0050 ...
マークされたステートメントを参照するステートメントでは、ステートメントの構文図に示されている位置に、ラベルをカッコで囲んで指定します(『ステートメント』ドキュメントを参照)。 次に例を示します。
AT BREAK (READ1.) OF NAME
ソースコード行番号
ソースコード行番号を使用して参照する場合、行番号は、カッコで囲んだ 4 桁の数字(先行ゼロは省略不可)で指定する必要があります。 次に例を示します。
AT BREAK (0040) OF NAME
ステートメント内でラベル/行番号を使用して特定のフィールドを前のステートメントに関連付ける場合、ラベル/行番号は、フィールド名の後にカッコで囲んで指定します。 次に例を示します。
DISPLAY NAME (READ1.) JOB-TITLE (READ1.) MAKE MODEL
行番号とラベルは区別なく使用できます。
「ユーザー定義変数」の「表記 (r) を使用したデータベースフィールドの参照」を参照してください。
以下のプログラムでは、参照にソースコード行番号(カッコで囲んだ 4 桁の数字)を使用しています。
この例では、参照先のステートメントへのすべての参照において、デフォルトで行番号が使用されています。
0010 ** Example 'LABELX01': Labels for READ and FIND loops (line numbers) 0020 ************************************************************************ 0030 DEFINE DATA LOCAL 0040 1 MYVIEW1 VIEW OF EMPLOYEES 0050 2 NAME 0060 2 FIRST-NAME 0070 2 PERSONNEL-ID 0080 1 MYVIEW2 VIEW OF VEHICLES 0090 2 PERSONNEL-ID 0100 2 MAKE 0110 END-DEFINE 0120 * 0130 LIMIT 15 0140 READ MYVIEW1 BY NAME STARTING FROM 'JONES' 0150 FIND MYVIEW2 WITH PERSONNEL-ID = PERSONNEL-ID (0140) 0160 IF NO RECORDS FOUND 0170 MOVE '***NO CAR***' TO MAKE 0180 END-NOREC 0190 DISPLAY NOTITLE NAME (0140) (IS=ON) 0200 FIRST-NAME (0140) (IS=ON) 0210 MAKE (0150) 0220 END-FIND /* (0150) 0230 END-READ /* (0140) 0240 END
以下の例は、ステートメント参照ラベルの使用方法を示しています。
行番号の代わりにラベルが参照に使用されている点以外は、前述のプログラムと同一です。
** Example 'LABELX02': Labels for READ and FIND loops (user labels) ************************************************************************ DEFINE DATA LOCAL 1 MYVIEW1 VIEW OF EMPLOYEES 2 NAME 2 FIRST-NAME 2 PERSONNEL-ID 1 MYVIEW2 VIEW OF VEHICLES 2 PERSONNEL-ID 2 MAKE END-DEFINE * LIMIT 15 RD. READ MYVIEW1 BY NAME STARTING FROM 'JONES' FD. FIND MYVIEW2 WITH PERSONNEL-ID = PERSONNEL-ID (RD.) IF NO RECORDS FOUND MOVE '***NO CAR***' TO MAKE END-NOREC DISPLAY NOTITLE NAME (RD.) (IS=ON) FIRST-NAME (RD.) (IS=ON) MAKE (RD.) END-FIND /* (RD.) END-READ /* (RD.) END
どちらのプログラムでも、以下の出力が生成されます。
NAME FIRST-NAME MAKE -------------------- -------------------- -------------------- JONES VIRGINIA CHRYSLER MARSHA CHRYSLER CHRYSLER ROBERT GENERAL MOTORS LILLY FORD MG EDWARD GENERAL MOTORS LAUREL GENERAL MOTORS KEVIN DATSUN GREGORY FORD JOPER MANFRED ***NO CAR*** JOUSSELIN DANIEL RENAULT JUBE GABRIEL ***NO CAR*** JUNG ERNST ***NO CAR*** JUNKIN JEREMY ***NO CAR*** KAISER REINER ***NO CAR*** KANT HEIKE ***NO CAR***