記述した条件が満たされるまで、または一定の条件が有効である限り、処理ループはグループ化されたステートメントを繰り返し実行します。
このドキュメントでは、次のトピックについて説明します。
処理ループはデータベースループと非データベースループに分類できます。
データベース処理ループ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 14-01-14 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 (FD.)
END-FIND /* (FD.)
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***