【実務・中級編】ON ENDFILEユニットによるファイル終了制御 – PL/Iの基本構文とデータ制御実践ガイド

PL/Iの「ON ENDFILE」を使いこなす:基幹バッチの制御フローを完璧に制御する

やあ。今日もメインフレームの迷宮でバッチプログラムと格闘している諸君、お疲れ様。

PL/Iという言語は、COBOLに比べれば自由度が高く、かつC言語のような無骨な力強さも兼ね備えた、まさに「職人のための道具」だ。しかし、その強力な制御文である「ONユニット」を軽んじると、夜中の2時に障害対応で呼び出される羽目になる。

今日は、ストリーム入出力やレコード入出力において避けては通れない「ファイル終端(ENDFILE)の制御」について、現場の知見を交えて深掘りしていくぞ。

ON ENDFILE は単なる「終了処理」ではない

初心者がやりがちなミスは、`ON ENDFILE`を単なる「IF文の代わり」として使うことだ。だが、これは間違いだ。`ON ENDFILE`は、あくまで「例外発生時の制御をOS(PL/Iランタイム)に登録する」という宣言であることに注意してほしい。

ストリーム入出力の `GET FILE` や、レコード入出力の `READ` を実行した際、システムが物理的なEOF(End of File)を検知すると、その瞬間に制御が `ON` ユニットへ強制的にジャンプする。この「制御の飛び込み」を理解していないと、複雑なループ構造の中でどこで何が起きているのか追跡できなくなるんだ。

実装の勘所:コードで見る制御フロー

では、実務で使える標準的な実装例を見てみよう。VSAMファイル(KEYED)や順次ファイル(SEQUENTIAL)の読み込みでよくあるパターンだ。

/i
/——————————————————————-/
/ PROGRAM: BATCH01P (マスターファイル読み込みバッチ) /
/ 説明: ON ENDFILEによるループ制御の標準的な実装例 /
/——————————————————————-/
BATCH01P: PROCEDURE OPTIONS(MAIN);

DCL MSTR_FILE FILE RECORD INPUT; / VSAM等のレコードファイル /
DCL EOF_FLAG BIT(1) INIT(‘0’B); / ループ終了フラグ /

/ 1. ONユニットの定義(重要: ループの前で宣言しておく) /
ON ENDFILE(MSTR_FILE) BEGIN;
EOF_FLAG = ‘1’B; / フラグを立てて制御を戻す /
END;

OPEN FILE(MSTR_FILE);

/ 2. ファイル読み込みループ /
READ FILE(MSTR_FILE) INTO(MSTR_REC_AREA);

DO WHILE(¬EOF_FLAG);
/ — ここでビジネスロジックを記述する — /
PUT SKIP LIST(‘処理中レコードキー:’ || MSTR_REC_KEY);

READ FILE(MSTR_FILE) INTO(MSTR_REC_AREA);
END;

CLOSE FILE(MSTR_FILE);
PUT SKIP LIST(‘バッチ処理が正常に完了しました。’);

END BATCH01P;

ここで押さえておきたいポイント

1. 制御をフラグで戻す: `ON ENDFILE` の中でいきなり `STOP` や `EXIT` を呼ぶのは推奨しない。これだと、終了処理(ファイルのクローズやログ出力など)が正しく行われない可能性があるからだ。「フラグを立ててループを自然に終了させる」のが、最も堅牢でトラブルが少ない。
2. READの順序: `READ` をループの先頭と末尾に書くこのスタイルは、定石中の定石だ。最初に1件読んでからループに入り、ループ内で次のレコードを読む。これにより、空ファイルだった場合の制御もきれいに処理できる。
3. ONユニットのスコープ: `ON` ユニットは、プログラムの処理範囲(ブロックスコープ)全体で有効だ。もし途中で別のファイルを読み込む場合は、`REVERT` 文を使って一度無効化するか、ファイルごとに異なるONユニットを適切に制御する必要がある。

ベテランからのアドバイス:デバッグでハマらないために

現場の保守でよく見る悲劇は、「意図しないタイミングでのEOF検知」だ。

例えば、VSAMファイルで「レコードの読み込み」と「キー検索」が混在している場合、期待していたレコードが見つからなかったのか、物理的にEOFに達したのかの区別がつかなくなることがある。

  • REVERTの活用: 複数のファイルを扱う場合、一つのファイルが終わったら必ず `REVERT ONCODE(x)` や `REVERT ENDFILE(FILE_NAME)` を実行して、不要なONユニットを外す癖をつけろ。
  • ONCODEの確認: もし例外が発生した理由を詳細に特定したいなら、`ONCODE` ビルトイン関数を使え。`GET` や `READ` がなぜ失敗したのか、システムが吐き出したエラーコードを拾うことで、原因の切り分けが格段に早くなる。

最後に

PL/IのONユニットは、使いこなせばこれほど強力な武器はない。例外処理という「システムの綻び」を、美しいコードで制御下に置く。これこそが、メインフレームエンジニアの矜持だ。

難解な仕様に見えても、突き詰めればOSとプログラムの対話だと思えばいい。もし、現場で `ON` ユニットの挙動に迷ったら、まずは基本に立ち返り、制御の流れを紙に書き出してみることだ。

諸君、今夜もバッチの完走を祈っている。また次の現場で会おう。

タイトルとURLをコピーしました