COBOL記述時の注意点(初心者の陥りやすい罠)

 時々COBOL熟練者様からもお便りを戴きます。その中で自分が初めてCOBOL言語に触れたとき、クセがあるなと気づいた点を指摘していただきました。この場を借りてお礼申し上げます。私もCOBOLに慣れ過ぎ、すっかり忘れていました。言われてみればナルホドと頷くものばかりです。例題を挙げながら解説します。現時点で命令語や文法は理解しなくて構いません。必ず後々この頁を見直す時が訪れます。

  1. 予約語が完結する前に余計なピリオドを入れてはいけない
  2. 予約語の完了時には必ずピリオド
  3. 予約語と予約語の間には1文字以上の空白をいれる
  4. そもそも予約語のスペルが誤まっている
  5. <PROGRAM-ID> 英字で始まっていない
  6. <PROGRAM-ID> 8文字を超えている
  7. <WORKING-STORAGE> 空文字は使用できない(命令語も同様)
  8. <WORKING-STORAGE> 桁数と初期値が合ってない
  9. <WORKING-STORAGE> これはエラーにならない
  10. <LINKAGE> 01レベル指定時は全て記述すること
  11. <LINKAGE> 下位レベル指定の記述はできない
  12. <命令文> IF〜END-IFの記述中にピリオドは使用禁止
  13. <命令文> 各命令文での省略系(ピリオドで終了させる場合)
  14. <共通> 一行は必ず80カラム(桁)で収める(有効桁は72カラムまで)
  15. <共通> 各SECTIONの最後には必ずピリオドが必要
  16. <命令文> IF文ではTHENの記載を省略できる
※他にも何か気づいた点がございましたらメールでお知らせ下さると助かります。

▼メニューへ

*>> 予約語が完結する前に余計なピリオドを入れてはいけない

 IDENTIFICATION.     DIVISION.
*
 ENVIRON.MENT        DIVISION.
*
 CONFIGURATION.      SECTION.

こういう簡単なエラーはわかり易いのでいいんですけどね
▲トップへ  ▼メニューへ
*>> 予約語の完了時には必ずピリオド

 IDENTIFICATION      DIVISION
*
 FILE-CONTROL

これも簡単ですね。どの予約語にピリオドが必須なのか、よく覚えましょう。
▲トップへ  ▼メニューへ
*>> 予約語と予約語の間には1文字以上の空白をいれる

 IDENTIFICATIONDIVISION.

 PROGRAM-ID.12345678.

当たり前のことですが、予約語(命令語)の直後に連続して英数字を書いていたら、
誰だって意味がわかりません。それは機械でも同じことです。ピリオドがあってもダメ
なものはダメですよ!
▲トップへ  ▼メニューへ
*>> そもそも予約語のスペルが誤まっている

 DATE DIVISION.
*
      WRITO A FROM B.
*
      DISPLEY "ABC".

えっと、話になりません。以上です。必死に覚えましょう。
▲トップへ  ▼メニューへ
*>> <PROGRAM-ID> 英字で始まっていない

 PROGRAM-ID. 12345678.
*
 PROGRAM-ID. @1234567.

プログラム名は必ず英字で始まる必要があります。

▲トップへ  ▼メニューへ
*>> <PROGRAM-ID> 8文字以内でなければならない

 PROGRAM-ID. ABC123456.

プログラム名は8文字以内で収まらなければなりません。最低3文字以上の名前にしましょう。
▲トップへ  ▼メニューへ
*>> <WORKING-STORAGE> 空文字は指定できない(命令語も同様)

 01  W-TEXT PIC X(4) VALUE "".

   *> 正解は以下の通り ↓

 01  W-TEXT PIC X(4) VALUE SPACE.  *>もしくは↓
 01  W-TEXT PIC X(4) VALUE "    ".

これも他言語ではよく利用されますが、COBOLでは禁止になっています。注意して下さい。
▲トップへ  ▼メニューへ
*>> <WORKING-STORAGE> 桁数と初期値が合っていない

 01  IN-CNT PIC 9(2) VALUE 100.
 01  W-TEXT PIC X(4) VALUE "ABCDE".

桁数以上の初期値は設定できません。結構頻繁に見かけるエラーです。
▲トップへ  ▼メニューへ
*>> <WORKING-STORAGE> これはエラーになりません

 01  IN-CNT PIC 9(4) VALUE 100.      *>データは"0100"になる
 01  W-TEXT PIC X(6) VALUE "ABCDE".  *>データは"ABCDE "になる

桁数以内であれば必ずしも桁数に達している必要はありません。
空いた列には数字であればゼロ、文字であれば空白が入ります。
▲トップへ  ▼メニューへ
*>> <LINKAGE> 01レベル指定時は全て記述

 LINKAGE SECTION.
 01  L-PARA1  PIC X(1).
 01  L-PARA2  PIC X(5).
 PROCEDURE DIVISION USING L-PARA1.

   *> 正解は以下の通り ↓

 PROCEDURE DIVISION USING L-PARA1 L-PARA2.

外部パラメータを利用する場合、独立項目(01レベル)は全て記述する必要があります。
▲トップへ  ▼メニューへ
*>> <LINKAGE> 下位レベル指定の記述はできない

 LINKAGE SECTION.
 01  L-PARA.
     03  L-P1  PIC X(1).
     03  L-P2  PIC X(5).
 PROCEDURE DIVISION USING L-P1 L-P2.

   *> 正解は以下の通り ↓

 PROCEDURE DIVISION USING L-PARA.

