COBOLのPERFORM文は、繰り返し処理(ループ)と段落呼び出しの両方を担う中核命令です。TIMES・UNTIL・VARYINGの3種類のループ形式に加え、TEST BEFORE/AFTER(前判定/後判定)・VARYING AFTERによる多重ループ・EXIT PERFORMによるループ中断など、業務コードで頻繁に必要となる応用まで習得することが重要です。
この記事ではPERFORM文の各形式を基本から押さえたうえで、ファイル読み込みループ・配列集計・検索処理・バリデーションループといった業務でよく使うパターンを実践コードで解説します。
- PERFORM段落呼び出し・TIMES・UNTIL・VARYINGの構文と使い分け
- TEST BEFORE(前判定)とTEST AFTER(後判定)の違いと使い分け
- VARYING … AFTER句による多次元配列の多重ループ
- EXIT PERFORMでループを途中で抜ける方法
- ファイル読み込みループ(AT END/NOT AT END)のパターン
- 配列集計・線形検索・バリデーションの実践ループパターン
- よくある落とし穴と対策
PERFORM文の全体像
PERFORM文には大きく「段落呼び出し」と「インラインループ」の2つの使い方があります。
| 種類 | 構文 | 用途 |
|---|---|---|
| 段落呼び出し | PERFORM 段落名 | 段落(パラグラフ)を1回呼び出す |
| THRU付き段落呼び出し | PERFORM 段落A THRU 段落B | 段落AからBまで連続実行する |
| 回数指定ループ | PERFORM … TIMES | 指定回数繰り返す |
| 条件ループ | PERFORM UNTIL … | 条件が真になるまで繰り返す(TEST BEFORE/AFTER) |
| カウンタ制御ループ | PERFORM VARYING … UNTIL … | カウンタを増減しながら繰り返す |
| 多重ループ | PERFORM VARYING … AFTER … | 2変数以上のネストループ |
インラインPERFORMとアウトオブラインPERFORMの使い分け
*=== アウトオブライン: 処理を段落に切り出す ===
*> メリット: 段落名がコメント代わりになり可読性が高い
*> 同じ処理を複数箇所から呼べる(再利用性)
PROCEDURE DIVISION.
PERFORM VALIDATE-INPUT
PERFORM CALC-AMOUNT
PERFORM OUTPUT-RESULT
STOP RUN.
VALIDATE-INPUT.
*> 入力チェック処理
EXIT.
CALC-AMOUNT.
*> 計算処理
EXIT.
OUTPUT-RESULT.
*> 出力処理
EXIT.
*=== インライン: END-PERFORMで囲む ===
*> メリット: 短いループには簡潔に書ける
*> 変数スコープが明確
PROCEDURE DIVISION.
PERFORM VARYING WS-IDX FROM 1 BY 1 UNTIL WS-IDX > 10
ADD WS-SCORE(WS-IDX) TO WS-TOTAL
END-PERFORM.
- 5行以下の短い処理 → インラインPERFOMでOK
- 10行超の処理・複数箇所から呼ぶ処理 → アウトオブラインで段落に切り出す
- 段落名は「何をする段落か」が一目でわかる名前にする(VALIDATE-INPUT、CALC-TAX等)
PERFORM TIMES(回数指定ループ)
指定した回数だけ処理を繰り返します。回数は定数でも変数でも指定できます。ループカウンタは自動管理されないため、必要な場合は別途変数を用意します。
WORKING-STORAGE SECTION.
01 WS-REPEAT-COUNT PIC 9(3) VALUE 5.
01 WS-LOOP-CNT PIC 9(3) VALUE 0.
01 WS-TOTAL PIC 9(9) VALUE 0.
01 WS-INPUT-VAL PIC 9(5) VALUE 1000.
PROCEDURE DIVISION.
*> 定数回繰り返す
PERFORM 3 TIMES
DISPLAY 'リトライ中...'
END-PERFORM.
*> 変数で回数を指定
PERFORM WS-REPEAT-COUNT TIMES
ADD 1 TO WS-LOOP-CNT
ADD WS-INPUT-VAL TO WS-TOTAL
END-PERFORM.
DISPLAY '合計: ' WS-TOTAL *> 5000
PERFORM 0 TIMESはループ本体を実行しません(0回ループ)。負の値を指定した場合の動作はコンパイラ依存ですが、ほとんどの実装で実行されません。ループ回数を変数で渡す場合は、事前に値が正か確認しておきましょう。
PERFORM UNTIL(条件ループ)とTEST BEFORE/TEST AFTER
PERFORM UNTILは「条件が真になるまで繰り返す」ループです。条件の判定タイミングをTEST BEFORE(前判定・デフォルト)かTEST AFTER(後判定)かで選べます。
| 種類 | 動作 | 0回実行の可否 | 向いているケース |
|---|---|---|---|
| TEST BEFORE(省略時デフォルト) | ループ本体実行前に条件を評価する | 条件が最初から真の場合、0回実行 | ファイル読み込み・通常の繰り返し |
| TEST AFTER | ループ本体実行後に条件を評価する | 必ず最低1回は実行される | 初回は必ず処理したいケース(メニュー表示・再入力要求) |
*> TEST BEFORE: 最初に条件を評価する(デフォルト)
WORKING-STORAGE SECTION.
01 WS-CNT PIC 9(3) VALUE 0.
01 WS-LIMIT PIC 9(3) VALUE 0. *> 最初から0
PROCEDURE DIVISION.
*> WS-LIMITが0なので、条件 WS-CNT >= WS-LIMIT は最初からTRUE
PERFORM WITH TEST BEFORE UNTIL WS-CNT >= WS-LIMIT
ADD 1 TO WS-CNT *> 一度も実行されない
END-PERFORM
DISPLAY WS-CNT. *> 0(本体が0回実行)
*> TEST AFTER: 本体を実行してから条件を評価する(do-while相当)
WORKING-STORAGE SECTION.
01 WS-CNT PIC 9(3) VALUE 0.
01 WS-LIMIT PIC 9(3) VALUE 0. *> 最初から0
PROCEDURE DIVISION.
*> TEST AFTER: 最初に必ず1回実行してから条件を評価
PERFORM WITH TEST AFTER UNTIL WS-CNT >= WS-LIMIT
ADD 1 TO WS-CNT *> 1回実行される
END-PERFORM
DISPLAY WS-CNT. *> 1(本体が1回実行)
WORKING-STORAGE SECTION.
01 WS-USER-INPUT PIC X(1).
01 WS-RETRY-COUNT PIC 9(2) VALUE 0.
PROCEDURE DIVISION.
*> 正しい入力が来るまで繰り返す(最低1回は必ず入力させる)
PERFORM WITH TEST AFTER UNTIL
(WS-USER-INPUT = 'Y' OR WS-USER-INPUT = 'N')
OR WS-RETRY-COUNT >= 3
DISPLAY '処理を続けますか?(Y/N): '
ACCEPT WS-USER-INPUT
INSPECT WS-USER-INPUT CONVERTING 'yn' TO 'YN' *> 小文字対応
ADD 1 TO WS-RETRY-COUNT
END-PERFORM
IF WS-RETRY-COUNT >= 3 AND
WS-USER-INPUT NOT = 'Y' AND WS-USER-INPUT NOT = 'N'
DISPLAY '入力回数超過。処理を中断します'
MOVE 8 TO RETURN-CODE
GOBACK
END-IF
IF WS-USER-INPUT = 'Y'
PERFORM MAIN-PROCESS
ELSE
DISPLAY '処理をキャンセルしました'
END-IF.
PERFORM VARYING(カウンタ制御ループ)
PERFORM VARYINGはカウンタ変数を自動的に増減させながら繰り返すループです。配列(OCCURS句)の走査に最もよく使われます。
WORKING-STORAGE SECTION.
01 WS-IDX PIC 9(3).
01 WS-SCORE-TBL.
05 WS-SCORE PIC 9(3) OCCURS 10 TIMES.
01 WS-TOTAL PIC 9(6) VALUE 0.
01 WS-MAX-SCORE PIC 9(3) VALUE 0.
PROCEDURE DIVISION.
*> 配列の合計・最大値を求める
PERFORM VARYING WS-IDX FROM 1 BY 1 UNTIL WS-IDX > 10
ADD WS-SCORE(WS-IDX) TO WS-TOTAL
IF WS-SCORE(WS-IDX) > WS-MAX-SCORE
MOVE WS-SCORE(WS-IDX) TO WS-MAX-SCORE
END-IF
END-PERFORM
DISPLAY '合計: ' WS-TOTAL
DISPLAY '最大値: ' WS-MAX-SCORE
FROM・BY・UNTILの組み合わせパターン
*> 順方向ループ(1から始まり+1ずつ)
PERFORM VARYING WS-IDX FROM 1 BY 1 UNTIL WS-IDX > WS-MAX
処理
END-PERFORM.
*> 逆順ループ(末尾から-1ずつ)
PERFORM VARYING WS-IDX FROM WS-MAX BY -1 UNTIL WS-IDX < 1
処理
END-PERFORM.
*> 偶数インデックスのみ(+2ずつ)
PERFORM VARYING WS-IDX FROM 2 BY 2 UNTIL WS-IDX > WS-MAX
処理
END-PERFORM.
*> 変数でステップを制御
WORKING-STORAGE SECTION.
01 WS-STEP PIC 9(3) VALUE 10. *> 10件ずつ処理
PROCEDURE DIVISION.
PERFORM VARYING WS-IDX FROM 1 BY WS-STEP UNTIL WS-IDX > WS-TOTAL-COUNT
*> WS-IDX, WS-IDX+1, ..., WS-IDX+9 の10件をまとめて処理
PERFORM BULK-PROCESS
END-PERFORM.
VARYING … AFTER による多重ループ
PERFORM VARYINGにAFTER句を追加すると、複数のカウンタを持つ多重ループ(二重・三重ループ)を1つのPERFORM文で記述できます。二次元配列や帳票の行列処理に使います。
PERFORM VARYING 外側カウンタ FROM 開始値 BY 増分 UNTIL 終了条件
AFTER 内側カウンタ FROM 開始値 BY 増分 UNTIL 終了条件
処理
END-PERFORM.
WORKING-STORAGE SECTION.
01 WS-MATRIX.
05 WS-ROW OCCURS 5 TIMES.
10 WS-COL PIC 9(5) OCCURS 5 TIMES.
01 WS-ROW-IDX PIC 9(2).
01 WS-COL-IDX PIC 9(2).
01 WS-COUNTER PIC 9(4) VALUE 1.
PROCEDURE DIVISION.
*> 二次元配列に連番を埋める(1〜25)
PERFORM VARYING WS-ROW-IDX FROM 1 BY 1 UNTIL WS-ROW-IDX > 5
AFTER WS-COL-IDX FROM 1 BY 1 UNTIL WS-COL-IDX > 5
MOVE WS-COUNTER TO WS-COL(WS-ROW-IDX WS-COL-IDX)
ADD 1 TO WS-COUNTER
END-PERFORM
*> 結果確認(5×5の行列表示)
PERFORM VARYING WS-ROW-IDX FROM 1 BY 1 UNTIL WS-ROW-IDX > 5
AFTER WS-COL-IDX FROM 1 BY 1 UNTIL WS-COL-IDX > 5
IF WS-COL-IDX = 5
DISPLAY WS-COL(WS-ROW-IDX WS-COL-IDX)
ELSE
DISPLAY WS-COL(WS-ROW-IDX WS-COL-IDX) ' ' WITH NO ADVANCING
END-IF
END-PERFORM.
外側変数(VARYING)が1回増分されるとき、内側変数(AFTER)はFROMの値にリセットされます。つまり外側1周ごとに内側は最初から最後まで走ります(通常の二重ループと同じ動作)。3重ループが必要な場合はAFTERをもう1つ追加できます。
WORKING-STORAGE SECTION.
01 WS-YEAR-IDX PIC 9(2). *> 1〜3(3年分)
01 WS-MONTH-IDX PIC 9(2). *> 1〜12
01 WS-DAY-IDX PIC 9(2). *> 1〜31
01 WS-SALES-TBL.
05 WS-YEAR-TBL OCCURS 3 TIMES.
10 WS-MONTH-TBL OCCURS 12 TIMES.
15 WS-DAY-SALES PIC 9(9)V99 OCCURS 31 TIMES.
01 WS-TOTAL PIC 9(12)V99 VALUE 0.
PROCEDURE DIVISION.
PERFORM VARYING WS-YEAR-IDX FROM 1 BY 1 UNTIL WS-YEAR-IDX > 3
AFTER WS-MONTH-IDX FROM 1 BY 1 UNTIL WS-MONTH-IDX > 12
AFTER WS-DAY-IDX FROM 1 BY 1 UNTIL WS-DAY-IDX > 31
ADD WS-DAY-SALES(WS-YEAR-IDX WS-MONTH-IDX WS-DAY-IDX)
TO WS-TOTAL
END-PERFORM
DISPLAY '3年間の総売上: ' WS-TOTAL.
EXIT PERFORMでループを途中で抜ける
ループ処理中に特定の条件が成立したとき、残りの繰り返しをスキップしてループを終了させるにはEXIT PERFORMを使います。他の言語のbreakに相当します。
WORKING-STORAGE SECTION.
01 WS-ITEM-TABLE.
05 WS-ITEM-CODE PIC X(6) OCCURS 100 TIMES.
01 WS-SEARCH-CODE PIC X(6).
01 WS-FOUND-IDX PIC 9(3) VALUE 0.
01 WS-IDX PIC 9(3).
PROCEDURE DIVISION.
MOVE 'ITM042' TO WS-SEARCH-CODE
MOVE 0 TO WS-FOUND-IDX
PERFORM VARYING WS-IDX FROM 1 BY 1 UNTIL WS-IDX > 100
IF WS-ITEM-CODE(WS-IDX) = WS-SEARCH-CODE
MOVE WS-IDX TO WS-FOUND-IDX
EXIT PERFORM *> 発見次第ループを即時終了
END-IF
END-PERFORM
IF WS-FOUND-IDX > 0
DISPLAY '見つかりました: 位置=' WS-FOUND-IDX
ELSE
DISPLAY '見つかりませんでした'
END-IF.
*> EXIT PERFORM CYCLE: 当回の残り処理をスキップして次の繰り返しへ進む(continue相当)
WORKING-STORAGE SECTION.
01 WS-IDX PIC 9(3).
01 WS-DATA-TBL.
05 WS-DATA PIC S9(7)V99 OCCURS 50 TIMES.
01 WS-POSITIVE-SUM PIC 9(9)V99 VALUE 0.
PROCEDURE DIVISION.
PERFORM VARYING WS-IDX FROM 1 BY 1 UNTIL WS-IDX > 50
*> 負の値はスキップ(正の値だけ合計)
IF WS-DATA(WS-IDX) <= 0
EXIT PERFORM CYCLE *> 次の繰り返しへ
END-IF
ADD WS-DATA(WS-IDX) TO WS-POSITIVE-SUM
END-PERFORM
DISPLAY '正の値の合計: ' WS-POSITIVE-SUM.
PERFORM THRU(段落範囲の実行)
PERFORM THRU は指定した段落から別の段落まで連続して実行します。複数の段落をひとまとまりの処理として呼び出すときに使います。
PROCEDURE DIVISION.
MAIN-PROC.
PERFORM OPEN-FILES THRU READ-FIRST-RECORD
PERFORM PROCESS-LOOP UNTIL WS-EOF
PERFORM CLOSE-FILES
STOP RUN.
OPEN-FILES.
OPEN INPUT TRANS-FILE
OPEN OUTPUT REPORT-FILE.
INIT-COUNTERS.
MOVE ZEROS TO WS-COUNT WS-TOTAL.
READ-FIRST-RECORD.
READ TRANS-FILE
AT END SET WS-EOF TO TRUE
END-READ.
*> PERFORM OPEN-FILES THRU READ-FIRST-RECORD で
*> OPEN-FILES → INIT-COUNTERS → READ-FIRST-RECORD の順に実行
PROCESS-LOOP.
PERFORM PROCESS-RECORD
READ TRANS-FILE
AT END SET WS-EOF TO TRUE
END-READ.
CLOSE-FILES.
CLOSE TRANS-FILE REPORT-FILE.
PERFORM A THRU B では、A段落から始まりB段落の最後のEXIT.まで、その間にあるすべての段落が順に実行されます。間に意図しない段落が挟まっていた場合も実行されるため、段落の並び順を把握しておく必要があります。大規模なプログラムでは意図しない段落の実行が起きやすいため、THRUの範囲は最小限にしてEXIT.で明示的に終端を示すことを推奨します。
業務でよく使う実践パターン
ファイル読み込みループ(最も基本的なバッチパターン)
COBOLバッチ処理の基本形です。AT END/NOT AT ENDを使ったファイル全件読み込みパターンです。
IDENTIFICATION DIVISION.
PROGRAM-ID. FILE-AGG.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT SALES-FILE ASSIGN TO 'SALES.DAT'
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS WS-FILE-STATUS.
DATA DIVISION.
FILE SECTION.
FD SALES-FILE.
01 SALES-RECORD.
05 SR-DATE PIC X(8).
05 SR-DEPT-CODE PIC X(4).
05 SR-AMOUNT PIC 9(9)V99.
WORKING-STORAGE SECTION.
01 WS-FILE-STATUS PIC X(2).
01 WS-EOF-FLG PIC X(1) VALUE 'N'.
88 WS-EOF VALUE 'Y'.
01 WS-TOTAL-AMT PIC 9(12)V99 VALUE 0.
01 WS-REC-COUNT PIC 9(7) VALUE 0.
PROCEDURE DIVISION.
MAIN.
OPEN INPUT SALES-FILE
IF WS-FILE-STATUS NOT = '00'
DISPLAY 'ファイルOPENエラー: ' WS-FILE-STATUS
MOVE 8 TO RETURN-CODE
STOP RUN
END-IF
*> 先読み(プライミングリード)
READ SALES-FILE
AT END SET WS-EOF TO TRUE
END-READ
PERFORM UNTIL WS-EOF
ADD 1 TO WS-REC-COUNT
ADD SR-AMOUNT TO WS-TOTAL-AMT
PERFORM PROCESS-RECORD
READ SALES-FILE
AT END SET WS-EOF TO TRUE
END-READ
END-PERFORM
CLOSE SALES-FILE
DISPLAY '処理件数: ' WS-REC-COUNT
DISPLAY '合計金額: ' WS-TOTAL-AMT
STOP RUN.
PROCESS-RECORD.
*> レコードごとの処理(省略)
EXIT.
配列への累積集計(部門別集計)
WORKING-STORAGE SECTION.
01 WS-DEPT-COUNT PIC 9(2) VALUE 5.
01 WS-DEPT-TABLE.
05 WS-DEPT-ENTRY OCCURS 5 TIMES INDEXED BY WS-DEPT-IDX.
10 WS-DEPT-CODE PIC X(4).
10 WS-DEPT-SALES PIC 9(12)V99 VALUE 0.
10 WS-DEPT-CNT PIC 9(7) VALUE 0.
01 WS-SEARCH-IDX PIC 9(2).
01 WS-FOUND-FLG PIC X(1).
88 DEPT-FOUND VALUE 'Y'.
PROCEDURE DIVISION.
*> テーブルの初期化
PERFORM VARYING WS-SEARCH-IDX FROM 1 BY 1
UNTIL WS-SEARCH-IDX > WS-DEPT-COUNT
MOVE SPACES TO WS-DEPT-CODE(WS-SEARCH-IDX)
MOVE ZEROS TO WS-DEPT-SALES(WS-SEARCH-IDX)
MOVE ZEROS TO WS-DEPT-CNT(WS-SEARCH-IDX)
END-PERFORM
*> 売上データ読み込みループ(省略: SR-DEPT-CODE, SR-AMOUNTが読み込まれている想定)
PERFORM UNTIL WS-EOF
*> 部門コードを検索
MOVE 'N' TO WS-FOUND-FLG
PERFORM VARYING WS-SEARCH-IDX FROM 1 BY 1
UNTIL WS-SEARCH-IDX > WS-DEPT-COUNT
IF WS-DEPT-CODE(WS-SEARCH-IDX) = SR-DEPT-CODE
MOVE 'Y' TO WS-FOUND-FLG
ADD SR-AMOUNT TO WS-DEPT-SALES(WS-SEARCH-IDX)
ADD 1 TO WS-DEPT-CNT(WS-SEARCH-IDX)
EXIT PERFORM
END-IF
END-PERFORM
*> 次レコード読み込み(省略)
END-PERFORM
*> 結果出力
PERFORM VARYING WS-SEARCH-IDX FROM 1 BY 1
UNTIL WS-SEARCH-IDX > WS-DEPT-COUNT
DISPLAY WS-DEPT-CODE(WS-SEARCH-IDX)
': ' WS-DEPT-CNT(WS-SEARCH-IDX) '件'
' ' WS-DEPT-SALES(WS-SEARCH-IDX) '円'
END-PERFORM.
リトライループ(API呼び出し・タイムアウト対策)
WORKING-STORAGE SECTION.
01 WS-RETRY-MAX PIC 9(1) VALUE 3.
01 WS-RETRY-CNT PIC 9(1) VALUE 0.
01 WS-API-STATUS PIC X(2).
88 API-SUCCESS VALUE '00'.
88 API-TIMEOUT VALUE '08'.
PROCEDURE DIVISION.
PERFORM WITH TEST AFTER
UNTIL API-SUCCESS OR WS-RETRY-CNT >= WS-RETRY-MAX
PERFORM CALL-EXTERNAL-API
ADD 1 TO WS-RETRY-CNT
IF NOT API-SUCCESS AND WS-RETRY-CNT < WS-RETRY-MAX
DISPLAY 'リトライ ' WS-RETRY-CNT '回目...'
*> 実際の処理では CALL 'SLEEP' などを挿入
END-IF
END-PERFORM
IF NOT API-SUCCESS
DISPLAY 'API呼び出し失敗(' WS-RETRY-MAX '回リトライ済)'
MOVE 12 TO RETURN-CODE
GOBACK
END-IF
DISPLAY 'API呼び出し成功'.
ページング出力(帳票の改ページ)
WORKING-STORAGE SECTION.
01 WS-PAGE-NO PIC 9(4) VALUE 1.
01 WS-LINE-NO PIC 9(2) VALUE 0.
01 WS-LINES-PER-PAGE PIC 9(2) VALUE 50.
01 WS-IDX PIC 9(7) VALUE 0.
PROCEDURE DIVISION.
PERFORM PRINT-HEADER
MOVE 0 TO WS-LINE-NO
PERFORM UNTIL WS-EOF
*> ページ満杯になったら改ページ
IF WS-LINE-NO >= WS-LINES-PER-PAGE
WRITE REPORT-RECORD FROM WS-PAGE-BREAK-LINE
ADD 1 TO WS-PAGE-NO
PERFORM PRINT-HEADER
MOVE 0 TO WS-LINE-NO
END-IF
WRITE REPORT-RECORD FROM SALES-RECORD
ADD 1 TO WS-LINE-NO
READ SALES-FILE
AT END SET WS-EOF TO TRUE
END-READ
END-PERFORM.
PRINT-HEADER.
MOVE WS-PAGE-NO TO WS-HDR-PAGE
WRITE REPORT-RECORD FROM WS-HEADER-LINE
MOVE 0 TO WS-LINE-NO.
EXIT.
よくある落とし穴と対策
| 落とし穴 | 問題 | 対策 |
|---|---|---|
| 無限ループ | UNTIL条件の変数がループ内で更新されないため条件が永久にFALSEのまま | ループ内で必ずUNTIL条件に影響する変数を更新する。またはループカウンタに上限を設ける |
| OFF-BY-ONE(1ずれ) | UNTIL WS-IDX > 10 とすべきところを = 10 にして最後の要素を処理しない | 「>最大値」か「>= 最大値+1」で終了条件を書く。配列の先頭は1(0ではない) |
| VARYINGカウンタのループ後の値 | PERFORM VARYING WS-IDX FROM 1 BY 1 UNTIL WS-IDX > 10 が終了した後、WS-IDXの値は11(終了条件を満たした値) | ループ後にWS-IDXを使う場合は、ループ内で最後に処理した値を別変数に退避しておく |
| TEST AFTERの意図しない1回実行 | TEST AFTERを使うと条件が最初から真でも1回は実行される | 事前に条件が真になる可能性があるループにはTEST BEFORE(デフォルト)を使う |
| ファイルループでのプライミングリード忘れ | PERFORM UNTIL WS-EOFの前にREADを1回書かないと、最初のレコードが2回処理されることがある | ループ開始前に先読み(プライミングリード)を必ず行う |
よくある質問
PERFORM VARYING WS-IDX FROM WS-MAX BY -1 UNTIL WS-IDX < 1とすると配列の末尾から先頭に向かって処理できます。配列の逆順表示や後ろから検索する場合に使います。まとめ
PERFORM文のループ形式と使い分けを整理します。
| 形式 | 説明 |
|---|---|
| PERFORM TIMES | 固定回数ループ。カウンタ不要でシンプルに書ける |
| PERFORM UNTIL(TEST BEFORE) | ゼロ回実行あり。ファイル読み込みなど条件が最初から成立する可能性があるループ |
| PERFORM UNTIL(TEST AFTER) | 最低1回は必ず実行。入力要求・リトライなど |
| PERFORM VARYING | 配列処理の基本。FROM/BY/UNTILでカウンタを自動制御 |
| PERFORM VARYING … AFTER | 多次元配列の多重ループを1文で記述できる |
| EXIT PERFORM | ループを途中で終了(break相当) |
| EXIT PERFORM CYCLE | 当回のループをスキップして次へ(continue相当) |
| PERFORM THRU | 複数の段落をまとめて実行。範囲の管理に注意 |
TEST BEFORE/AFTERの選択とVARYING AFTERの多重ループは実務でよく使うにもかかわらず見落とされがちな機能です。配列処理や複数ファイルの同時処理の設計時に活用してみましょう。
ループで扱う配列の定義についてはOCCURS句の使い方を、条件判定についてはIF文の完全ガイドも合わせてご参照ください。
