これの続き。いよいよ最終回。更新ペースが遅いからとても長く感じた。
最後はテーブルについて学習しようと思う。
テーブルについて
考え方は他言語で言う配列に近い。これまでの学習内容だと、同じデータが何件もあるとき、一個一個定義していかなければならなかった。
例えばテーブルを使わないで3個分のデータ項目を作成するとしたら、こうなる。
*---1---------2---------3---------4---------5-----
01 DATA.
03 DATA1 PIC X(10).
03 DATA2 PIC X(10).
03 DATA3 PIC X(10).
これが何個持ってなるとやってらんない。
そこでテーブルが出てくる。
構文・使い方
レベル番号(親) テーブル名.
レベル番号(子) 項目名 PIC 型(文字数) OCCURES 要素数.
テーブルを定義する際は、データ項目定義時に、OCCURES
句使用し、後ろに作成するテーブル数を指定する。
テーブルを使用すれば、最初の例は次のようになる。
*---1---------2---------3---------4---------5-----
01 TABLE.
03 DATA PIC X(10) OCCURES 3.
これなら大量件数でも対応できる。また、多次元配列のようにしたいときは次のようにすれば良い。
テーブルレイアウト(テーブル名:PROFILE-TBL
)
項目1 | 項目2 | 項目3 |
---|---|---|
DT-NO PIC 9(01) |
NICNAME PIC X(10) |
COMMENT X(20) |
データ番号 | ニックネーム | コメント |
※ 項目1〜項目3の1セットは
PROFILE
とする
*---1---------2---------3---------4---------5-----
01 PROFILE-TBL.
03 PROFILE OCCURS 3.
05 DT-NO PIC 9(01).
05 NICNAME PIC X(10).
05 COMMENT PIC X(20).
上記の構成イメージはこんな感じ。
データ項目にアクセスする
上の図を見ての通り、OCCURES
句を使用してテーブルを作成すると、同じ項目名が指定した数分できるため、今までのやり方ではアクセスできない。アクセスするには、アクセスしたい添字番号を指定する必要がある。指定するには、アクセスしたい項目名の後ろにカッコでアクセスしたい添字番号を記載する。
例えば、2番目のPROFILE
のNICNAME
を'ZAMA8722'
としたい場合は以下のようになる。
MOVE 'ZAMA8722' TO NICNAME(2).
COBOLは添字番号が__1から__なので、多言語で0からで慣れている場合は注意が必要。
1番上から総なめするときは
PERFORM VARYING
でできる。例えば、上で作成したテーブルの全項目にデータが入っていて、全て画面出力したいときは、次のようにしてあげる。
*---1---------2---------3---------4---------5-----
PERFORM
VARYING IDX FROM 1 BY 1
UNTIL IDX > 3
DISPLAY PROFILE(IDX)
END-PERFORM.
※IDX
は9(01)
型の添字
外部データをテーブルに入れる
読み込んだレコードをそのままMOVE
すればOK
*---1---------2---------3---------4---------5-----
IDENTIFICATION DIVISION.
PROGRAM-ID. SAMPLE.
*
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT IN-FILE ASSIGN 'infile.dat'
ORGANIZATION LINE SEQUENTIAL.
*
DATA DIVISION.
FILE SECTION.
FD IN-FILE LABEL RECORD STANDARD
BLOCK CONTAINS 0 RECORDS.
01 IN-REC PIC X(31).
*
WORKING-STORAGE SECTION.
01 PROFILE-TBL.
03 PROFILE OCCURS 3.
05 DT-NO PIC 9(01).
05 NICNAME PIC X(10).
05 COMMENT PIC X(20).
01 IDX PIC 9(01).
01 FLG PIC X(01).
*
PROCEDURE DIVISION.
PGM-FLOW SECTION.
*-- PGM-FLOW SEC
PGM-FLOW-S.
OPEN INPUT IN-FILE.
MOVE SPACE TO FLG.
MOVE ZERO TO IDX.
PERFORM PGM-READ.
PERFORM PGM-MAIN
UNTIL FLG = '1'.
CLOSE IN-FILE.
PGM-FLOW-E.
STOP RUN.
*-- PGM-READ SEC
PGM-READ SECTION.
PGM-READ-S.
READ IN-FILE
AT END
MOVE '1' TO FLG
NOT AT END
COMPUTE IDX = IDX + 1
END-READ.
PGM-READ-E.
EXIT.
*-- PGM-MAIN SEC
PGM-MAIN SECTION.
PGM-MAIN-S.
MOVE IN-REC TO PROFILE(IDX).
PERFORM PGM-READ.
PGM-MAIN-E.
EXIT.
1COBOLER001TABLE SAMPLE
2ALICE HELLO EVERYONE
3BOB-001 NICE TO MEET YOU
テーブルの再定義
再定義をすることで、あるデータ項目を別のレイアウトで参照できるようにすることができる。例えば、
*---1---------2---------3---------4---------5-----
01 MEMBER-LIST
03 FILLER PIC X(31) VALUE
'1COBOLER001TABLE SAMPLE '.
03 FILLER PIC X(31) VALUE
'2ALICE HELLO EVERYONE '.
03 FILLER PIC X(31) VALUE
'3BOB-001 NICE TO MEET YOU '.
のようなデータがあり、これを上でも使用したテーブルのレイアウトで使用したいときは、REDEFINES
句を使用して再定義する。
レベル番号(親) テーブル名 REDEFINES 再定義するデータ項目.
レベル番号(子) 項目名 PIC 型(文字数) OCCURES 要素数.
とりあえずサンプルプログラム。
*---1---------2---------3---------4---------5-----
IDENTIFICATION DIVISION.
PROGRAM-ID. SAMPLE.
*
ENVIRONMENT DIVISION.
*
DATA DIVISION.
WORKING-STORAGE SECTION.
01 MEMBER-LIST.
03 FILLER PIC X(31) VALUE
'1COBOLER001TABLE SAMPLE '.
03 FILLER PIC X(31) VALUE
'2ALICE HELLO EVERYONE '.
03 FILLER PIC X(31) VALUE
'3BOB-001 NICE TO MEET YOU '.
01 PROFILE-TBL REDEFINES MEMBER-LIST.
03 PROFILE OCCURS 3.
05 DT-NO PIC 9(01).
05 NICNAME PIC X(10).
05 COMMENT PIC X(20).
01 IDX PIC 9(01).
*
PROCEDURE DIVISION.
PGM-MAIN SECTION.
PGM-MAIN-S.
PERFORM
VARYING IDX FROM 1 BY 1
UNTIL IDX > 3
DISPLAY NICNAME(IDX)
END-PERFORM.
PGM-MAIN-E.
STOP RUN.
COBOLER001
ALICE
BOB-001
このように、固定長のレコードであれば、再定義してデータを別レイアウトで作成し直すことができる。今回の場合は以下のような感じ。
今回はテーブルの学習で再定義を記載したが、別に普通のデータ項目でも使える。また、再定義前のデータ項目の内容を変えれば、再定義後のデータも変更される。
これにて終了
とりあえずこれでさらっと研修の教本を流すことができた。研修時間外にこうやって復習することで、更に覚えることができたし、合間にググったりすることで、新たな知識も手に入れることができた。
これから配属されて、毎回教本を持ち運ぶわけには行かないので、通勤時間などを使って、もう一度自分が作った記事を見直して行きたいと思う。
謝辞
ここまで閲覧頂いた方と、指摘等コメントをしていただいた皆さん、ありがとうございました。