COBOLソースコードの読み方【最低限の基礎】

· · COBOL, レガシー技術, 業務システム, 保守, Mainframe

まず結論

  • COBOLはロジックの言語である前に、レコード定義の言語
  • PROCEDURE DIVISIONだけ読んでも半分もわからない。まずDATA DIVISIONを見る
  • PICは項目のUSAGE内部表現
  • COMP-3はpacked decimal。金額や件数で頻出
  • 88は別変数ではなく、直前項目の値に名前を付けた条件名
  • REDEFINESは同じメモリを別の形で見る仕組み(コピーではない)
  • COPYがあるならcopybookを見ないと全体が見えない
  • 古いソースは列位置に意味がある固定形式。空白が飾りではない

4つのDIVISION

DIVISION 見ること
IDENTIFICATION DIVISION プログラム名
ENVIRONMENT DIVISION ファイル、入出力の前提
DATA DIVISION レコード定義、作業領域、引数
PROCEDURE DIVISION 実際の処理手順

特に重要なのはDATA DIVISIONの中の:

  • FILE SECTION - 入出力ファイルのレコード定義
  • WORKING-STORAGE SECTION - 変数、フラグ、カウンタ
  • LINKAGE SECTION - 外から渡される引数(サブプログラムの受け口)

固定形式の見方

古いCOBOLでは列位置に意味がある。

  • 1-6列: 一連番号
  • 7列: indicator(*=コメント、-=継続行、D=デバッグ行)
  • 8-11列: Area A
  • 12-72列: Area B

タブ変換や左寄せをすると壊れる。fixed formatかfree formatかを最初に確認する。

DATA DIVISIONの最低限

レベル番号

01  WS-ORDER.               ← 最上位レコード
   05  WS-ORDER-ID  PIC 9(8).
   05  WS-AMOUNT    PIC S9(7)V99 COMP-3.
   05  WS-STATUS    PIC X.
       88  WS-OK    VALUE '0'.   ← 条件名(WS-STATUSが'0'のとき真)
       88  WS-ERROR VALUE '9'.

77  WS-COUNT         PIC 9(4).   ← 独立した単項目
  • 01: グループの最上位
  • 0549: 下位項目
  • 77: 独立した単項目
  • 88: 条件名(直前項目の値に名前を付ける)

88をboolの別変数だと思わないこと。 値の状態に名前を付けているだけ。

PICTURE(PIC)

記法 意味
X 文字
9 数字
S 符号付き
V 小数点(論理上のみ。データに.は入っていない)
X(10) 10文字
9(5) 5桁数値
S9(7)V99 符号付き7桁整数+2桁小数

Vは実際の.文字を持たないので、ファイルを文字列として見ると桁がずれる。

USAGE(内部表現)

記法 意味 注意
DISPLAY 文字として見える10進 mainframeではEBCDICのことがある
COMP / BINARY 2進数 見た目の桁数と内部表現は別
COMP-3 packed decimal 金額・件数。テキストとして見ると壊れて見える

DISPLAYだからといってASCIIとは限らない。 z/OS系ではEBCDIC前提。

REDEFINES / OCCURS / COPY / FILLER

  • REDEFINES: 同じ領域を別の形で見る(Cのunionに近い)。コピーではない
  • OCCURS: 配列。OCCURS DEPENDING ONは可変長テーブル
  • COPY: コンパイル時のinclude。copybookを見ないと完成形がわからない
  • FILLER: 名前のない項目。予約領域やレコード長合わせに使われる。バイト数としては存在する

PROCEDURE DIVISIONの最低限

PERFORM

処理を呼んで戻る基本構文。

PERFORM UNTIL EOF
    READ IN-FILE
        AT END SET EOF TO TRUE
        NOT AT END PERFORM PROCESS-REC
    END-READ
END-PERFORM

IF / EVALUATE

  • IFが基本の条件分岐
  • EVALUATEはswitch/case的なもの

ピリオド.の注意

古いコードでは.暗黙のスコープ終端。たった1個のピリオドでIFやPERFORMの範囲が変わる。NEXT SENTENCEは次の.の後ろへ進む。

