CTS-KB
COBOL 1 / 5

COBOL 文法基礎

#COBOL #文法 #基礎

対象: GnuCOBOL 4 / Free Format 本ドキュメントはプロジェクト内のサンプルコードに基づいて構成


目次

  1. プログラムの全体構造
  2. IDENTIFICATION DIVISION(見出し部)
  3. ENVIRONMENT DIVISION(環境部)
  4. DATA DIVISION(データ部)
  5. PROCEDURE DIVISION(手続き部)
  6. データ型と PICTURE 句
  7. 変数操作
  8. 制御構文
  9. ファイル操作
  10. 文字列操作
  11. コメントと書式
  12. コンパイルと実行

1. プログラムの全体構造

COBOLプログラムは 4つのDIVISION で構成される。順序は固定。

IDENTIFICATION DIVISION.    ← プログラムの名札
ENVIRONMENT DIVISION.       ← 実行環境・ファイル定義
DATA DIVISION.              ← 変数・レコード定義(COBOLの心臓部)
PROCEDURE DIVISION.         ← 実際の処理ロジック

各DIVISIONの中に SECTION、さらにその中に PARAGRAPH がある。

1. プログラムの全体構造

DIVISION(部)

SECTION(節)

SECTION

PARAGRAPH(段落)

PARAGRAPH

PARAGRAPH

最小構成のプログラム

IDENTIFICATION DIVISION.
    PROGRAM-ID. HELLO.
PROCEDURE DIVISION.
    DISPLAY "HELLO from GnuCOBOL4!".
    STOP RUN.

参照: hello.cob

ENVIRONMENT DIVISION と DATA DIVISION は、使わなければ省略可能。


2. IDENTIFICATION DIVISION(見出し部)

プログラムの識別情報を記述する。必須は PROGRAM-ID のみ。

IDENTIFICATION DIVISION.
    PROGRAM-ID. STRUCTURE-DEMO.
    AUTHOR. HIRO.               *> 任意
必須説明
PROGRAM-ID.必須プログラム名(英数字、ハイフン可、30文字以内推奨)
AUTHOR.任意作者名(COBOL 2002以降は非推奨だが使用可能)
DATE-WRITTEN.任意作成日
DATE-COMP[ILE](/glossary/ile)D.任意コンパイル日(自動置換される処理系もある)

参照: structure.cob:7-9


3. ENVIRONMENT DIVISION(環境部)

実行環境の設定。ファイルを使わないプログラムでは空でもOK。

ENVIRONMENT DIVISION.
    CONFIGURATION SECTION.
        REPOSITORY.             *> 外部モジュール定義
    INPUT-OUTPUT SECTION.
        FILE-CONTROL.           *> ファイル定義

3.1 CONFIGURATION SECTION

段落説明
SOURCE-COMPUTER.ソースのコンパイル環境
OBJECT-COMPUTER.実行環境
REPOSITORY.外部クラス・モジュールの定義

3.2 INPUT-OUTPUT SECTION / FILE-CONTROL

ファイルを使う場合に SELECT 句でファイルを定義する(詳細は9. ファイル操作)。

INPUT-OUTPUT SECTION.
    FILE-CONTROL.
        SELECT ファイル論理名
            ASSIGN TO "物理ファイル名"
            ORGANIZATION IS SEQUENTIAL
            FILE STATUS IS 状態変数.

参照: file-fixed.cob:10-19, file-csv.cob:10-16


4. DATA DIVISION(データ部)

変数・レコード・ファイルレイアウトをすべてここで定義する。COBOLの最重要DIVISION。

DATA DIVISION.
    FILE SECTION.              *> ファイルのレコード構造
    WORKING-STORAGE SECTION.   *> プログラム内のローカル変数
    LOCAL-STORAGE SECTION.     *> PERFORM呼び出し毎に初期化される変数
    LINKAGE SECTION.           *> 外部プログラムとの受け渡し変数

4.1 FILE SECTION

ファイルのレコード構造を FD(File Description)で定義する。

FILE SECTION.
FD EMP-FILE
    RECORD CONTAINS 36 CHARACTERS.

*> |社員番号(5)|名前(20)|部署(8)|年齢(3)| = 36バイト
01 EMP-RECORD.
    05 EMP-ID          PIC X(5).
    05 EMP-NAME        PIC X(20).
    05 EMP-DEPT        PIC X(8).
    05 EMP-AGE         PIC 9(3).

参照: file-fixed.cob:26-39

4.2 WORKING-STORAGE SECTION

プログラム内で使うすべての変数を定義する場所。

