1. 導入: なぜPICTURE句の混在はNGなのか?
皆さん、COBOLのプログラムを組む際、データ項目の定義は基本中の基本ですよね。特にPICTURE句は、その項目がどんな種類のデータを、どれくらいの桁数で持つのかをコンパイラに伝える非常に重要な役割を担っています。
しかし、このPICTURE句の定義において、一つ守らなければならない鉄則があります。それは、『数字を表す「9」と、英数字を表す「X」、英字を表す「A」を一つのPICTURE句内で混在させてはならない』というものです。
「え、そんなの当たり前じゃないか」と思う方もいれば、「あれ?そういえば昔、よくコンパイルエラーになったな」と思い出す方もいるかもしれません。このルールを破ると、プログラムはコンパイルエラーとなり、実行すらできません。なぜこのルールが重要なのか、そしてどのように正しく定義すべきか、今一度基本に立ち返って確認していきましょう。これは、単にエラーを回避するだけでなく、プログラムの堅牢性と保守性を高める上でも非常に大切なポイントになります。
2. 基礎知識: PICTURE句とデータ型の基本
COBOLでは、データ項目をPICTURE句で定義することで、その項目の「型」と「長さ」を決定します。
- ‘9’ (数字文字):
- 0から9までの数字のみを格納できます。
- 計算処理の対象となる数値項目を定義する際に使用します。
- 内部的には、ゾーン10進数やパック10進数といった形式で表現されます(USAGE句によって変わります)。
- ‘X’ (英数字文字):
- あらゆる文字(数字、英字、記号、日本語など)を格納できます。
- 文字データの表現に最も汎用的に使われます。
- 内部的には、文字コード(EBCDICやASCIIなど)として表現されます。
- ‘A’ (英字文字):
- 英字(A~Z、a~z)とスペースのみを格納できます。
- あまり使われませんが、厳密に英字のみを扱いたい場合に用います。
- 内部的には、文字コードとして表現されます。
なぜこれらの文字を混在させることができないのでしょうか?それは、COBOLのコンパイラが、PICTURE句全体を見てその項目の「データ型」を決定するからです。例えば、「99X99」のような定義があった場合、コンパイラは「これは数字なのか?それとも英数字なのか?」と判断に迷ってしまいます。数字項目と英数字項目では、内部でのデータの持ち方(表現形式)が根本的に異なるため、一つの項目の中で両方の特性を持たせることはできないのです。データ型を明確にすることで、後続の計算や比較、移動などの処理が正しく行われることを保証します。
3. 実装/解決策: 正しいPICTURE句の定義方法
PICTURE句は、以下のいずれかの形で定義する必要があります。
- 全てが数字文字 (‘9’) のみで構成される「数字項目」
- 全てが英数字文字 (‘X’) のみで構成される「英数字項目」
- 全てが英字文字 (‘A’) のみで構成される「英字項目」
もし、一つのデータ項目の中に「数字のように見えて計算はしない部分」と「英字の部分」が混在するようなデータ(例: 商品コード “A123B”)を扱いたい場合は、その項目全体を ‘X’ (英数字項目) として定義するのが一般的です。その上で、もし一部を数値として扱いたい場合は、後述するFUNCTION句などを使って明示的に変換する必要があります。
4. サンプルプログラム
以下に、PICTURE句のNG例とOK例を示します。NG例はコンパイルエラーになるため、実際に動かすことはできません。
IDENTIFICATION DIVISION.
PROGRAM-ID. PICTURE-RULE-SAMPLE.
DATA DIVISION.
WORKING-STORAGE SECTION.
— NG例:この項目はコンパイルエラーになります —
- 01 NG-ITEM-MIXED PIC 99X99. <-- '9'と'X'が混在しているためNG
— OK例:正しいPICTURE句の定義 —
- 01 英数字項目 (全て’X’で定義)
01 WS-ALPHANUM-DATA PIC X(10). > 英字、数字、記号など何でも格納可能
- 01 数字項目 (全て’9’で定義)
01 WS-NUMERIC-DATA PIC 9(5). > 0-9の数字のみ格納可能。計算可能
01 WS-NUMERIC-SIGNED PIC S9(5)V99. > 符号付き、小数点付きの数字項目
- 01 英字項目 (全て’A’で定義)
01 WS-ALPHABETIC-DATA PIC A(8). > 英字とスペースのみ格納可能
PROCEDURE DIVISION.
MAIN-PARAGRAPH.
- — 英数字項目 —
MOVE “ABC123DEF4” TO WS-ALPHANUM-DATA.
DISPLAY “英数字項目: ” WS-ALPHANUM-DATA.
- — 数字項目 —
MOVE 12345 TO WS-NUMERIC-DATA.
DISPLAY “数字項目 (整数): ” WS-NUMERIC-DATA.
MOVE -123.45 TO WS-NUMERIC-SIGNED.
DISPLAY “数字項目 (符号/小数): ” WS-NUMERIC-SIGNED.
COMPUTE WS-NUMERIC-SIGNED = WS-NUMERIC-SIGNED + 100.00.
DISPLAY “数字項目 (計算後): ” WS-NUMERIC-SIGNED.
- — 英字項目 —
MOVE “COBOL-PG” TO WS-ALPHABETIC-DATA.
DISPLAY “英字項目: ” WS-ALPHABETIC-DATA.
STOP RUN.
5. 応用・注意点: 現場で役立つ補足情報
- 外部連携データへの対応:
CSVファイルなど、外部から取り込むデータには「品目コードA001」のように、見た目上数字と英字が混在しているものがよくあります。このようなデータは、COBOLプログラム内では必ず英数字項目 (PIC X) として定義し、必要に応じてサブストリング操作 (例: `WS-ITEM-CODE(2:3)`) や、`FUNCTION NUMVAL()` を使って数値部分を抽出し、数値として利用するようにしましょう。
例: `COMPUTE WS-TOTAL = WS-TOTAL + FUNCTION NUMVAL(WS-ITEM-CODE(2:3))` - REDEFINES句の活用(注意が必要):
どうしても一時的に同じメモリ領域を異なる型として扱いたい場合は、`REDEFINES` 句を使うこともできます。ただし、これはメモリを直接操作するようなものであり、データの意味合いと内部表現をしっかり理解していないと、予期せぬバグやデータ破壊に繋がるリスクがあります。基本的には推奨されません。
例:01 ORIGINAL-DATA PIC X(5). 01 REDEFINED-NUMERIC REDEFINES ORIGINAL-DATA PIC 9(5).この例では、`ORIGINAL-DATA` に “12345” を入れた後、`REDEFINED-NUMERIC` として参照すれば数値として扱えますが、”ABCDE” を入れた後に `REDEFINED-NUMERIC` を参照すると、実行時エラーや不正な値になる可能性があります。
- コンパイラの挙動:
多くのCOBOLコンパイラは、PICTURE句の混在に対して厳格で、コンパイルエラー(致命的エラー)として処理します。しかし、一部のコンパイラや古いバージョンでは、警告で済ませたり、特定の解釈をしたりする場合が稀にあります。しかし、これは「動くから良い」という話ではなく、データ型定義の原則から外れているため、絶対に行ってはいけません。将来のメンテナンスや他の環境への移行時に問題となる可能性が高いです。 - データ定義のベストプラクティス:
データ項目を定義する際は、その項目が「何のために使われるのか」を明確にし、最も適切なPICTURE句を選択することが重要です。- 計算に使うなら `PIC 9`
- 文字情報としてそのまま扱うなら `PIC X`
- 厳密に英字のみなら `PIC A` (ただし稀)
この基本を徹底することで、プログラムの可読性が向上し、バグの発生を未然に防ぎ、後々の改修も容易になります。
PICTURE句の定義は、COBOLプログラミングの基礎中の基礎ですが、その裏にあるデータ型の考え方や内部表現の違いを理解しておくことは、より高度なプログラミングを行う上でも非常に役立ちます。この鉄則をしっかりと守り、堅牢なCOBOLプログラムを開発していきましょう。

コメント