COBOLの書き方

COBOLの書き方は初期からある「固定書式」と、後の言語仕様の改定で導入された「自由書式」がある。

自由書式は最近のプログラミング言語と同様、桁数の制約はなく、コードはインデントで整形する(インデントしてなくても、コンパイル自体はできる)。
ただ、自分がCOBOLに関わるのは既に稼働しているシステムの保守開発の時が多く、開発現場で自由書式のCOBOLソースコードを見たことはない。

よって、以降は固定書式を前提に記載する。


固定書式のルール

1行は80桁以内で、桁数によって領域が分かれている(コンパイラによっては1行あたり80桁の制限がないものもある)。
それぞれの領域には、何を記述するのかが定められている。

・1~6桁目は一連番号領域
ここには行番号を書く。
行番号は10や100単位で付番することが多い。
ただし、最近のコンパイラは一連番号領域を無視するので、行番号が正しくなくても問題にはならない。
そのため、全行を「000000」としたり、空白で埋めるケースもある。

・7桁目は標識領域
8桁目以降に何が書かれているのかを記号で示す。
以下のようなものがある。
  空白なら、通常行(プログラムコード)。
  *(アスタリスク)なら、コメント行。

・8~11桁目はA領域
各部(DIVISION)の開始宣言、節や段落の宣言などをこの領域から書き始める。

・12~72桁目はB領域
命令文などを記述する。

・73~80桁目は見出し領域
自由に記述できる(プログラムとして認識されない)。
コメントも書けるが、文字数に制限があるので、使わないことが多い。


4つの部(DIVISION)と節(SECTION)

COBOLのプログラムは、下記の4つの部(DIVISION)に分けて記述する。
部からさらに節、段落と、要素が分かれていく。
なお、使わない部は省略ができる。

■見出し部(IDENTIFICATION DIVISION)
プログラム名や作成者等を記述する。

■環境部(ENVIRONMENT DIVISION)
入出力ファイルや環境変数の情報等を記述する。
以下のような節(SECTION)がある。

・構成節(CONFIGURATION SECTION)
利用するコンピューター名や環境変数などを定義する。

・入出力節(INPUT-OUTPUT SECTION、FILE-CONTROL)
入力/出力するファイルに対する、プログラム内での名前や、格納先(パス)などを定義する。

■データ部(DATA DIVISION)
プログラム内で使用するデータ(ファイル内の項目・変数・定数など)の定義を記述する。
以下のような節(SECTION)がある。

・ファイル節(FILE SECTION)
入力/出力ファイルのデータ項目について定義する。

・作業場所節(WORKNG-STORAGE SECTION)
プログラム内で使用する変数や定数などを定義する。

・連絡節(LINKAGE SECTION)
外部プログラムとのデータのやりとりに関する情報を定義する。

■手続き部(PROCEDURE DIVISION)
実際の処理内容(ロジック)を記述する。


データ項目の定義方法

COBOLでデータ項目(変数・定数)を定義するときは、レベル番号を用いて集団項目・基本項目を定義する。

レベル番号とはデータ項目の階層や従属関係を定義するための番号。
「01」が最上位の階層で、数字が増えるほど下位の階層となる。
ロジック内で上位レベルの項目(集団項目)を参照すると、下位項目が連結された1つのデータ項目として扱われる。

具体的には、以下のように定義する。
なお、ここでは便宜上、変数名に日本語を使っている。
変数名に日本語を使うことはできるのだが、英語かローマ字を使うことが多い。
ただし、プロジェクトによってはコーディング規約で変数名に日本語を使うルールになっている事もあるので、プロジェクトのルールに従う。

000000 01  社員.
000000     03  社員コード      PIC  X(06).
000000     03  社員氏名        PIC  X(30).
000000     03  入社日付.
000000         05  入社年      PIC  9(04).
000000         05  FILLER      PIC  X(01)  VALUE '/'.
000000         05  入社月      PIC  9(02).
000000         05  FILLER      PIC  X(01)  VALUE '/'.
000000         05  入社日      PIC  9(02).
000000     03  退社日付.
000000         05  退社年      PIC  9(04).
000000         05  FILLER      PIC  X(01)  VALUE '/'.
000000         05  退社月      PIC  9(02).
000000         05  FILLER      PIC  X(01)  VALUE '/'.
000000         05  退社日      PIC  9(02).

データ項目には文字列、数字(符号あり/なし、ゼロサプレス)、小数点などの型とサイズ(桁数)を指定する。
なお、「FILLER」は特別な項目名であり、何度でも定義できるが、ロジック内で参照はできない。


サンプルプログラム

プログラムソース

