cv.cm

コーディング · プログラミング言語

COBOL入門:初心者向けチュートリアル

約11分で読めます

結論

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
      *> big

PERFORM 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進の浮動小数点数の丸め誤差を避けられます。

コーディング講座の一覧