【入門編】PIC ‘B’および’/’による編集文字の挿入とデータ長 – PL/Iの基本構文とデータ制御実践ガイド

こんにちは!メインフレームの世界へようこそ。
JavaやCOBOLといった他の言語の経験がある方にとって、レガシーな世界、特にPL/I(ピーエルアイ)のコードを初めて目にしたときは、「おや、なんだか見慣れない記号がたくさんあるぞ……」と少し身構えてしまうかもしれませんよね。

でも、安心してください。怖がる必要は全くありません。
今回は、PL/Iのデータ制御において非常にユニークで、かつ実務の帳票出力や画面表示でめちゃくちゃお世話になる「ピクチャ編集(PIC)」、その中でも特に日付や口座番号の整形に欠かせない`B`(空白挿入)と`/`(スラッシュ挿入)に焦点を当てて、データ長の変化とメモリ確保の裏側を優しく紐解いていきたいと思います。

Javaの`String.format`やCOBOLの`PICTURE`句とはひと味違う、PL/Iならではのスマート(かつ時に奥深い)世界を一緒に覗いてみましょう!

1. 他言語から来た人が驚く? PL/Iのピクチャ編集とは

Javaで日付(例: `20231025`)を `2023/10/25` のようにスラッシュ区切りに変えたい時、みなさんはどう書きますか?
きっと `String.format` を使ったり、部分文字列を切り出して結合したりしますよね。COBOLなら、`PIC 9999/99/99` のような編集句おなじみの機能を使います。

PL/Iにも、これとよく似たピクチャ句(PICTURE / PIC)という強力な機能があります。
変数にただ数字を詰め込むだけでなく、「このデータはこういう見た目で扱いたいんです」という“お召し物(型・レイアウト)”をあらかじめ着せてあげるイメージです。

たとえば、次のような数字の羅列があるとします。

  • 生年月日: `19850415` (8桁の数字)
  • 口座番号: `1234567890` (10桁の数字)

これをそのまま画面や帳票に出すと、人間にとってはちょっと見づらいですよね。そこでPL/Iのピクチャ編集の出番です。

2. ‘B’ と ‘/’ が織りなすマジック:文字の挿入とデータ長の変化

ここで今日のメインテーマである「データ長の変化」についてお話しします。これが、初心者の方や他言語出身者が一番ハマりやすいポイントなんです。

結論から言いましょう。
PL/Iでピクチャ編集文字(`B` や `/` など)を挟むと、その変数の「文字数(データ長)」は膨らみます。

文字通り、元のデータに「空白(BlankのB)」や「スラッシュ(`/`)」という文字を物理的に埋め込むからです。

データの例え話:お洋服のサイズ変更

イメージしてみてください。
あなたは「数字専用のタイトなパンツ(8文字分のメモリ)」を持っています。そこに、無理やりベルトの飾り(スラッシュ `/`)や、ゆとりの空間(空白 `B`)をあとからねじ込もうとしています。
当然、パンツの布地(必要なメモリの長さ)は、その分だけ広げなければボタンが閉まりませんよね?

PL/Iのコンパイラもこれと同じことをやっています。

  • 元のデータ: `8` バイトの数字
  • 編集後の見た目: `10` バイト(スラッシュが2つ入るため)

この「メモリ上のサイズ」と「見栄えのサイズ」が頭の中でごっちゃになると、「あれ? 項目がズレるぞ」「領域オーバー(S0C4やデータ例外)になった!」というレガシー特融のトラブルにつながるのです。

3. 実践!PL/Iコードで見る `B` と `/` の使い方

百聞は一見にしかず。実際にPL/Iでどのように書くのか、サンプルコードを見てみましょう。
実務のバッチプログラムを想定して、大文字ベースで記述しています。

——————————————————————

  • ピクチャ編集(B および /)のサンプルプログラム

——————————————————————
DATE_EDIT_SAMPLE: PROC OPTIONS(MAIN);

— 1. 変数の定義 —

  • 編集前:純粋な文字データ(8桁の数字)

DCL W_RAW_DATE CHAR(8) INIT(‘19850415’);

  • 編集後①:スラッシュで日付を区切る(YYYY/MM/DD)
  • ピクチャ ‘9999/99/99’ は、全体で 10 桁の長さになります!

