COBOL基本文法3

「PERFORM/EVALUATE」

(繰り返し・多分岐)


●データ定義について●

COBOLでのデータ定義にはレベル番号という概念があります。

01  WK-PUNIPUNI     PIC  X(10).

単独項目として定義する場合は、01 か 77 を使用します。

これらの場合はA領域から書き始めます。

集団項目の定義だと下のようになります。

01 WK-AREA.

   03 WK-PUNIPUNI   PIC  X(10).

   03 WK-DOKODON. 

     05 WK-DOKO    PIC  X(03).

     05 WK-DON     PIC  9(02).   

01 以下のレベル番号はそれより下位の番号であれば

特に付け方に決まりはありませんが、後の変更に対する

柔軟性を持たせるという意味で通常は2つおきに

レベル番号を割り当てます。ただし、77のような

単独項目専用のレベル番号を割り振ることはできません。

●データ再定義(REDEFINES)について●

REDEFINES句は、COBOL特有のとても便利、

あるいは、一種反則的な(笑)概念です。

普通、データ定義は最初に文字属性か数字属性かを

決めてしまいます。そしてそのデータ項目の属性が

途中で変わることは決してありません。

これを同じデータ項目でも場合によって、文字属性として

扱ったり、数字属性として扱ったり、いろんな見方をする

ことができるのが、REDEFINES です。

01 WK-AREA.

   03 WK-PUNIPUNI   PIC  X(10).

01 WK-AREA-R REDEFINES WK-AREA. 

   03 WK-PUYOPUYO  PIC  X(02).

   03 WK-PUKAPUKA  PIC  9(08).

これで、WK-PUNIPUNIという文字10桁の項目を

文字2桁 + 数字8桁の項目としても扱うことが

できるようになったわけです。ただし、再定義する

データ項目のレベル番号は同じでなくてはなりません。

また、桁数も同じになるように定義する必要があります。

●PERFORM●

IF文のところでちょろっと出てきましたが、

PERFORM文には2通りの使い方があります。

@同じプログラム内の他のSECTIONを呼ぶ。

Aループ(繰り返し)条件を記述する。

ここでは、繰り返し条件の記述について説明しましょう。

繰り返しをやめる条件を「回数」にしたい場合は、

PERFORM WITH TEST BEFORE VARYING 添字 FROM 1 BY 1

UNTIL 添字 > 繰り返しを実行する回数

繰り返し行いたい処理

END-PERFORM

のように記述します。繰り返しをやめる条件を後で判定したい場合は

PERFORM WITH TEST AFTER

にすることで、実現可能です。

繰り返しをやめる条件を「ある条件になったら」としたい場合は、

PERFORM WITH TEST BEFORE

UNTIL 条件式

繰り返し行いたい処理

END-PERFORM

と記述します。繰り返し処理を記述する上で注意しなくては

ならないのは、条件式がいつかは必ず満たされるか、

ということです。例えばUNTIL条件で「SW=”1”」と

きいているのに、繰り返し処理の中でSWに”1”を設定する

処理が記述されていなければ、いつまでたっても、条件を

満たすことがなく、永遠に繰り返し処理を行うことになって

しまいます。これを無限ループといい、暴走を止めるのが

一苦労(運が悪いと再立ち上げしなくてはならない)だという

バグの中でも最も悪質な部類に入ります。気をつけましょう。

●EVALUATE●

多分岐命令です。IF文でも代用できます。

(Cでいうswitch case文のことです)

EVALUATE データ名

WHEN  データ内容1

処理1

WHEN  データ内容2

処理2

WHEN OTHER

いずれの条件も満たさなかった場合の処理

END-EVALUATE

データ名の内容がWHEN句の条件と一致した場合に

その処理を行います。

WHEN OTHER句は省略しても構いません。

EVALUATE TRUE

WHEN 条件式1

処理1

と記述すると、WHEN句に記述した条件式が満たされた

ときにだけその処理を行います。

●その他●

OCCURS句はデータ項目の繰り返し(配列)を表します。