READ / WRITE / CALL

  • READ ... AT END ...が王道パターン
  • CALL 'SUBPGM' USING ...で別プログラムへ飛ぶ

COBOLの外側にあるもの

COBOLはソースだけで完結しないことが多い。

  • FILE STATUS - 各I/O後の結果コード。ファイル障害の調査に必須
  • EXEC SQL - 埋め込みSQL。COBOLはホスト変数の器で、実質はSQL側
  • EXEC CICS - CICSトランザクション文脈。画面やCOMMAREA込みで読む必要がある
  • JCL - mainframeバッチでは、どのデータセットが割り当てられるかはCOBOLの外で決まる

最低限の読み順

  1. COPYを全部洗う - copybookを開くか、展開後ソースを探す
  2. 01レベルのレコード定義を拾う - FILE SECTION、WORKING-STORAGE、LINKAGE SECTION
  3. PICとUSAGEを読む - 金額、日付、件数、コードを識別
  4. READ/WRITE/CALL/EXEC SQL/EXEC CICSを検索 - 入出力と外部境界を掴む
  5. 最初の主経路だけ追う - PROCEDURE DIVISIONの先頭からPERFORM連鎖をなぞる
  6. 88とstatus項目を見る - EOF、正常/異常の意味が読みやすくなる
  7. REDEFINES/OCCURS DEPENDING ON/COMP-3に印を付ける
  8. FILE STATUSを見る - I/Oエラー系の読み違いを減らせる

早見表

見つけた語 まず考えること
01 レコードやグループの最上位
88 フラグや状態コードの意味名
PIC X(…) 文字項目
PIC 9(…) 数値項目。桁数と小数位置を確認
COMP binary
COMP-3 packed decimal。金額・件数の可能性が高い
REDEFINES 同じ領域を別解釈している
OCCURS 配列
OCCURS DEPENDING ON 可変長。後続位置にも注意
FILLER 名前はないが長さはある
COPY copybookを見ないと完成形が見えない
PERFORM 主経路の骨格
READ/WRITE ファイルI/O
EXEC SQL DB処理
EXEC CICS トランザクション処理
FILE STATUS I/Oの結果コード

よくある詰まりどころ

  1. REDEFINESを別変数だと思う → 同じ領域を別の形で見ているだけ
  2. 88を独立したboolだと思う → 直前項目の値に名前が付いているだけ
  3. COPYを無視して本文だけ読む → フィールド定義の半分が外にある
  4. MOVEを単純代入だと思う → 型に応じて変換・桁合わせが入る
  5. .の影響を軽く見る → スコープの終端を読み違える
  6. packed decimalやEBCDICを文字化けだと思う → 最初から文字列ではない、またはASCIIではないだけ

まとめ

COBOLは古いから難しいのではない。データ定義、外部ファイル、実行文脈が密に結び付いているため入口が見えにくいだけ。

  • DIVISIONで地図を掴む
  • DATA DIVISIONを先に読む
  • PICとUSAGEで項目の形を読む
  • COMP-3、REDEFINES、OCCURS、88、COPYに印を付ける
  • PERFORM、READ、WRITE、CALLを追う
  • FILE STATUS、EXEC SQL、EXEC CICSで外部境界を押さえる

地図の縮尺が合えば、意外と普通に読める。

関連する記事

同じタグを共有する最新の記事です。さらに近い話題で知識を深められます。

Reg-Free COM 入門【レジストリ不要のCOM】

Reg-Free COMの仕組みを、アクティベーションコンテキストとマニフェストの役割から整理します。XCOPY配布や版の共存といった利点と、bitnessや設計時参照といった限界、向き不向きの判断軸まで実務目線でまとめます。

記事を読む

COM/ActiveX/OCXの違いを徹底解説

COM・ActiveX・OCX の違いを土台と部品とファイルという三層で整理し、OLE との関係や IE モードを含む現代の実務での扱い方、調査の観点や残す判断の目安までコンパクトにまとめた解説記事です。

記事を読む

関連トピック

このテーマと近いトピックページです。記事を起点に、関連するサービスや他の記事へ進めます。

このテーマがつながるサービス

この記事は次のサービスページにつながります。近い入口からご覧ください。

ブログ一覧に戻る