PL/Iの「PICTURE属性」で帳票出力に自信を持つ!ゼロサプレスと編集の魔法
こんにちは!長年メインフレームの深淵でシステムアーキテクトをしています。
JavaやCOBOLからメインフレームの世界に足を踏み入れた皆さん、ようこそ。PL/I(ピーエル・アイ)という言語、一見すると「歴史を感じる構文だな…」と身構えてしまうかもしれませんね。でも大丈夫。PL/Iは、非常に柔軟で、かつ論理的な言語です。
今日は、そんなPL/Iの門を叩いた皆さんが、最初に出会う「ちょっと不思議な呪文」、PICTURE(ピクチャ)属性についてお話しします。
—
PICTURE属性って何者?
他の言語でいう「フォーマット指定」に近いのですが、PL/IのPICTURE属性は、変数の「見た目」を定義すると同時に、そのデータが「どう格納されているか」という素性まで規定してしまう強力なツールです。
特に、帳票や出力ファイルを作成する際、数値を綺麗に見せるための`9`と`Z`の使い分けは、まさに「メインフレームのたしなみ」と言えるでしょう。
1. ‘9’ は「数字が必ず入る場所」
`9`は、その桁に必ず数字が埋まることを保証します。例えば、`PICTURE ‘999’` と定義した変数に `5` を入れると、内部では `005` として扱われます。
2. ‘Z’ は「ゼロを隠す魔法(ゼロサプレス)」
ここが面白いところです。`Z`を使うと、数値の先頭にある不要なゼロをスペースに置き換えてくれます。金額を表示する際、「00001200円」と出るより「 1,200円」と出たほうが美しいですよね?この「0を消す」作業を自動でやってくれるのが `Z` なのです。
—
さっそくコードで確認してみましょう
実際に、数値を変数から出力用フォーマットへ変換するPL/Iプログラムを見てみましょう。
/i
/ メインプロシージャの宣言 /
SAMPLE: PROCEDURE OPTIONS(MAIN);
/ 内部計算用の数値変数(固定小数点) /
DCL AMOUNT FIXED DECIMAL(7) INIT(1200);
/ 出力用:9999で定義(先頭にゼロが残る) /
DCL OUT_FORMAT_1 PICTURE ‘9999’;
/ 出力用:ZZZ9で定義(先頭のゼロをスペースに置換) /
DCL OUT_FORMAT_2 PICTURE ‘ZZZ9’;
/ 値の転記(PL/Iは代入時に自動でPICTURE形式に変換してくれます) /
OUT_FORMAT_1 = AMOUNT;
OUT_FORMAT_2 = AMOUNT;
/ PUT LISTで画面やログに出力してみる /
PUT SKIP LIST(‘9の羅列:’, OUT_FORMAT_1); / 出力: 1200 /
PUT SKIP LIST(‘Zを使ったゼロサプレス:’, OUT_FORMAT_2); / 出力: 1200 /
/ もっと小さい値で試してみましょう /
AMOUNT = 50;
OUT_FORMAT_1 = AMOUNT;
OUT_FORMAT_2 = AMOUNT;
PUT SKIP LIST(‘9の羅列:’, OUT_FORMAT_1); / 出力: 0050 /
PUT SKIP LIST(‘Zを使ったゼロサプレス:’, OUT_FORMAT_2); / 出力: 50 /
END SAMPLE;
—
なぜこんな仕組みが必要なの?
Javaなどのモダンな言語では、`String.format(“%04d”, value)` のように出力時にメソッドを呼び出しますよね。しかし、メインフレームの世界では、「データそのものに表示形式(PICTURE)を持たせる」という文化が根付いています。
これには理由があります。
かつてメモリやストレージが非常に高価だった時代、データを「数値」として計算しつつ、出力する瞬間に「編集済みデータ」としてメモリ上に展開するこの仕組みは、CPU負荷を最小限に抑え、かつ定型的な帳票出力のミスを減らすための「先人の知恵」だったのです。
実務で役立つワンポイントアドバイス
- 「9」と「Z」の混在: `ZZZ9` という書き方はよく使います。これは「値が0の場合でも、最低1桁は表示する(最後の9があるから)」という意図です。もし `ZZZZ` と書くと、値が0の時にすべてスペースになってしまい、「何も表示されない」という事故が起きることがあるので注意してくださいね。
- PICTURE属性は数値として計算できない: ここが最大の落とし穴です。`PICTURE` で定義した変数は、あくまで「文字の羅列(編集済みデータ)」として扱われる傾向が強いため、直接計算式に組み込むとコンパイラが頑張って変換しますが、予期せぬ挙動を招くこともあります。計算は `FIXED DECIMAL` や `BIN` で行い、出力直前で `PICTURE` 変数に代入する、という分離の原則を守るのが、バグを防ぐコツです。
—
最後に:怖がらなくて大丈夫です
PL/Iの構文は、最初は少し堅苦しく見えるかもしれません。ですが、一度「この属性は、このデータをどう見せたいか」という視点で眺めてみると、その設計のシンプルさにきっと驚くはずです。
もし現場のコードで「なんだこの記号は!?」と悩んだら、いつでも紐解いてみてください。一つひとつは、プログラムをより安全に、より効率的にするための「守り神」のようなものです。
また次回の記事では、メインフレームのキモである「構造体(DECLARE 構造)」についてお話ししましょう。これが分かれば、レガシーなデータレイアウトも怖くありませんよ!