WORKING-STORAGE SECTION.
77 WS-COUNTER        PIC 9(3)    VALUE 0.
77 WS-NAME           PIC X(20)   VALUE "TARO".

参照: structure.cob:25-57

4.3 レベル番号

COBOLの変数は レベル番号 で階層構造を表現する。

レベル番号名称用途
01レコード項目グループ項目の最上位。構造体の先頭01 WS-DATE-RECORD.
0249従属項目グループの子要素。番号が大きいほど深い階層05 WS-YEAR PIC 9(4).
66RENAMES既存項目の別名定義(あまり使わない)
77独立項目グループに属さない単独変数77 WS-COUNTER PIC 9(3).
88条件名boolean的な条件定義88 IS-MALE VALUE "M".

グループ項目の例(構造体のようなもの)

01 WS-DATE-RECORD.          *> グループ項目(親)
    05 WS-YEAR   PIC 9(4).  *> 従属項目(子)
    05 WS-MONTH  PIC 9(2).
    05 WS-DAY    PIC 9(2).
*> WS-DATE-RECORD 全体は "20260325" のような8桁
*> WS-YEAR, WS-MONTH, WS-DAY で個別にアクセス可能

参照: structure.cob:46-51

条件名(88レベル)の例

01 WS-GENDER         PIC X(1).
    88 IS-MALE       VALUE "M".
    88 IS-FEMALE     VALUE "F".

*> 使い方(以下の2つは同じ意味):
IF IS-MALE ...
IF WS-GENDER = "M" ...

*> SET で値をセットすることも可能:
SET IS-MALE TO TRUE    *> WS-GENDER に "M" が入る

参照: structure.cob:54-57

4.4 OCCURS(配列)

01 WS-SAMPLE-DATA.
    05 WS-SAMPLE       OCCURS 3 TIMES.
        10 WS-S-ID     PIC X(5).
        10 WS-S-NAME   PIC X(20).
        10 WS-S-DEPT   PIC X(8).
        10 WS-S-AGE    PIC 9(3).

*> アクセス: 添字は 1 始まり
MOVE "TANAKA" TO WS-S-NAME(1)
MOVE "SUZUKI" TO WS-S-NAME(2)

参照: file-fixed.cob:53-58

4.5 VALUE 句(初期値)

77 WS-COUNTER   PIC 9(3)    VALUE 0.        *> 数値の初期値
77 WS-NAME      PIC X(20)   VALUE "TARO".   *> 文字列の初期値
77 WS-EOF-FLAG  PIC X(1)    VALUE "N".       *> フラグの初期値

VALUE を省略した場合、数値は 0、文字列は SPACES で初期化される(GnuCOBOLの場合)。


5. PROCEDURE DIVISION(手続き部)

実際の処理ロジックを記述する。SECTION と PARAGRAPH で構造化する。

PROCEDURE DIVISION.

    *> SECTION: 大きな処理のまとまり
    MAIN-SECTION SECTION.
        *> PARAGRAPH: 処理の単位
        MAIN-PARA.
            PERFORM INIT-PARA
            PERFORM DISPLAY-PARA
            PERFORM END-PARA
            STOP RUN.

    INIT-PARA.
        MOVE 2026 TO WS-YEAR
        MOVE 03   TO WS-MONTH
        MOVE 25   TO WS-DAY.

参照: structure.cob:61-93

5.1 SECTION と PARAGRAPH の違い

要素役割終わり方
SECTION段落のグループ(大分類)次のSECTIONの開始、またはプログラム終了
PARAGRAPH処理の最小単位(関数的に使う)次のPARAGRAPHの開始、またはSECTION終了

5.2 文(Statement)の終わり

COBOLでは ピリオド . が文の終了を示す。

INIT-PARA.
    MOVE 2026 TO WS-YEAR
    MOVE 03   TO WS-MONTH
    MOVE 25   TO WS-DAY.          *> ← ピリオドでこの段落の全文が終了

重要: ピリオドは段落の最後にだけ打つのが現代的な書き方。 途中のピリオドは IF / PERFORM のスコープを意図せず閉じてしまう。

*> NG: ピリオドが IF のスコープを閉じてしまう
IF WS-AGE > 20
    DISPLAY "Adult".        *> ← ここでIFが終わる!
    DISPLAY "Hello"         *> ← IF の外になる(常に実行される)

*> OK: END-IF を使う
IF WS-AGE > 20
    DISPLAY "Adult"
    DISPLAY "Hello"
END-IF.                     *> ← 段落末のピリオド

5.3 STOP RUN