下のサンプルソースで

000500    03 KIBOU-BI   OCCURS 3   TIMES.
000501      05 HINICHI            PIC 9(08).

という記述がありますね。これは、HINICHIというデータ項目が

3つあるよ、ということを表しています。

使用するときには、HINICHI(1)(一つめのHINICHI)の

ようにデータ項目名の後ろに( )をつけて記述します。

●サンプルソース●

旅行参加者の連絡先や個人情報と希望日データの入った

入力ファイルIN01をCSV形式に編集して

出力ファイルOUT01に書き出すプログラムです。

000080******************************************************************
000081*
000082* COBOL 練習用プログラム
000083* PROGRAM-ID:PERFORM1(PERFORM/EVALUATE 練習)
000084* 作成日:2001-02-10
000085* 作成者:プー
000086* 機能概要:
000087* 複数行ある固定長データを読み込み、CSV形式にし、出力する。
000088*
000089******************************************************************
000091 IDENTIFICATION   DIVISION.
000100 PROGRAM-ID.     PERFORM1.
000110 AUTHOR.        PU.
000120 DATE-WRITTEN.    2001.02.10.
000130*
000140 ENVIRONMENT    DIVISION.
000150*
000160 INPUT-OUTPUT    SECTION.
000170 FILE-CONTROL.
000180     SELECT   IN01-F   ASSIGN  TO  IN01
000211             ORGANIZATION IS LINE SEQUENTIAL.
000213     SELECT   OUT01-F  ASSIGN  TO  OUT01
000220             ORGANIZATION IS LINE SEQUENTIAL.
000230*
000240 DATA   DIVISION.
000250 FILE    SECTION.
000260******************************************************************
000270* 入力ファイル
000280******************************************************************
000290 FD IN01-F.
000300 01 IN01-R.
000310    03 NAME               PIC N(10).
000311    03 NAME-YOMI           PIC X(10).
000312    03 CLUB               PIC N(10).
000313    03 TEL                PIC X(12).
000314    03 NENREI              PIC 9(02).
000500    03 KIBOU-BI   OCCURS 3   TIMES.
000501      05 HINICHI            PIC 9(08).
000502******************************************************************
000510* 出力ファイル
000520******************************************************************
000530 FD OUT01-F.
000540 01 OUT01-R                PIC X(95).
000550******************************************************************
000560* WORK定義
000570******************************************************************
000580 WORKING-STORAGE    SECTION.
000610*
000620 01 IN01-EOF                PIC X(01)   VALUE  SPACE.
000630 01 CT-W                   PIC 9(02) VALUE ZERO.
000910* 出力ファイル編集エリア
000920 01 WK-CSV.
000921    03 WK-NAME             PIC N(10).
000922    03 FILLER               PIC X(01)   VALUE ",".
000923    03 WK-NAME-YOMI         PIC X(10).
000924    03 FILLER               PIC X(01)   VALUE ",".
000925    03 WK-CLUB             PIC N(10).
000926    03 FILLER               PIC X(01)   VALUE ",".
000927    03 WK-TEL              PIC X(12).
000928    03 FILLER               PIC X(01)   VALUE ",".
000929    03 WK-NENREI            PIC 9(02).
000930    03 FILLER               PIC X(01)   VALUE ",".
000939    03 WK-HINICHI1           PIC 9(08).
001420    03 FILLER               PIC X(01)   VALUE ",".
001421    03 WK-HINICHI2           PIC 9(08).
001422    03 FILLER               PIC X(01)   VALUE ",".
001423    03 WK-HINICHI3           PIC 9(08).
001424******************************************************************
001430* メイン処理
001440******************************************************************
001450 PROCEDURE   DIVISION.
001460 MAIN   SECTION.
001461 MAIN-STA.
001470    PERFORM   INIT-SEC.
001480    PERFORM   SUB-MAIN
001490      UNTIL SI01-EOF  =  HIGH-VALUE
001500    PERFORM   END-SEC.
001510*
001520    MOVE   ZERO   TO   PROGRAM-STATUS.
001540    STOP   RUN.
001550 MAIN-END.
001560    EXIT.
001570******************************************************************
001580* 初期処理
001590******************************************************************
001600 INIT-SEC   SECTION.
001610 INIT-STA.
001680* 入出力ファイルオープン
001690    OPEN   INPUT    IN01-F.
001720    OPEN   OUTPUT   OUT01-F.
001730* 出力領域の初期化
001740    INITIALIZE   OUT01-R.
001741    INITIALIZE   WK-CSV.
001750* 入力ファイルの初期読込み(1件目)
001800    PERFORM   READ-SYORI.
001810*
001820 INIT-END.
001830    EXIT.
002210******************************************************************
002220* 入力ファイル読込み処理
002230******************************************************************
002240 READ-SYORI   SECTION.
002250 READ-STA.
002260    READ IN01-F
002270    AT END
002280      MOVE  HIGH-VALUE  TO  IN01-EOF
002300    NOT AT END
002310      CONTINUE
002320    END-READ.
002330 READ-END.
002340    EXIT.
002350******************************************************************
002360* 主処理
002370******************************************************************
002380 SUB-MAIN SECTION.
002390 SUB-MAIN-STA.
002400* 入力ファイルの項目を編集領域に設定
002410    MOVE  NAME       TO  WK-NAME
002411    MOVE  NAME-YOMI   TO  WK-NAME-YOMI
002412    MOVE  CLUB       TO  WK-CLUB
002413    MOVE  TEL        TO  WK-TEL
002414    MOVE  NENREI      TO  WK-NENREI
002431*
002432    PERFORM WITH TEST BEFORE VARYING CT-W FROM 1 BY 1
002433      UNTIL CT-W > 3
002434*
002435      EVALUATE CT-W
002436      WHEN 1
002437        MOVE   HINICHI(CT-W)  TO  WK-HINICHI1
002438      WHEN 2
002439        MOVE   HINICHI(CT-W)  TO  WK-HINICHI2
002440      WHEN 3
002441        MOVE   HINICHI(CT-W)  TO  WK-HINICHI3
002442      END-EVALUATE
002449*
002450    END-PERFORM.
002451* 出力ファイルへの書き出し
003010    WRITE   OUT01-R   FROM   WK-CSV.
003030* 出力領域の初期化
003041    INITIALIZE   OUT01-R.
003042    INITIALIZE   WK-CSV.
003050* 入力ファイルの読込み
003060    PERFORM   READ-SYORI.
003070*
003080 SUB-MAIN-END.
003090    EXIT.
003100******************************************************************
003110* 終了処理
003120******************************************************************
003130 END-SEC   SECTION.
003140 END-STA.
003141* 入出力ファイルのクローズ
003150   CLOSE   SI01-F.
003180   CLOSE   SO01-F.
003290*
003291 END-END.
003300   EXIT.

↓入力ファイルをコピー句(外部構造体)に置き換えた場合の例です。

000240 DATA   DIVISION.
000250 FILE    SECTION.
000260******************************************************************
000270* 入力ファイル
000280******************************************************************
000290 FD  IN01-F.
000291 COPY INPUT-FILE.
000502******************************************************************
000510* 出力ファイル
000520******************************************************************
000530 FD  OUT01-F.
000540 01  OUT01-R                     PIC X(95).

<コピー句 INPUT-FILE>

000010******************************************************************
000020* (COPY句) INPUT-FILE(入力データ)
000030******************************************************************
000040* 入力データ
000230 01 IN01-R.
000240    03 NAME                PIC N(10).
000250    03 NAME-YOMI            PIC X(10).
000260    03 CLUB                PIC N(10).
000270    03 TEL                 PIC X(12).
000280    03 NENREI               PIC 9(02).
000290    03 KIBOU-BI   OCCURS  3   TIMES.
000300      05 HINICHI             PIC 9(08).
000310*

プログラミング入門に戻る