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

【現場の流儀】PL/IのON ENDFILEでハマらないための「終了制御」の鉄則

メインフレームの現場で長く戦っていると、若手から「なぜかファイル読み込みループが終わらない」「EOF検知が正しく動作しない」という相談をよく受ける。

PL/Iの`ON ENDFILE`ユニットは、C言語の`feof()`やJavaの`hasNext()`に慣れた世代には、いささか独特な「非同期的な割り込み」のように映るかもしれない。しかし、この仕組みこそがPL/Iの強力な制御構造であり、正しく扱えばバッチ処理の堅牢性は格段に上がる。

今日は、順次ファイル(QSAM)やVSAMを読み込む際の、「フラグ制御によるループ脱出」の定石を伝授しよう。

1. なぜ「ONユニット」を使うのか

PL/Iの歴史を振り返れば、`ON ENDFILE`は単なるエラーハンドリングではなく、システムがファイル終了を検知した瞬間に、メインロジックとは別の「例外処理」として呼び出される仕組みだ。

ここでやってはいけないのが、`ON`ユニット内でいきなり`GO TO`でメインループの外へ飛び出すことだ。プログラムの構造を破壊し、保守性を損なう悪手である。現場の標準として推奨するのは、「フラグ変数によるステータス管理」だ。

2. 実践的なコーディング・パターン

以下に、VSAM(またはQSAM)を読み込み、フラグを用いてループを綺麗に終了させる標準的なテンプレートを示す。

/i
SAMPLE_BATCH: PACKAGE;

/

  • メインプロシージャ:OPTIONS(MAIN)はプログラムのエントリポイント
  • 必要なファイル定義やデータ属性はここに集約する

/
MAIN_PROC: PROCEDURE OPTIONS(MAIN);

DCL INFILE FILE RECORD INPUT; / 入力ファイル /
DCL EOF_FLG BIT(1) INIT(‘0’B); / 終了検知フラグ:’1’Bで終了 /

/ ファイル終了時のONユニット定義 /
ON ENDFILE(INFILE) BEGIN;
EOF_FLG = ‘1’B;
END;

OPEN FILE(INFILE);

/ 読み込みループ /
DO WHILE(^EOF_FLG);
READ FILE(INFILE) INTO(RECORD_AREA);

/ フラグが立っていないか再確認(ガード節) /
IF EOF_FLG THEN LEAVE;

/ ここに実務ロジックを記述 /
CALL PROCESS_LOGIC(RECORD_AREA);
END;

CLOSE FILE(INFILE);

END MAIN_PROC;

/ 処理用サブプロシージャの例 /
PROCESS_LOGIC: PROCEDURE(REC);
DCL REC CHAR(80);
/ 業務処理をここに記述 /
END PROCESS_LOGIC;

END SAMPLE_BATCH;

3. このコードにおける「こだわり」と現場のコツ

① `BEGIN` … `END` ブロックの徹底

`ON ENDFILE(INFILE) EOF_FLG = ‘1’B;` と一行で書くことも可能だが、実務では将来的な拡張(例えばログ出力やカウンターのリセットなど)を見越して、必ず`BEGIN`ブロックを使う習慣をつけよう。

② `DO WHILE(^EOF_FLG)` のガード

`READ`文の直後に `IF EOF_FLG THEN LEAVE;` を入れている点に注目してほしい。これは非常に重要だ。なぜなら、`READ`文が実行された瞬間にEOFに到達した場合、直ちに`ON`ユニットが起動するが、その後の処理で誤ったデータを加工しないよう、即座にループを抜ける「防御」が必要だからだ。

③ `PACKAGE`の活用

昔のPL/Iプログラムは、一つのソースにすべてを詰め込みがちだった。しかし、現代的なメインフレーム開発では、`PACKAGE`を用いてスコープを明確に区切ることが、コンパイル単位の整理にもなり、デバッグ時のメモリ監視も容易になる。

4. トラブルシューティング:ハマりやすいポイント

  • ONユニットの定義位置: `OPEN`文よりも前に`ON`ユニットを配置することを忘れないこと。`OPEN`の後に配置すると、最悪の場合、読み込み開始直後のEOFを検知できず、無限ループや異常終了(ABEND)を招く。
  • フラグの初期化: 同じタスク内で複数のファイルを順次読み込む場合、フラグの初期化忘れは致命的だ。`DO`ループに入る直前に必ず初期化されているか、常に意識すること。
  • VSAMの場合: VSAMのキー順読み込みなどで`READ`の代わりに`READ SET`を使用する場合、ポインタの扱いに注意が必要だが、基本構造(EOF検知→フラグ変更→ループ脱出)は変わらない。

最後に:シニアエンジニアからの助言

PL/Iは古い言語と言われることもあるが、その言語仕様には「データに対する誠実さ」が詰まっている。`ON ENDFILE`を使いこなすということは、プログラムの「正常系」と「異常系(終了処理)」を明確に切り分けるという、システム開発の基本原則を体現することに他ならない。

後輩諸君、単に動くコードを書くだけではなく、「誰が読んでも読み込み終了のタイミングが論理的に追えるコード」を目指してほしい。それが大規模バッチの保守における、君たちの最大の武器になるはずだ。

また何か不明点があればいつでも聞いてくれ。設計の現場で待っている。

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