プログラムを終了する命令。メインプログラムの最後に必ず書く。

STOP RUN.

サブプログラムの場合は GOBACK. を使う。


6. データ型と PICTURE 句

COBOLの変数はすべて PIC(PICTURE)句で型と長さを定義する。

6.1 基本記号

記号意味格納例
9数字1桁(0-9)PIC 9(3) → 数字3桁028
X英数字1文字PIC X(20) → 20文字TANAKA TARO
A英字1文字(A-Z, スペース)PIC A(10)HELLO
V暗黙の小数点(格納時には見えない)PIC 9(5)V990123456(=1234.56)
S符号付き(正負を扱える)PIC S9(5)-12345

6.2 省略記法

PIC 9(5)    *> = PIC 99999    (数字5桁)
PIC X(20)   *> = PIC XXXXXXXXXXXXXXXXXXXX
PIC XX      *> = PIC X(2)     (2文字)

6.3 編集用PICTURE(表示専用)

表示用のフォーマットを定義するPICTURE。計算には使えない。

記号意味入力と表示
Z先行ゼロ抑制(スペース置換)PIC Z(4)900123 → ␣␣123
*先行ゼロ抑制(*置換)PIC *(4)900123 → **123
,カンマ挿入PIC ZZZ,ZZ9012345 → ␣12,345
.小数点挿入PIC ZZ9.9912345 → 123.45
-負の場合にマイナス表示PIC -(5)9-123 → ␣␣-123
+正負の符号を表示PIC +(5)9+123 → ␣␣+123
$ / ¥通貨記号PIC $ZZ,ZZ9012345 → $12,345
*> 実例
77 WS-DISP-PRICE   PIC Z(6)9.        *> 先行ゼロをスペースに
77 WS-NUM-PRICE    PIC 9(7).          *> 計算用

MOVE 1500 TO WS-NUM-PRICE
MOVE WS-NUM-PRICE TO WS-DISP-PRICE   *> 表示: "   1500"

参照: file-csv.cob:50-52

6.4 よく使うPICTUREパターン一覧

用途PIC定義
フラグPIC X(1)"Y" / "N"
コード(英数字)PIC X(5)"E001 "
名前PIC X(20)"TANAKA TARO "
整数(正のみ)PIC 9(5)00123
整数(正負)PIC S9(5)-00123
金額PIC 9(7)V990012345.67
日付(YYYYMMDD)PIC 9(8)20260325
ファイルステータスPIC XX"00"

7. 変数操作

7.1 MOVE(代入)

COBOLで最も使う命令。右辺を左辺にコピーする。

MOVE 2026       TO WS-YEAR       *> 数値の代入
MOVE "TANAKA"   TO WS-NAME       *> 文字列の代入(右側はスペース埋め)
MOVE "M"        TO WS-GENDER     *> 1文字の代入
MOVE SPACES     TO WS-NAME       *> 全スペースで初期化
MOVE ZEROS      TO WS-COUNTER    *> 全ゼロで初期化

転記ルール:

送り側 → 受け側動作
文字列 → 文字列左詰め、余りはスペース埋め
数値 → 数値右詰め(小数点位置合わせ)、余りはゼロ埋め
短い → 長い余った部分はスペース/ゼロ埋め
長い → 短い切り捨て(文字列は右が切れる、数値は上位桁が切れる)
*> MOVE CORRESPONDING: グループ項目間で同名フィールドを一括転記
MOVE CORRESPONDING WS-INPUT-REC TO WS-OUTPUT-REC

参照: structure.cob:73-76, file-fixed.cob:74-87

7.2 INITIALIZE(初期化)

INITIALIZE WS-DATE-RECORD
*> 数値項目 → 0、文字項目 → スペース にリセット
*> MOVE SPACES + MOVE ZEROS を一括で行う便利命令

7.3 算術演算

ADD 1          TO WS-COUNTER           *> WS-COUNTER = WS-COUNTER + 1
SUBTRACT 10    FROM WS-PRICE           *> WS-PRICE = WS-PRICE - 10
MULTIPLY 1.08  BY WS-PRICE             *> WS-PRICE = WS-PRICE * 1.08
DIVIDE WS-TOTAL BY WS-COUNT
    GIVING WS-AVERAGE                  *> WS-AVERAGE = WS-TOTAL / WS-COUNT
    REMAINDER WS-MOD                   *> 余り

*> COMPUTE: 数式を直接書ける(現代的な書き方)
COMPUTE WS-TAX = WS-PRICE * 0.10
COMPUTE WS-TOTAL = WS-PRICE + WS-TAX
COMPUTE WS-AVG = (WS-A + WS-B + WS-C) / 3

