Cobolの基本
 

 Cobol自体今更って感じですが、あえて書いてみたいと思います。
 過去に日本ユニシスの汎用機、NECのオフコン、富士通のNetCobolについて仕事をしてきてますが、今は富士通のNetCobolを使っているので、ベースはそれで説明します。
 基本的には、あまり変わらないので、こんなもんか〜と思ってみてください。

 プログラムの構成
  1.IDENTIFICTION DIVITION.
  2.ENVIRONMENT  DIVITION.
  3.DATA      DIVITION.
  4.PROCEDURE   DIVITION.

  コボルは基本的にこの4つのDIVITIONより構成されています。

  それぞれの意味について
  1.IDENTIFICATION DIVITIONではプログラム名や作者などを指定します。

     IDENTIFICATION  DIVITION.
     PROGRAM-ID.    SAMPLE.    :プログラム名
     AUTHOR.      METABON.    :作者名

  2.ENVIRONMENT DIVITIONでは、環境について指定します。

    このDIVITIONの中で、CONFIGURATION SECTION、INPUT-OUTPUT SECTIONの記述をします。
    ・CONFIGURATION SECTIONには翻訳用コンピュータの記述、実行コンピュータの記述と、
     環境変数やコマンドラインについての記述を行います。
    ・INPUT-OUTPUT SECTIONには、プログラムが使用するファイルの定義を行います。

     ENVIRONMENT    DIVITION.
     
CONFIGURATION   SECTION.
     SOURCE-COMPUTER. 翻訳用コンピュータ名
     OBJECT-COMPUTER. 実行コンピュータ名
     
     ARGUMENT-NUMBER   IS A-NUM.  コマンドラインの引数の数を取得する変数です。
     ARGUMENT-VALUE    IS A-VAL.  コマンドラインの引数を取得する変数です。

     ENVIRONMENT-NAME   IS E-NAM.  環境変数の名前を指定する変数です。
     ENVIRONMENT-VALUE  IS E-VAL.  環境変数の値を扱う変数です。
     
     INPUT-OUTPUT   SECTION.
     FILE-CONTROL.

     ※シーケンシャルファイルの場合
     SELECT INFILE  ASSIGN  TO INPUT
         ACCESS  MODE   IS SEQUENTIAL シーケンシャル指定です
         ORGANIZATION    IS SEQUENTIAL. シーケンシャル指定です
     ※索引ファイルの場合
     SELECT INFILE2  ASSIGN  TO INPUT2
         ACCESS  MODE   IS RANDOM   ランダム指定です
         RECORD  KEY    IS IN2-KEY   キーを指定します
         ORGANIZATION    IS INDEXED.  インデックス指定です
     ※出力ファイル
     SELECT OTFILE  ASSIGN  TO OUTPUT
         ACCESS  MODE   IS SEQUENTIAL シーケンシャル指定です
         ORGANIZATION    IS SEQUENTIAL. シーケンシャル指定です
     ※プリンタファイルの場合
     SELECT PRNTR   ASSIGN  TO PRINTER.  プリンタを指定します

  3.DATA DIVITIONでは、データの定義を行います。

    FILE SECTIONとWORKING-STRAGE SECTION、LINKAGE SECTIONなどの指定をします
    ・FILE SECTIONには、入出力ファイルのレイアウトを定義します。
    ・WORKING-STORAGEには、ワーク用の変数を定義します。
    ・LINKAGEには、別のプログラムから受け取る変数の指定をします。

     データの定義の基本
     レベル番号 データ名 PIC データタイプ(桁数).
     01 DATA       PIC X(001).
     
     データタイプの種類
      
      英数字タイプ  X
      数字タイプ   9
      日本語タイプ  N

     DATA       DIVITION.
     FILE       SECTION.
     FD INFILE.
     01 IN-REC.
       03 IN-DATA01  PIC X(001).
       03 IN-DATA02  PIC 9(001).
       03 IN-DATA03  PIC N(001).

     01 OT-REC.
       03 OT-DATA01  PIC X(001).
       03 OT-DATA02  PIC 9(001).
       03 OT-DATA03  PIC N(001).

     WORKING      SECTION.

     ※ データ定義時に初期値を代入するのには、VALUE句を使います。

     01 END-SW      PIC X(001).
     01 WORK-DATA    PIC X(003).
     01 DATA-COUNT    PIC 9(003) VALUE 0. 

     LINKGE      SECTION.
     01 PARAM      PIC X(001).

  4.PROCEDURE DIVITIONでは、ロジックの記述を行います。

    ・受け取るパラメータのある場合は、この記述の後にUSING パラメータ名を記述します。

    PROCEDURE      DIVITION.   パラメータ無しのとき。
    PROCEDURE      DIVITION
            UGING PARAM.   パラメータありのとき。
   