DCL W_FMT_DATE PICTURE ‘9999/99/99’;

  • 編集後②:B(空白)を使って文字の間にスペースを入れる(12 34 56)
  • ’99B99B99′ は、全体で 8桁の数字 + 2個の空白 = 10 桁になります!

DCL W_FMT_CODE PICTURE ’99B99B99′;

— 2. データの代入と編集の実行 —

  • PL/Iでは、編集ピクチャ変数へ代入するだけで自動的に整形されます

W_FMT_DATE = W_RAW_DATE;
W_FMT_CODE = ‘123456’; 適当な6桁の数値を代入

— 3. 結果の確認(出力) —
PUT SKIP EDIT (‘日付整形結果 : ‘, W_FMT_DATE) (A, A);
PUT SKIP EDIT (‘コード整形結果: ‘, W_FMT_CODE) (A, A);

END DATE_EDIT_SAMPLE;

コードのここがポイント!

1. `W_FMT_DATE PICTURE ‘9999/99/99’` の長さ

  • `9` が8個、`/` が2個で、トータル10文字分の領域がメモリ上に確保されます。
  • 元データ `W_RAW_DATE` は `CHAR(8)` ですが、これを `W_FMT_DATE` に代入すると、PL/Iがよしなに位置を合わせて `1985/04/15` と埋め込んでくれます。

2. `B`(空白)の働き

  • `99B99B99` の `B` は、その場所に半角スペース(`X’40’`)を挿入せよ、という指示です。
  • 「文字と文字の間にちょっと隙間が欲しいな」という時に、わざわざ文字列連結関数を使わなくても、ピクチャ一撃で綺麗に整うので非常にスマートです。

4. メモリ確保時の注意点:マイグレーション・バッチ改修で泣かないために

さて、ここからがシニアアーキテクトからの現場の知見を込めたアドバイスです。
Javaやオープン系からメインフレームの移行(マイグレーション)に携わると、次のような設計書やコピーブック(データ定義)によく遭遇します。

> 「出力ファイルのレコード長が変わらないように、編集後の項目を詰め込んでおいてね」

ここで、元の `CHAR(8)` のつもりでプログラムを書いてしまい、うっかり `PICTURE ‘9999/99/99’` の変数をそのままファイル出力用の構造体に組み込んでしまうと……。
出力ファイルのレコード長が意図せず 2バイト増えてしまいます!

COBOLであれば、コンパイラやレイアウト定義で厳密にパディングやサイズが管理されますが、PL/Iのピクチャ変数は「編集文字も文字数(バイト数)としてカウントされる」という仕様が強く働きます。

  • `PICTURE ‘9999/99/99’` = 10 バイト
  • `PICTURE ‘X(4)B(3)X(4)’` などの場合も同様に空白分の長さが膨らむ

もしファイルレイアウトや通信電文の長さを厳密に守る必要がある場合は、編集前のデータはあくまでワークエリア(作業領域)のピクチャ変数で扱い、最終的にファイルへ書き出す直前に、指定された長さの `CHAR` 型のエリアにMOVE(代入)し直す、といった一手間が必要になるケースがあります。

この「見た目の文字数」と「実際のバイト数(データ長)」のズレを見落とすことが、レガシー移行におけるデータ化けやABEND(異常終了)の隠れた原因第一位だったりするのです。

まとめ

いかがでしたでしょうか?
今回はPL/Iのピクチャ編集における `B` と `/` を通して、データ長の変化とメモリ確保の注意点についてお話ししました。

  • 編集文字(`B`や`/`)を入れると、その分データ長(必要なメモリ)は増える!
  • PL/Iのピクチャ変数は、代入するだけで自動的にカッコよく整形してくれる頼もしい相棒。
  • ただし、ファイル出力や電文レイアウトに組み込むときは、バイト数の変化に要注意!

「レガシー言語のルールってなんだか厳しそう……」と感じたかもしれませんが、仕組みさえ分かってしまえば、PL/Iはコードを非常に簡潔に書かせてくれるエレガントな言語です。
一つひとつの仕様を怖がらずに、ぜひご自身のプロジェクトのコードでも確認してみてくださいね。あなたのメインフレームライフを、これからも応援しています!

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