*> ROUNDED: 四捨五入
COMPUTE WS-RESULT ROUNDED = WS-A / WS-B

7.4 DISPLAY / ACCEPT

*> 画面出力
DISPLAY "Hello, World!"
DISPLAY "Name: " WS-NAME              *> 複数の値を連結して表示
DISPLAY "ID: " EMP-ID " | " EMP-NAME  *> 3つ以上も可

*> キーボード入力
ACCEPT WS-USER-INPUT FROM CONSOLE
ACCEPT WS-TODAY FROM DATE YYYYMMDD    *> システム日付を取得

参照: structure.cob:79-90, file-fixed.cob:147-151


8. 制御構文

8.1 IF / ELSE

IF WS-AGE >= 20
    DISPLAY "Adult"
ELSE
    DISPLAY "Minor"
END-IF.

*> 条件名(88レベル)を使った場合
IF IS-MALE
    DISPLAY "Gender: Male"
END-IF.

*> ネスト
IF WS-SCORE >= 90
    DISPLAY "A"
ELSE IF WS-SCORE >= 70
    DISPLAY "B"
ELSE
    DISPLAY "C"
END-IF.

参照: structure.cob:88-90

8.2 EVALUATE(switch文に相当)

EVALUATE WS-DEPT
    WHEN "SALES"
        DISPLAY "営業部"
    WHEN "DEVELOP"
        DISPLAY "開発部"
    WHEN "HR"
        DISPLAY "人事部"
    WHEN OTHER
        DISPLAY "その他"
END-EVALUATE.

*> TRUE を使ったパターン(複雑な条件分岐)
EVALUATE TRUE
    WHEN WS-SCORE >= 90
        MOVE "A" TO WS-GRADE
    WHEN WS-SCORE >= 70
        MOVE "B" TO WS-GRADE
    WHEN OTHER
        MOVE "C" TO WS-GRADE
END-EVALUATE.

8.3 PERFORM(サブルーチン呼び出し / ループ)

COBOLの最重要制御構文。段落の呼び出しとループの両方に使う。

*> --- 単純呼び出し(関数呼び出し的) ---
PERFORM INIT-PARA
PERFORM DISPLAY-PARA

*> --- 回数指定ループ ---
PERFORM PROCESS-PARA 10 TIMES

*> --- 条件ループ(while的) ---
PERFORM UNTIL WS-EOF
    READ EMP-FILE
        AT END SET WS-EOF TO TRUE
    END-READ
END-PERFORM

*> --- カウンタループ(for的) ---
*> PERFORM VARYING = COBOLのforループ
PERFORM VARYING WS-REC-COUNT FROM 1 BY 1
    UNTIL WS-REC-COUNT > 3
    DISPLAY WS-REC-COUNT
END-PERFORM
*> WS-REC-COUNT を 1 → 2 → 3 と増やしながら繰り返す

*> --- インラインでないPERFORM(段落を範囲指定) ---
PERFORM PARA-A THRU PARA-C
*> PARA-A, PARA-B, PARA-C を順に実行

参照: structure.cob:66-68, file-fixed.cob:101-113, file-fixed.cob:141-153

8.4 ループ制御(EXIT / CONTINUE)

*> --- EXIT PERFORM: ループの途中脱出(break に相当) ---
PERFORM VARYING WS-I FROM 1 BY 1
    UNTIL WS-I > 100
    IF WS-DATA(WS-I) = "TARGET"
        DISPLAY "Found at: " WS-I
        EXIT PERFORM
    END-IF
END-PERFORM

*> --- EXIT PERFORM CYCLE: 残りをスキップして次の回へ(continue に相当) ---
PERFORM VARYING WS-I FROM 1 BY 1
    UNTIL WS-I > 10
    IF WS-SKIP-FLAG(WS-I) = "Y"
        EXIT PERFORM CYCLE
    END-IF
    DISPLAY "Processing: " WS-I
END-PERFORM

*> --- PERFORM WITH TEST AFTER: 必ず1回は実行(do-while に相当) ---
*> デフォルトは WITH TEST BEFORE(while に相当)
PERFORM WITH TEST AFTER
    UNTIL WS-INPUT = "Q"
    ACCEPT WS-INPUT FROM CONSOLE
    DISPLAY "You entered: " WS-INPUT
END-PERFORM

