コーディング · プログラミング言語
COBOL入門:初心者向けチュートリアル
結論
COBOL(Common Business-Oriented Language)は、レコード、ファイル、帳票、正確な10進演算といった業務データ処理のために設計された、コンパイル型の言語です。プログラムは4つの部(DIVISION)に分かれ、データはPIC(picture)句で記述し、コードはADD AMOUNT TO TOTALのように英語の文章のように読めます。今でも銀行、保険会社、政府の基幹システムで、主にIBMメインフレーム上で動いています。GnuCOBOLコンパイラ(cobc -x hello.cob)を使えば、無料で学べます。
COBOLとは何か、誰が使うのか
COBOLは1959年にCODASYL委員会が設計し、Grace Hopperの先行する言語FLOW-MATICの影響を強く受けています。ISOで標準化されており、後の規格で構造化プログラミング、オブジェクト指向などの機能が加わり、直近の改訂は2023年に公開されました。
COBOLは、バッチ処理とトランザクションシステムに使われています。口座処理、給与計算、保険金の請求、税や給付のシステムなどです。このコードの多くは、IBM Enterprise COBOLを使ってIBM Zメインフレーム上で動き、トランザクションにはCICS、データにはDb2が組み合わされます。これらのシステムの保守と近代化の仕事は、今も多くあります。
GnuCOBOLのインストールとhello, worldの実行
GnuCOBOLは、COBOLをCに変換してからネイティブプログラムにする、無料のコンパイラです。多くのLinuxディストリビューションではgnucobolパッケージ、macOSではHomebrewで入手できます。Windowsでは、WSLかビルド済みパッケージを使えます。
IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO.
PROCEDURE DIVISION.
DISPLAY "Hello, world!".
STOP RUN.cobc -x hello.cob
./hello
# Hello, world!このコードは従来の固定形式を使っています。1〜6桁目は連番用、7桁目はコメント(*)または継続行の印、A領域(8〜11桁目)には部、節、段落の名前、B領域(12〜72桁目)には文を書きます。GnuCOBOLは、cobc -x -freeで自由形式のソースも受け付けます。オプション-xは、モジュールではなく実行ファイルをビルドします。
4つの部
| 部 | 目的 |
|---|---|
| IDENTIFICATION DIVISION | プログラムに名前を付ける(PROGRAM-ID) |
| ENVIRONMENT DIVISION | プログラムを外部とつなぐ。たとえば使うファイルなど |
| DATA DIVISION | すべてのデータを宣言する。ファイルのレコード、作業用記憶域、パラメーター |
| PROCEDURE DIVISION | 実行文。段落にまとめられる |
すべての変数は、使う前にDATA DIVISIONで宣言しなければなりません。WORKING-STORAGE SECTIONにはプログラムの変数、FILE SECTIONにはファイルのレコード、LINKAGE SECTIONには呼び出し側から渡されるパラメーターを記述します。
データとPIC句
COBOLは、データを正確なレイアウトで記述します。レベル番号は階層を示し(01はレコード、05はその中のフィールド)、PIC句が形式を指定します。Xは任意の文字、9は数字、Sは符号、Vは暗黙の小数点です。
| 宣言 | 意味 | 値の例 |
|---|---|---|
PIC X(10) | 10文字。空白で埋められる | "Ana " |
PIC 9(3) | 符号なしの3桁の数 | 030 |
PIC S9(5)V99 | 符号付き。小数点の前が5桁、後が2桁 | -01234.50 |
PIC $ZZ,ZZ9.99 | 編集出力:通貨記号、先頭のゼロは空白に | $ 1,234.50 |
PIC S9(7)V99 COMP-3 | パック10進数。メインフレームでよく使う | 5バイトで格納 |
88 IS-DONE VALUE "Y" | 条件名:親のフィールドに対する真偽値のテスト | IF IS-DONE |
IDENTIFICATION DIVISION.
PROGRAM-ID. DATA-DEMO.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-NAME PIC X(10) VALUE "Ana".
01 WS-AGE PIC 9(3) VALUE 30.
01 WS-PRICE PIC S9(5)V99 VALUE 1234.50.
01 WS-PRICE-OUT PIC $ZZ,ZZ9.99.
01 WS-CUSTOMER.
05 WS-FIRST PIC X(10).
05 WS-LAST PIC X(15).
PROCEDURE DIVISION.
MOVE WS-PRICE TO WS-PRICE-OUT
DISPLAY WS-NAME "is " WS-AGE
DISPLAY "Price: " WS-PRICE-OUT
STOP RUN.
*> Ana is 030
*> Price: $ 1,234.50数値は10進数で格納されるため、0.10 + 0.20は正確に0.30になります。これが、COBOLがお金の扱いに向いている理由の1つです。WS-CUSTOMERは集団項目で、全体でも、フィールドごとでも移動できます。
制御構文:IF・EVALUATE・PERFORM
IDENTIFICATION DIVISION.
PROGRAM-ID. CONTROL-DEMO.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-I PIC 99.
01 WS-TOTAL PIC 9(4) VALUE 0.
01 WS-SCORE PIC 999 VALUE 85.
PROCEDURE DIVISION.
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 10
ADD WS-I TO WS-TOTAL
END-PERFORM
DISPLAY "Total: " WS-TOTAL
EVALUATE TRUE
WHEN WS-SCORE >= 90
DISPLAY "A"
WHEN WS-SCORE >= 80
DISPLAY "B"
WHEN OTHER
DISPLAY "C"
END-EVALUATE
IF WS-TOTAL > 50
DISPLAY "big"
ELSE
DISPLAY "small"
END-IF
STOP RUN.
*> Total: 0055
*> B
*> bigPERFORM VARYINGはCOBOLのカウント付きループ、PERFORM UNTIL conditionはwhileループです。EVALUATEはswitch文にあたります。END-IFやEND-PERFORMなどの範囲終了子が各ブロックを閉じ、ピリオドは文全体を終わらせます。
段落・算術・テーブル
COBOLには、一般的な意味での関数がありません。ロジックは名前付きの段落にまとめてPERFORMで実行し、より大きな単位はCALL "PROG" USING ...で呼ぶ別プログラムにします。算術には動詞(ADD、SUBTRACT、MULTIPLY、DIVIDE)か、式を使うCOMPUTEを使います。配列はテーブルと呼ばれ、OCCURSで宣言し、添字は1から始まります。
IDENTIFICATION DIVISION.
PROGRAM-ID. PARA-DEMO.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-PRICES.
05 WS-PRICE PIC 9(3)V99 OCCURS 3 TIMES.
01 WS-I PIC 9.
01 WS-SUM PIC 9(4)V99 VALUE 0.
01 WS-SUM-OUT PIC Z,ZZ9.99.
PROCEDURE DIVISION.
MAIN-PARA.
MOVE 10.50 TO WS-PRICE(1)
MOVE 4.25 TO WS-PRICE(2)
MOVE 7.00 TO WS-PRICE(3)
PERFORM ADD-PRICE VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 3
COMPUTE WS-SUM = WS-SUM * 1.1
MOVE WS-SUM TO WS-SUM-OUT
DISPLAY "With 10% tax: " WS-SUM-OUT
STOP RUN.
ADD-PRICE.
ADD WS-PRICE(WS-I) TO WS-SUM.
*> With 10% tax: 23.92合計は21.75で、1.1を掛けると23.925になりますが、COMPUTE ... ROUNDEDと書かない限り、COBOLは宣言された小数2桁に切り捨てます(23.92)。
エラー処理
日常的なコードでは、COBOLに例外はありません。代わりに、文に条件句があります。算術のオーバーフローやゼロ除算にはON SIZE ERROR、ファイルの終わりにはAT END、索引ファイルにはINVALID KEY、そしてファイル操作のたびに2文字のコードを受け取るFILE STATUSフィールドです("00"は成功を意味します)。
DIVIDE WS-A BY WS-B GIVING WS-C
ON SIZE ERROR
DISPLAY "Division failed"
NOT ON SIZE ERROR
DISPLAY "Result: " WS-C
END-DIVIDE小さな完成プログラム:売上ファイルの合計
固定レイアウトのレコードをファイルから読み込むのは、典型的なCOBOLの仕事です。このプログラムはsales.txtを読みます。各行は、10文字の品名に続いて、暗黙の小数2桁を持つ7桁の金額です。
apples 0001250
pears 0000899
plums 0002000 IDENTIFICATION DIVISION.
PROGRAM-ID. SALES-TOTAL.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT SALES-FILE ASSIGN TO "sales.txt"
ORGANIZATION IS LINE SEQUENTIAL
FILE STATUS IS WS-FS.
DATA DIVISION.
FILE SECTION.
FD SALES-FILE.
01 SALES-REC.
05 SR-ITEM PIC X(10).
05 SR-AMOUNT PIC 9(5)V99.
WORKING-STORAGE SECTION.
01 WS-FS PIC XX.
01 WS-EOF PIC X VALUE "N".
88 NO-MORE-RECORDS VALUE "Y".
01 WS-TOTAL PIC 9(7)V99 VALUE 0.
01 WS-TOTAL-OUT PIC Z,ZZZ,ZZ9.99.
PROCEDURE DIVISION.
OPEN INPUT SALES-FILE
IF WS-FS NOT = "00"
DISPLAY "Cannot open file, status " WS-FS
STOP RUN
END-IF
PERFORM UNTIL NO-MORE-RECORDS
READ SALES-FILE
AT END SET NO-MORE-RECORDS TO TRUE
NOT AT END ADD SR-AMOUNT TO WS-TOTAL
END-READ
END-PERFORM
CLOSE SALES-FILE
MOVE WS-TOTAL TO WS-TOTAL-OUT
DISPLAY "Total sales: " WS-TOTAL-OUT
STOP RUN.実行すると、Total sales:に続いて、12文字の編集フィールドに右寄せで41.49が出力されます。LINE SEQUENTIALは、1行が1レコードのテキストファイルを意味し、GnuCOBOLなどのPC向けコンパイラが対応しています。メインフレームのプログラムは通常、JCLで定義した固定長のデータセットを読みます。
次に学ぶこと
- GnuCOBOLプロジェクトのページと、言語リファレンスの全体像がわかるProgrammer's Guide。
- メインフレームのCOBOL、CICS、Db2の使い方についての、IBMのEnterprise COBOL for z/OSのドキュメント。
- ファイルの読み書き、
SORT動詞による並べ替え、整形した帳票の出力を練習する。 - 本番のシステムで働きたいなら、周辺のメインフレームツール(JCL、TSO/ISPF)を学ぶ。
よくある質問
COBOLは今でも使われていますか?
はい。多くの銀行、保険会社、官公庁が、基幹のバッチ処理やトランザクション処理で今もCOBOLプログラムを動かしており、それらを保守・近代化できる開発者への需要が続いています。
COBOLは習得が難しいですか?
構文は冗長ですが単純で、ほとんどの初心者はすぐに動くプログラムを書けます。難しいのは、周辺のメインフレーム環境、つまりJCL、データセット、CICS、Db2のほうです。
メインフレームなしでCOBOLを学べますか?
はい。GnuCOBOLはLinux、macOS、Windowsで動き、標準的なCOBOLに対応しているので、メインフレームに移る前に、普通のコンピューターでこの言語を学べます。
COBOLはなぜ10進数を使うのですか?
お金のような業務データは正確でなければなりません。COBOLは数値を、小数の桁数が固定された10進の数字として格納するため、2進の浮動小数点数の丸め誤差を避けられます。