導入
メインフレームでのバッチ処理において、可変長レコードから特定のキーワードを抽出する処理は日常茶飯事です。特にPL/I環境で文字列の解析を行う際、INDEX関数は最も頻繁に利用される組み込み関数の一つです。本稿では、INDEX関数の正しい仕様と、現場で発生しやすい「0(未検出)」の取り扱いミスを防ぐための実装テクニックを解説します。
基礎知識
PL/IのINDEX関数は、ソース文字列(SOURCE)の中から検索対象文字列(KEYWORD)を検索し、最初に出現した位置を整数(FIXED BINARY)で返します。
重要な点は、PL/Iの文字列インデックスが「1から始まる」ことです。もしキーワードが文字列の先頭にあれば「1」が返り、見つからない場合は「0」が返ります。この「0」を適切に処理しないと、後続のSUBSTR関数などで無効なオフセットを指定してしまい、プログラム異常終了(S0C1やS0C4等)の原因となるため注意が必要です。
実装/解決策
実務では、単に位置を取得するだけでなく、その結果を使って文字列を切り出す処理がセットになります。検索開始位置を動的に変えることで、同一文字列内の複数出現箇所をループで走査することも可能です。
サンプルプログラム
以下のコードは、レコードから特定のタグ(ここでは’ID:’)を検索し、その後の値を抽出する一般的な実装例です。
/ サンプル:レコード内のID抽出処理 /
DCL SOURCE_REC CHAR(80) VARYING INIT(‘TYPE=USER;ID=12345;STATUS=ACTIVE’);
DCL KEYWORD CHAR(3) INIT(‘ID:’);
DCL POS FIXED BIN(15);
DCL ID_VALUE CHAR(5);
/ INDEX関数でキーワードの位置を特定 /
POS = INDEX(SOURCE_REC, KEYWORD);
/ 戻り値が0の場合の安全策(重要:異常終了を防ぐ) /
IF POS > 0 THEN DO;
/ キーワードの長さ分を足して、値の開始位置を算出 /
/ 抽出:INDEXで見つけた位置 + キーワード長 から5バイト /
ID_VALUE = SUBSTR(SOURCE_REC, POS + LENGTH(KEYWORD), 5);
PUT SKIP LIST(‘抽出されたID:’ || ID_VALUE);
END;
ELSE DO;
PUT SKIP LIST(‘エラー:キーワードが見つかりませんでした’);
END;
応用・注意点
1. 検索開始位置の活用: 第3引数を指定する際は、現在位置にキーワード長を加算した値を指定することで、ループ処理による全件検索が可能になります。
2. 空文字の挙動: 検索対象のKEYWORDが空文字(”)の場合、INDEX関数は「1」を返します。予期せぬ挙動を防ぐため、検索前にKEYWORDが空でないことを保証するチェックルーチンを設けるのが、堅牢なシステム設計の基本です。
3. 比較の罠: 戻り値が1から始まるという特性上、IF POS = 0 THEN … という条件分岐は、他の言語(0ベースのindexOf)から移行してきた技術者が最もミスを犯しやすい箇所です。必ず「0」を未検出として明示的に扱う習慣をつけましょう。

コメント