*> --- EXIT PARAGRAPH: 段落の途中脱出(early return に相当) ---
VALIDATE-PARA.
    IF WS-NAME = SPACES
        DISPLAY "Error: Name is empty"
        EXIT PARAGRAPH
    END-IF
    IF WS-AGE = 0
        DISPLAY "Error: Age is zero"
        EXIT PARAGRAPH
    END-IF
    DISPLAY "Validation OK".

*> --- GO TO(非推奨・参考知識) ---
*> 無条件に指定段落へジャンプする。スパゲッティコードの原因になるため
*> 現代のCOBOLでは使用を避け、PERFORM + EXIT で代替する。
*> GO TO ERROR-PARA

他言語との対応:

COBOL他言語での相当
EXIT PERFORMbreak
EXIT PERFORM CYCLEcontinue
PERFORM WITH TEST AFTERdo-while
EXIT PARAGRAPHreturn(早期リターン)
GO TO(非推奨)goto

8.5 標準プロシージャ構成パターン

COBOLでは「初期化 → 主処理ループ → 終了処理」の3段構成が定石。

*> ========================================
*> 典型的なバッチ処理プログラムの構成
*> ========================================
PROCEDURE DIVISION.
MAIN-PARA.
    PERFORM INIT-PARA           *> 1. 初期化
    PERFORM PROCESS-PARA        *> 2. 主処理
        UNTIL WS-EOF
    PERFORM TERM-PARA           *> 3. 終了処理
    STOP RUN.

*> --- 1. 初期化: ファイルを開く、変数を初期化 ---
INIT-PARA.
    OPEN INPUT IN-FILE
    OPEN OUTPUT OUT-FILE
    MOVE "N" TO WS-EOF-FLAG
    INITIALIZE WS-COUNTERS.

*> --- 2. 主処理: 1レコードずつ読んで処理 ---
PROCESS-PARA.
    READ IN-FILE
        AT END
            SET WS-EOF TO TRUE
        NOT AT END
            PERFORM EDIT-PARA
            PERFORM WRITE-PARA
            ADD 1 TO WS-REC-COUNT
    END-READ.

*> --- 2a. 編集処理: 業務ロジック ---
EDIT-PARA.
    IF IN-STATUS = "A"
        MOVE "Active" TO OUT-STATUS-TEXT
    ELSE
        MOVE "Inactive" TO OUT-STATUS-TEXT
    END-IF.

*> --- 2b. 書き込み ---
WRITE-PARA.
    WRITE OUT-RECORD.

*> --- 3. 終了処理: ファイルを閉じる、集計表示 ---
TERM-PARA.
    CLOSE IN-FILE
    CLOSE OUT-FILE
    DISPLAY "Processed: " WS-REC-COUNT " records".

この構成を図で表すと:

8.5 標準プロシージャ構成パターン

MAIN-PARA

INIT-PARA(初期化)

PROCESS-PARA × n回(EOFまで)

TERM-PARA(終了処理)

OPEN ファイル

変数初期化

READ → EDIT-PARA → WRITE-PARA

カウンタ加算

CLOSE ファイル

集計表示

設計のポイント:

  • MAIN-PARA は「何をするか」の一覧だけ書く(処理の詳細は書かない)
  • 各段落は1つの責務だけ持つ(初期化、編集、書き込み、終了)
  • PERFORM で呼び出す = 段落が「関数」の役割を果たす
  • ネストが深くなったら新しい段落に切り出す

8.6 比較演算子

COBOL記法記号意味
IS EQUAL TO=等しい
IS NOT EQUAL TONOT =等しくない
IS GREATER THAN>より大きい
IS LESS THAN<より小さい
IS GREATER THAN OR EQUAL TO>=以上
IS LESS THAN OR EQUAL TO<=以下
*> 英語記法と記号記法は同じ意味
IF WS-AGE IS GREATER THAN 20 ...
IF WS-AGE > 20 ...

*> 複合条件
IF WS-AGE >= 20 AND WS-GENDER = "M" ...
IF WS-DEPT = "SALES" OR WS-DEPT = "HR" ...
IF NOT (WS-STATUS = "ACTIVE") ...

8.7 特殊条件

IF WS-NAME IS NUMERIC ...         *> 数字のみか
IF WS-NAME IS ALPHABETIC ...      *> 英字のみか
IF WS-NAME IS SPACES ...          *> 全てスペースか
IF WS-COUNTER IS ZERO ...         *> ゼロか(= 0 と同じ)
IF WS-COUNTER IS POSITIVE ...     *> 正数か
IF WS-COUNTER IS NEGATIVE ...     *> 負数か

9. ファイル操作

COBOLのファイル操作は以下の手順で行う:

1. ENVIRONMENT DIVISION で SELECT(論理名と物理名の紐付け)
2. DATA DIVISION の FILE SECTION で FD(レコード構造の定義)
3. PROCEDURE DIVISION で OPEN → READ/WRITE → CLOSE

9.1 SELECT 句(ファイル定義)

FILE-CONTROL.
    SELECT ファイル論理名
        ASSIGN TO "物理ファイルパス"
        ORGANIZATION IS ファイル編成
        FILE STATUS IS 状態変数.

9.2 ORGANIZATION(ファイル編成)

種類説明用途
SEQUENTIAL順編成(先頭から順にアクセス)固定長データファイル
LINE SEQUENTIAL行順編成(改行区切りのテキスト)CSV、ログ、テキストファイル
INDEXED索引編成(キーで直接アクセス)マスタファイル
RELATIVE相対編成(レコード番号でアクセス)番号ベースの検索

SEQUENTIAL vs LINE SEQUENTIAL の違い:

特性SEQUENTIALLINE SEQUENTIAL
レコード区切りなし(レコード長で判断)改行文字(LF / CRLF)
レコード長固定可変
ファイル形式バイナリ的テキスト
主な用途固定長データCSV、テキストファイル

参照: file-fixed.cob:16-19(SEQUENTIAL), file-csv.cob:13-16(LINE SEQUENTIAL)

9.3 FD(ファイル記述)

FILE SECTION.

*> 固定長ファイルの場合
FD EMP-FILE
    RECORD CONTAINS 36 CHARACTERS.
01 EMP-RECORD.
    05 EMP-ID     PIC X(5).
    05 EMP-NAME   PIC X(20).
    05 EMP-DEPT   PIC X(8).
    05 EMP-AGE    PIC 9(3).

*> 可変長ファイル(CSV等)の場合
FD CSV-FILE
    RECORD CONTAINS 100 CHARACTERS.
01 CSV-RECORD    PIC X(100).

参照: file-fixed.cob:30-39, file-csv.cob:27-29

9.4 FILE STATUS(ファイル状態コード)

77 WS-FILE-STATUS   PIC XX.
コード意味
"00"正常終了
"10"EOF(ファイル末尾に達した)
"22"重複キー
"23"レコードが見つからない
"30"永続的エラー
"35"ファイルが存在しない
"39"ファイル属性の不一致
"41"既にOPEN済み
"42"既にCLOSE済み
"44"レコード長オーバー
"47"INPUT以外でREADを実行
"48"OUTPUT以外でWRITEを実行

9.5 OPEN(ファイルを開く)

OPEN INPUT  ファイル名    *> 読み取り専用
OPEN OUTPUT ファイル名    *> 書き込み(新規作成 / 上書き)
OPEN EXTEND ファイル名    *> 追記モード(末尾に追加)
OPEN I-O    ファイル名    *> 読み書き両用
OPEN OUTPUT EMP-FILE
IF WS-FILE-STATUS NOT = "00"
    DISPLAY "OPEN ERROR: " WS-FILE-STATUS
    STOP RUN
END-IF

参照: file-fixed.cob:92-96

9.6 WRITE(書き込み)

*> レコード変数にデータをセットしてから WRITE
MOVE "E001"        TO EMP-ID
MOVE "TANAKA TARO" TO EMP-NAME
WRITE EMP-RECORD

*> CSVの場合(STRINGで行を組み立てて WRITE)
MOVE SPACES TO CSV-RECORD
STRING "P001" DELIMITED BY SIZE
       ","    DELIMITED BY SIZE
       "Item" DELIMITED BY SIZE
       INTO CSV-RECORD
END-STRING
WRITE CSV-RECORD

注意: WRITE の対象は FD配下のレコード名(ファイル名ではない)。

参照: file-fixed.cob:105-111, file-csv.cob:84-96

9.7 READ(読み込み)

READ ファイル名
    AT END
        *> EOF時の処理
        SET WS-EOF TO TRUE
    NOT AT END
        *> 正常読み込み時の処理
        DISPLAY EMP-ID " " EMP-NAME
END-READ

注意: READ の対象は ファイル名(レコード名ではない)。WRITE とは逆。

典型的な読み込みループ:

MOVE "N" TO WS-EOF-FLAG
PERFORM UNTIL WS-EOF
    READ EMP-FILE
        AT END
            SET WS-EOF TO TRUE
        NOT AT END
            ADD 1 TO WS-REC-COUNT
            DISPLAY EMP-ID " " EMP-NAME
    END-READ
END-PERFORM

参照: file-fixed.cob:141-153, file-csv.cob:148-182

