導入:なぜCOMMON属性が必要なのか?
COBOLの入れ子(Nested)プログラムは、関連するロジックを一つのソースファイルにまとめられる便利な機能です。しかし、標準のままでは「親プログラムの直下にある子プログラム」を「兄弟関係にある別の入れ子プログラム」から呼び出そうとすると、コンパイルエラーや呼び出し失敗が発生します。この「呼び出し範囲の制約」という壁を突破し、入れ子構造内でプログラムを柔軟に共有するために必須となるのがCOMMON属性です。
基礎知識:入れ子プログラムのスコープ
通常、入れ子プログラムは「直接の親プログラム」からのみ可視です。例えば、メインプログラムの中にAとBという二つのサブプログラムを作った場合、AからBを直接呼び出すことはできません。これは、Bの存在がメインプログラムに対してのみ有効(スコープ内)だからです。この制約を緩和し、同じ親を持つプログラム群であればどこからでも呼び出せるようにするのが、PROGRAM-ID句のCOMMON属性です。
実装・解決策
COMMON属性を指定するには、PROGRAM-ID句の末尾に「IS COMMON」を付与します。これにより、そのプログラムは「親プログラムの領域」に公開され、同じ親を持つ他の入れ子プログラムからも呼び出し可能な状態になります。
サンプルプログラム
以下のコードは、メインプログラム内で二つのサブプログラムを定義し、COMMON属性を使って相互連携させる例です。
PROGRAM-ID. MAIN-PROG.
WORKING-STORAGE SECTION.
01 WS-MSG PIC X(50).
PROCEDURE DIVISION.
> サブプログラムBを呼び出す
CALL “SUB-B” USING WS-MSG.
DISPLAY “MAIN: ” WS-MSG.
STOP RUN.
> COMMON属性を持つプログラムB(どこからでも呼ばれる)
PROGRAM-ID. SUB-B IS COMMON.
DATA DIVISION.
LINKAGE SECTION.
01 LS-MSG PIC X(50).
PROCEDURE DIVISION USING LS-MSG.
MOVE “SUB-Bからこんにちは” TO LS-MSG.
EXIT PROGRAM.
END PROGRAM SUB-B.
> プログラムA(ここからもSUB-Bを呼べる)
PROGRAM-ID. SUB-A.
PROCEDURE DIVISION.
> ここでCOMMON属性のSUB-Bを呼び出し可能
CALL “SUB-B” USING …
EXIT PROGRAM.
END PROGRAM SUB-A.
END PROGRAM MAIN-PROG.
応用・注意点
現場で活用する際は、以下の2点に注意してください。
1. 名前の衝突:COMMON属性を指定すると、その親プログラムの配下でプログラム名がグローバルな存在になります。同じ親の中に、同じ名前のCOMMONプログラムを複数配置することはできないため、命名規則には十分注意しましょう。
2. 再帰呼び出しとの併用:COMMON属性はあくまで「可視範囲」を広げるものです。プログラム自身の再帰呼び出しを行う場合は、RECURSIVE属性も併せて検討する必要があります。
大規模なバッチ処理などで、共通ロジックを入れ子構造内に閉じ込めつつ整理したい場合には、このCOMMON属性が非常に強力な武器となります。ぜひ使いこなしてください。

コメント