000000 IDENTIFICATION  DIVISION.
000000 PROGRAM-ID.  TEST_COB.
000000*
000000 ENVIRONMENT  DIVISION.
000000 INPUT-OUTPUT  SECTION.
000000 FILE-CONTROL.
000000*    入力ファイル指定(改行区切り)
000000     SELECT  IN-FL       ASSIGN TO  'infile.dat'
000000                         ORGANIZATION IS LINE SEQUENTIAL.
000000*
000000*    出力ファイル指定(改行区切り)
000000     SELECT  OUT-FL      ASSIGN TO  'outfile.dat'
000000                         ORGANIZATION IS LINE SEQUENTIAL.
000000*
000000 DATA  DIVISION.
000000*ファイルのレイアウト定義
000000 FILE  SECTION.
000000*入力ファイル
000000 FD  IN-FL.
000000 01  IN-REC.
000000     03  IN-CODE              PIC  X(04).
000000     03  FILLER               PIC  X(01).
000000     03  IN-UNIT-PRICE        PIC  9(05).
000000     03  FILLER               PIC  X(01).
000000     03  IN-QUANTITY          PIC  9(02).
000000*
000000*出力ファイル
000000 FD  OUT-FL.
000000 01  OUT-REC.
000000     03  OUT-NO               PIC  9(03).
000000     03  FILLER               PIC  X(01).
000000     03  OUT-CODE             PIC  X(04).
000000     03  FILLER               PIC  X(01).
000000     03  OUT-UNIT-PRICE       PIC  Z(05).
000000     03  FILLER               PIC  X(01).
000000     03  OUT-QUANTITY         PIC  Z(02).
000000     03  FILLER               PIC  X(01).
000000     03  OUT-TOTAL-PRICE      PIC  Z(07).
000000     03  FILLER               PIC  X(01).
000000     03  OUT-PRICE-JUDGMENT   PIC  X(01).
000000*
000000*変数・定数の定義
000000 WORKING-STORAGE  SECTION.
000000 01  FLG-EOF                  PIC  X(01).
000000 01  WK-TOTAL-PRICE           PIC  9(07).
000000 01  CONST-PRICE              PIC  9(07)  VALUE  500000.
000000*
000000 PROCEDURE  DIVISION.
000000*
000000     PERFORM  INIT-PROC.
000000     PERFORM  MAIN-PROC.
000000     PERFORM  END-PROC.
000000     STOP RUN.
000000*
000000*前処理
000000 INIT-PROC  SECTION.
000000*
000000*    入力/出力ファイルを開く
000000     OPEN  INPUT   IN-FL.
000000     OPEN  OUTPUT  OUT-FL.
000000*
000000*    フラグに初期値を設定
000000     MOVE  SPACE  TO  FLG-EOF.
000000*
000000*    全桁カンマを設定してから、出力レコードを属性初期化
000000*    FILLER項目は初期化されないため、カンマが残る
000000     MOVE  ALL ','  TO  OUT-REC.
000000     INITIALIZE  OUT-REC.
000000*
000000*    1件目のレコードを読む
000000     PERFORM  READ-FILE.
000000*
000000 INIT-PROC-EXIT.
000000     EXIT.
000000*
000000*主処理
000000 MAIN-PROC  SECTION.
000000*
000000*    フラグが設定されるまでループ
000000     PERFORM  UNTIL  FLG-EOF  =  '1'
000000*
000000*      変数のカウントアップ
000000       ADD  1  TO  OUT-NO
000000*
000000*      入力ファイルの内容を転記
000000       MOVE  IN-CODE        TO  OUT-CODE
000000       MOVE  IN-UNIT-PRICE  TO  OUT-UNIT-PRICE
000000       MOVE  IN-QUANTITY    TO  OUT-QUANTITY
000000*
000000*      数字の計算(合計金額=単価×数量)
000000       COMPUTE  WK-TOTAL-PRICE = IN-UNIT-PRICE * IN-QUANTITY
000000       MOVE  WK-TOTAL-PRICE  TO  OUT-TOTAL-PRICE
000000*
000000*      合計金額が一定額を超えているか判定
000000       IF  WK-TOTAL-PRICE  >  CONST-PRICE
000000           MOVE  '*'    TO  OUT-PRICE-JUDGMENT
000000       ELSE
000000           MOVE  SPACE  TO  OUT-PRICE-JUDGMENT
000000       END-IF
000000*
000000*      レコード書き出し
000000       WRITE  OUT-REC
000000*
000000*      次のレコードを読む
000000       PERFORM  READ-FILE
000000*
000000     END-PERFORM.
000000*
000000 MAIN-PROC-EXIT.
000000     EXIT.
000000*
000000*後処理
000000 END-PROC  SECTION.
000000*
000000*    入力/出力ファイルを閉じる
000000     CLOSE  IN-FL
000000            OUT-FL.
000000*
000000 END-PROC-EXIT.
000000     EXIT.
000000*
000000*ファイル入力処理
000000 READ-FILE  SECTION.
000000*
000000*    ファイルを読む
000000*    レコードが無ければフラグを設定
000000     READ IN-FL
000000       AT END
000000         MOVE  '1'  TO  FLG-EOF
000000     END-READ.
000000*
000000 READ-FILE-EXIT.
000000     EXIT.

実行結果

# 入力ファイル(infile.dat)
A001,01000,60
B010,30000,20
A002,02000,40
B020,40000,30
C100,15000,30

# 出力ファイル(outfile.dat)
001,A001, 1000,60,  60000,
002,B010,30000,20, 600000,*
003,A002, 2000,40,  80000,
004,B020,40000,30,1200000,*
005,C100,15000,30, 450000,

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