9.8 CLOSE(ファイルを閉じる)

CLOSE EMP-FILE

必ずCLOSEすること。 CLOSEしないとデータが書き込まれない場合がある。

9.9 ファイル操作の全体フロー

9.9 ファイル操作の全体フロー

追記

OPEN EXTEND

(MOVE + WRITE) × n回

CLOSE

読み込み

OPEN INPUT

PERFORM UNTIL EOF

(READ + 処理)

CLOSE

書き込み

OPEN OUTPUT

(MOVE + WRITE) × n回

CLOSE


10. 文字列操作

10.1 STRING(文字列の連結)

複数の文字列を1つに連結する。CSVの行を組み立てる時などに使う。

MOVE SPACES TO WS-RESULT
STRING
    "P001"     DELIMITED BY SIZE     *> 全文字を使う
    ","        DELIMITED BY SIZE
    "Widget A" DELIMITED BY SIZE
    ","        DELIMITED BY SIZE
    "1500"     DELIMITED BY SIZE
    INTO WS-RESULT
END-STRING
*> WS-RESULT = "P001,Widget A,1500"

DELIMITED BY の種類:

指定意味
DELIMITED BY SIZE変数の全長を使う(スペース含む)“TARO␣␣␣␣” → “TARO␣␣␣␣“
DELIMITED BY SPACE最初のスペースの手前まで”TARO␣␣␣␣” → “TARO”
DELIMITED BY ","指定文字の手前まで”A,B,C” → “A”
*> POINTER: 連結位置を制御
77 WS-PTR PIC 9(3) VALUE 1.
STRING "Hello" DELIMITED BY SIZE
       " "     DELIMITED BY SIZE
       "World" DELIMITED BY SIZE
       INTO WS-RESULT
       WITH POINTER WS-PTR     *> 書き込み開始位置を指定
END-STRING

*> OVERFLOW: 結果が格納先に収まらない場合の処理
STRING "Very long text..." DELIMITED BY SIZE
       INTO WS-SHORT-FIELD
       ON OVERFLOW DISPLAY "Truncated!"
END-STRING

参照: file-csv.cob:85-94

10.2 UNSTRING(文字列の分解)

区切り文字で文字列を分割する。CSVの解析に使う。

UNSTRING CSV-RECORD
    DELIMITED BY ","
    INTO WS-PROD-CODE
         WS-PROD-NAME
         WS-PROD-PRICE
         WS-PROD-QTY
END-UNSTRING
*> "P001,Widget A,1500,100" →
*>   WS-PROD-CODE  = "P001"
*>   WS-PROD-NAME  = "Widget A"
*>   WS-PROD-PRICE = "1500"
*>   WS-PROD-QTY   = "100"
*> TALLYING: 分割されたフィールド数をカウント
77 WS-FIELD-COUNT PIC 9(3).
UNSTRING WS-LINE
    DELIMITED BY ","
    INTO WS-F1 WS-F2 WS-F3
    TALLYING IN WS-FIELD-COUNT
END-UNSTRING
*> WS-FIELD-COUNT にフィールド数が入る

*> COUNT: 各フィールドの実際の文字数を取得
77 WS-LEN1 PIC 9(3).
77 WS-LEN2 PIC 9(3).
UNSTRING WS-LINE
    DELIMITED BY ","
    INTO WS-F1 COUNT IN WS-LEN1
         WS-F2 COUNT IN WS-LEN2
END-UNSTRING

*> 複数の区切り文字
UNSTRING WS-LINE
    DELIMITED BY "," OR ";" OR "|"
    INTO WS-F1 WS-F2 WS-F3
END-UNSTRING

参照: file-csv.cob:163-168

10.3 INSPECT(文字の検査・置換)

*> TALLYING: 特定文字の出現回数をカウント
INSPECT WS-TEXT TALLYING WS-COUNT FOR ALL ","
*> WS-TEXT 内のカンマの数を WS-COUNT に格納

*> REPLACING: 文字の置換
INSPECT WS-TEXT REPLACING ALL "," BY ";"
*> 全てのカンマをセミコロンに置換

INSPECT WS-TEXT REPLACING LEADING ZEROS BY SPACES
*> 先頭のゼロをスペースに置換

*> CONVERTING: 文字の一括変換(tr コマンド的)
INSPECT WS-TEXT CONVERTING
    "abcdefghijklmnopqrstuvwxyz" TO
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
*> 小文字を大文字に変換

10.4 REFERENCE MODIFICATION(部分参照)

変数の一部を切り出す。他言語の substring に相当。

