【実務・中級編】DOループにおけるITERATEおよびLEAVE文の制御フロー – PL/Iの基本構文とデータ制御実践ガイド

PL/Iのループ制御を極める:ITERATEとLEAVEで「スパゲッティ」を未然に防ぐ

メインフレームのバッチ改修で最も恐ろしいのは、何十年も前に書かれた「解読不能なGOTO地獄」です。特に、VSAMファイルを読み込みながら特定の条件で処理をスキップしたり、エラー時に強制終了したりするロジックにおいて、`ITERATE`と`LEAVE`を正しく使いこなせているかどうかは、保守性の分かれ道となります。

今日は、現場の若手がやりがちな「IF文のネストの深海」を脱出し、可読性の高いコードを書くための制御フローの極意を伝授します。

1. 基本の構造:PACKAGEとPROCEDUREの作法

まず前提として、現代のPL/Iプログラムは`PACKAGE`で括り、その中に`PROCEDURE OPTIONS(MAIN)`を配置するのが基本です。これにより、変数のスコープが明確になり、コンパイル単位での制御が容易になります。

1
/ プログラムの基本構造 /
MY_BATCH_JOB: PACKAGE;

MAIN_PROC: PROCEDURE OPTIONS(MAIN);
/ ここに変数を宣言 /
DCL EOF_FLAG BIT(1) INIT(‘0’B);

/ メインのループ処理 /
DO WHILE(^EOF_FLAG);
/ VSAM読み込み処理など /
END;
END MAIN_PROC;

END MY_BATCH_JOB;

2. ITERATEとLEAVE:制御フローの「外科手術」

`ITERATE`は「次へスキップ」、`LEAVE`は「即座に離脱」です。これらを適切に使うことで、ネストを浅く保つことができます。

特に注目すべきは、ラベル指定による制御範囲の明確化です。ネストされたDOループ内では、単に`LEAVE`と書くだけでは「どのループを抜けるのか」が曖昧になり、バグの温床になります。

実践:ラベル付き制御のサンプル

VSAMファイルを読み込み、取引金額が0の場合はスキップ(ITERATE)、異常終了フラグが立った場合は即座にループ全体を終了(LEAVE)させる実例です。

1
PROCESS_RECORDS: PROCEDURE;
DCL TRANSACTION_AMT DEC FIXED(15,2);
DCL ABEND_CONDITION BIT(1) INIT(‘0’B);

/ 外側のループにラベルを付与 /
RECORD_LOOP: DO WHILE(NOT_EOF);

GET FILE(VSAM_IN) INTO(RECORD_AREA);

/ 条件付きスキップ:金額0は処理不要のため次のレコードへ /
IF RECORD_AMT = 0 THEN
ITERATE RECORD_LOOP;

/ 業務ロジック /
CALL CALCULATE_LOGIC(RECORD_AREA);

/ 致命的なエラーチェック:即座にループを脱出 /
IF ABEND_CONDITION THEN
LEAVE RECORD_LOOP;

END RECORD_LOOP;
END PROCESS_RECORDS;

3. 注意すべき「ONユニット」との共存

ここがメインフレームエンジニアの腕の見せ所ですが、`LEAVE`や`ITERATE`と`ON-UNIT`(特に`ON ENDFILE`や`ON CONVERSION`)を混在させる際は注意が必要です。

`ON-UNIT`内で実行される処理から`LEAVE`で外側のループを抜けることはできません。`ON-UNIT`はあくまで割り込み処理です。エラーが発生した場合は、フラグを立ててメインのループフローに戻し、メインループ側で`LEAVE`を判断させるのが、システムの安全性を高めるコーディング標準です。

  • NG例: `ON ENDFILE(SYSIN) LEAVE MAIN_LOOP;` (これはコンパイルエラーになるか、予測不能な挙動を招きます)
  • OK例: `ON ENDFILE(SYSIN) EOF_FLAG = ‘1’B;` (フラグを立てて、メインループ側の`DO WHILE`条件で判定させる)

4. ベテランからのアドバイス:デバッグのコツ

もしあなたが「なぜかループが終わらない」「意図しないレコードでスキップされている」という状況に直面したら、以下のBUILTIN関数を活用して変数の遷移を追いかけてください。

  • `LINENO` / `PROCEDURE`: `PUT SKIP LIST`で現在地を特定する際、これらを併用するとログが劇的に読みやすくなります。
  • `UNSPEC`: ファイルから読み込んだレコードが文字化けしていないか、あるいは予期せぬ制御コードが含まれていないかを確認するのに必須です。

「コードは書き手のためではなく、半年後の自分がメンテナンスするためにある」。この言葉を忘れないでください。`LEAVE`や`ITERATE`を多用してネストを浅く保つことは、単なるテクニックではなく、後任者への「思いやり」なのです。

今日の話が、皆さんの次回のバッチ改修の一助となれば幸いです。もし具体的な制御フローで迷うことがあれば、いつでも相談してください。メインフレームの深淵は、まだまだ奥が深いですよ。

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