集団項目の場合、LINKAGE SECTIONの指定は、必ずトップ項目を記述しなければなりません。
▲トップへ  ▼メニューへ
*>> <命令語> IF〜END-IFなどの中にピリオドは打てない

         IF  A = ZERO
            MOVE  1  TO  B.
            MOVE  2  TO  C.
         END-IF.

ピリオドは文の終わりを意味します。上記の場合ではEND-IFの記述と同じ扱いになります。
MOVE 2 TO C は無条件で処理、最後の END-IF はエラーとなります。
▲トップへ  ▼メニューへ
*>> <命令語> 各命令文での省略系(ピリオドで終了させる場合)

         IF  A = ZERO
            MOVE  1  TO  B.

         IF  A = ZERO
           MOVE  1  TO  B
           MOVE  2  TO  C.

         PERFORM UNTIL IN-REC = HIGHVALUE
            PERFORM  READ-R.

         READ  IN-FILE
            AT END
               MOVE  HIGH-VALUE TO IN-REC.

        START  IN-FILE
            INVALID  "1" TO FLAG.

       SEARCH  WK-TABLE
           AT END  MOVE  1 TO FLAG
           WHEN  WK-AAA(IDX) = ZZ-AAA
               MOVE  99  TO  FLAG.

このように、命令の終了である"END"は、ピリオドをつける事で省略可能になります。
(END-IF,END-READ,END-PERFORM,END-START,END-STRING、などなど)
私個人の意見としては、命令文はIF〜END-IF,PERFORM〜END-PERFORMのように、
必ずEND-XXXXで終わるのが基本だと思います。また省略することで混乱の原因にもな
りお薦めできません。必ず"END"の記述するように心掛けましょう。
▲トップへ  ▼メニューへ
*>> <命令語> 1行は必ず80カラム(桁)まで

...1.T..*....2....*....3....*....4....*....5....*....6....*....7.

     MOVE   1    TO   B   C   D   E   F   G   H   I   J   K   L   M  N  O  P.

このMOVE命令はLまでで、以降のM〜Pまでは無視されます。
また80カラムを超える行は翻訳ソフトによって扱えません。
折り返す場合には7カラム目に"-"を記述しましょう。

記述するなら以下のようになります。

...1.T..*....2....*....3....*....4....*....5....*....6....*....7.

     MOVE   1    TO   B   C   D   E   F   G   H   I   J   K   L
-                     M   N   O   P.
▲トップへ  ▼メニューへ
*>> <命令語> 各SECTION内の最後は必ずピリオドで終わる

 LOOP  SECTION.
     PERFORM   OPEN-R
     EVALUATE  TRUE
         WHEN MST-KEY > TRN-KEY
                PERFORM   READ-M
         WHEN MST-KEY < TRN-KEY
                PERFORM WRITE-R
                PERFORM   READ-T
                PERFORM   READ-M
         WHEN MST-KEY > TRN-KEY
                PERFORM   READ-T
     END-EVALUATE
     PERFORM CLOSE-R
 LOOP-E. EXIT.

このようにPROCEDURE内で独自に作成した処理別のSECTIONを利用
する場合には、SECTIONの最後の行には必ずピリオドが必要です。
上記の例では最後の命令である、「PERFORM CLOSE-R」にピリオドを
つけ、「PERFORM CLOSE-R.」としなくてはなりません。

勿論、各命令の最後に全てピリオドをつけても構いません。
以下の2つの例はどちらでもOKになります。

 LOOP  SECTION.
     PERFORM   OPEN-R
     EVALUATE  TRUE
         WHEN MST-KEY < TRN-KEY
                PERFORM   READ-M
         WHEN MST-KEY = TRN-KEY
                PERFORM   WRITE-R
                PERFORM   READ-T
                PERFORM   READ-M
         WHEN MST-KEY > TRN-KEY
                PERFORM   READ-T
     END-EVALUATE
     PERFORM CLOSE-R.
 LOOP-E. EXIT.

 LOOP  SECTION.
     PERFORM   OPEN-R.
     EVALUATE  TRUE
         WHEN MST-KEY < TRN-KEY
                PERFORM   READ-M
         WHEN MST-KEY = TRN-KEY
                PERFORM   WRITE-R
                PERFORM   READ-T
                PERFORM   READ-M
         WHEN MST-KEY > TRN-KEY
                PERFORM   READ-T
     END-EVALUATE.
     PERFORM CLOSE-R.
 LOOP-E. EXIT.

上記の2パターンは全く同じ動作をします。全ての文の最後にピリオドをつけてもいいし、
最後の一行にだけピリオドをつけても動作は変わらない、ということを理解して下さい。
▲トップへ  ▼メニューへ
*>> <命令語> IF文のTHENは省略できる

         IF  A = ZERO
           THEN
               MOVE  1  TO  B
         END-IF

IF文はIF  THEN  ELSE  END-IFというのが一連の流れなんですが、COBOLの場合、
THENの記述は省略が可能になっています。別に書いても構いません。エラーにもなりま
せん。ですが、現状ではほとんど記述を省略されています。
▲トップへ  ▼メニューへ

<< Back    Index   Next >>   < Top >