*> 書式: 変数名(開始位置:長さ)
*> 位置は 1 始まり

MOVE "HELLO WORLD" TO WS-TEXT

DISPLAY WS-TEXT(1:5)     *> "HELLO"    (1文字目から5文字)
DISPLAY WS-TEXT(7:5)     *> "WORLD"    (7文字目から5文字)
DISPLAY WS-TEXT(7:)      *> "WORLD"    (7文字目から末尾まで)

*> 部分的に書き換え
MOVE "COBOL" TO WS-TEXT(7:5)
*> WS-TEXT = "HELLO COBOL"

11. コメントと書式

11.1 コメント

*> これは自由形式のコメント(行のどこにでも書ける)
DISPLAY "Hello"    *> 行末コメント

固定形式(7カラム目)の場合:

      * これは固定形式のコメント(7カラム目に * を書く)

11.2 固定形式 vs 自由形式

項目固定形式自由形式(-free
カラム1-6行番号領域(空白可)なし
カラム7標識領域(*=コメント, -=継続)なし
カラム8-11A領域(DIVISION, SECTION等)なし
カラム12-72B領域(文の本体)なし
カラム73-80識別領域(無視される)なし
コメント7カラム目に **> をどこにでも
行の長さ72カラムまで(本体部分)制限なし

GnuCOBOL では -free オプションで自由形式を使用する(本プロジェクトの方式)。

11.3 継続行

*> 自由形式では普通に複数行に書ける
DISPLAY "This is a very long"
    " string that spans"
    " multiple lines"

11.4 予約語と命名規則

変数名のルール:

  • 英字(A-Z)、数字(0-9)、ハイフン(-)が使用可能
  • 先頭は英字
  • ハイフンで終わらない
  • 最大30文字(GnuCOBOLではもっと長くても可)
  • 大文字・小文字は区別しない

命名慣例:

接頭辞意味
WS-WORKING-STORAGE の変数WS-COUNTER
LS-LOCAL-STORAGE の変数LS-TEMP
LK-LINKAGE の変数LK-PARAM
IS-88レベルの条件名IS-MALE
EMP-従業員レコードのフィールドEMP-NAME

11.5 定数(figurative constants)

定数意味
SPACES / SPACEスペース文字で埋める
ZEROS / ZEROES / ZEROゼロで埋める
HIGH-VALUES最大値(X”FF”)で埋める
LOW-VALUES最小値(X”00”)で埋める
QUOTES / QUOTE引用符で埋める
ALL "x"指定文字で埋める
MOVE SPACES TO WS-NAME        *> 全スペース
MOVE ZEROS  TO WS-COUNTER     *> 全ゼロ
MOVE ALL "*" TO WS-LINE       *> 全て "*"

12. コンパイルと実行

12.1 GnuCOBOL の基本コマンド

# コンパイル + 実行ファイル生成
cobc -x -free -o 出力名 ソース.cob

# オプション:
#   -x     : 実行ファイルを生成(必須)
#   -free  : 自由形式(Free Format)
#   -o     : 出力ファイル名

# 実行
./出力名

12.2 よく使うコンパイルオプション

オプション説明
-x実行可能ファイルを生成
-free自由形式(Free Format)
-fixed固定形式(デフォルト)
-o ファイル名出力ファイル名を指定
-Wall全ての警告を表示
-debugデバッグ情報を埋め込む
-std=cobol2014COBOL 2014 準拠モードでコンパイル
-vコンパイル過程の詳細表示

12.3 コンパイル例

# 基本
cobc -x -free -o hello hello.cob

# 全警告 + デバッグ情報付き
cobc -x -free -Wall -debug -o myapp myapp.cob

# 複数ファイルのコンパイル
cobc -x -free -o myapp main.cob sub1.cob sub2.cob

付録: 本プロジェクトのサンプル一覧

ファイル内容学べること
hello.cobHello World最小構成のCOBOLプログラム
structure.cob構造デモ4つのDIVISION、レベル番号、PIC、88条件名
file-fixed.cob固定長ファイルSEQUENTIAL、FD、WRITE/READ、OCCURS
file-csv.cobCSVファイルLINE SEQUENTIAL、STRING、UNSTRING
salary-main.cob給与計算メイン外部CALL、COPY句、エラーハンドリング
calc-salary.cob給与計算サブLINKAGE、GOBACK、バリデーション
copybooks/salary-record.cpy共通レコードCOPY句、リクエスト/レスポンスパターン

| report-print.cob | 帳票出力 | LINAGE、WRITE ADVANCING、FILLER |

関連ドキュメント:


関連記事