コマンドの種類

 Cobolでコーディングするときは、基本的にそんなに沢山のコマンドを覚えなくても大丈夫だと
思います。その中でも、よく使うコマンドを紹介したいと思います。

  ファイル操作

OPEN ファイルを開く。
OPEN INPUT.   INFILE(読込専用として開く)
OPEN OUTPUT.   OTFILE(出力専用として開く)
OPEN I-O.    INFILE(読み書き用として開く)
CLOSE ファイルを閉じる。
CLOSE INPUT.
READ  ファイルを読み込む。
READ INFILE.
WRITE    ファイルに書き込む。
WRITE OT-REC.
REWRITE   ファイルに上書きする。
REWRITE OT-REC.
RELEASE   ソートファイルに書き込む。
RELEASE S-REC.
RETURN   ソートファイルから読み込む。
RETURN S-FILE.

  データ操作

MOVE データを変数にセットする。
IN-DATA01に1をセットする。(文字の場合は、""で括って送る)
MOVE "1"   TO IN-DATA01
IN-DATA02に1をセットする。(数字の場合はそのまま送る)
MOVE 1    TO IN-DATA02
IN-DATA03に1をセットする。(日本語の場合はNC""で括って送る)
MOVE NC"1"  TO IN-DATA03
ACCEPT 日時の取得
ACCEPT SYSDATE FROM DATE    (コンピュータ日付をSYSDATEに取込)
ACCEPT SYSTIME FROM TIME    (コンピュータ時間をSYSTIMEに取込)
ACCEPT SYSWEEK FROM DAY-OF-WEEK(コンピュータ曜日をSYSWEEKに取込む)
コマンドライン変数を取得
ACCEPT ARG-NUM FROM A-NUM.   (コマンド変数の数を取得)
ACCEPT ARG-VAL FROM A-VAL.   (コマンド変数の取得)
環境変数を取得
ACCEPT HENSU  FROM E-VAL.
DISPLAY 指定した内容を画面に表示
DISPLAY "この文字を表示します" UPON CONSOLE.
コマンドライン変数の何番目を指定する。
DISPLAY COUNT UPON A-NUM.
環境変数名をセットする。
DISPLAY "OS"    UPON E-NAM.
環境変数に値をセットする。
DISPLAY "WINDOWS" UPON E-VAL.
COMPUTE  計算する。
COMPUTE KOTAE = 1 * 10.
結果を四捨五入する。
COMPUTE KOTAE ROUNDED = 20 / 3.
INITIALIZE 指定したデータを初期化する。
INITIALIZE END-SW DATA-COUNT.
英数字項目は空白が、数字項目は0がセットされる。
INSPECT 特定の文字を特定の文字で置き換える。
(WORK-DATAの全ての空白を"1"に置き換える。
INSPECT WORK-DATA REPLACING ALL" " BY "1".
ADD 足し算(KEKKAに1を足してKEKKAに代入)
ADD  1  TO KEKKA. 
SUBTRACT 引き算(KEKKAから1を引いてKEKKAに代入)
SUBTRACT 1 FROM KEKKA 
MULTIPLY 掛け算(KEKKAに2を掛けてKEKKAに代入)
MULTIPLY 2 BY KEKKA.
DIVIDE 割り算(KEKKAを2で割ってKEKKAに代入余りをAMARIに代入)
DIVIDE 2 INTO KEKKA GIVING AMARI. 

  制御関係

PERFORM モジュールへ制御を移す。

EXITを使う場合

  PERFORM module.

module.

module-ext.
  EXIT.

THRUを使った場合
  PERFORM module-s THRU module-e

module-s.

module-e.
うちPERFORM
  MOVE 0   TO CNT.
  PERFORM UNTIL CNT >= 5
    ADD 1 TO CNT
  END-PERFORM. 
GO TO 指定のラベルへ制御を移す。
  GO TO LABEL1.

LABEL1.
IF〜
ELSE
END-IF.
条件による分岐
IF END-SW = "E"
  GO TO SYURYO   (真の時の処理)
ELSE
  PERFORM READ-RTN  (偽の時の処理)
END-IF.
CALL 別のプログラムを起動する。
引数のない時
CALL "SUBPROG".
引数のある時
CALL "SUBPROG" USING PARAM.
EVALUATE 複数条件による分岐
EVALUATE SYORI-FLG
  WHEN "1"
     MOVE "001"    TO WORK-DATA
  WHEN "2"
     MOVE "002"    TO WORK-DATA
  WHEN OTHER
     MOVE "OTH"    TO WORK-DATA
END-EVALUATE.

データベースアクセス

 データベースにアクセスするには、幾通りかありますが、ここではODBCを使ったデータベースアクセスについて記述したいと思います。
 NetCobolでは、ODBCの利用の際には、事前にデータベースアクセスのための環境ファイルを作成する必要があります。(ODBC情報ファイル)

 DATA DIVITIONの内容

 データ変数定義
 
 EXEC SQL
    BEGIN DECLARE SECTION
 END-EXEC

 ここにデータベースで使用する変数を定義します。
 実際のデータベースのフィールド名ではありません。
 01 CUSTOM-CODE     PIC X(003).

 EXEC SQL
    END DECLARE SECTION
 END-EXEC

 特殊な変数
 01 SQLSTATE PIC X(005) ODBCのメッセージコード
 01 SQLMSG  PIC X(100) 日本語のメッセージ

 PROCEDURE DIVITIONの内容
 
 データベース処理異常時の処理
 何らかのエラーが発生した場合、指定したラベルに制御を移すことが出来ます
 
 EXEC SQL
    WHENEVER SQLERROR GO TO :ラベル名
 END-EXEC

 データベース接続
 (ここでは、ODBC情報ファイル設定をデフォルトとします。)
 EXEC SQL
    CONNECT TO DEFAULT
 END-EXEC
 
 データベース切断
 EXEC SQL
    DISCONNECT TO DEFAULT
 END-EXEC
 
 データ抽出(カーソルなし)
 EXEC SQL
    SELECT CUSTOMCD   データベースのフィールド名です
     INTO :CUSTOM-CODE DATA DIVITIONで指定した変数に':'を付けます
     FROM TBL-CUSTOM
     WHERE CUSTOMCD   ='001' シングルクォーテーションです
     ORDER BY CUSTOMCD
 END-EXEC

 データ抽出(カーソルあり)
 SELECT句の後にカーソルのオープンFETCHでデータを読み込みます。

 MOVE "001"  TO CUSTOM-CODE ダブルクォーテーションです
 EXEC SQL
    DECLARE CUR1 CURSOR ON
    SELECT CUSTOMCD
     FROM TBL-CUSTOM
     WHERE CUSTOMCD   = :CUSTOM-CODE 変数名の前に":"を付けます
     ORDER BY CUSTOMCD
 END-EXEC

 EXEC SQL
    OPEN CUR1
 END-EXEC

 EXEC SQL
    FETCH CUR1
    INTO  :CUSTOM-CODE
 END-EXEC

 データ更新
 MOVE "002" TO CUSTOM-CODE
 EXEC SQL
    UPDATE TBL-CUSTOM 
      SET CUSTOMCD = :CUSTOM-CODE
     WHERE CUSTOMCD = '001'
 END-EXEC

 データ削除
 EXEC SQL
    DELETE TBL-CUSTOM
     WHERE CUSTOMCD = '001'
 END-EXEC

 コミット
 EXEC SQL
    COMMIT WORK
 END-EXEC

 ロールバック
 EXEC SQL
    ROLLBACK WORK
 END-EXEC