これの続き。先日いよいよ配属が決まり、研修が終わればバリバリCOBOLを使うことになりそうだ…。
話を戻して、今回は外部ファイルを取り扱ってみようと思う。さぁ、頑張ろう。
外部ファイルを定義する
外部ファイルを開く前に、環境部とデータ部に追記が必要。
環境部
- 新たに入出力節
INPUT-OUTPUT SECTION.を追加する - 入出力節の中に、ファイル管理記述
FILE-CONTROL.を追加する - 構文で使用するファイル名と実際のファイルを対応付ける
SELECT <ファイル名> ASSIGN <実際のファイル>
ORGANIZATION IS LINE SEQUENTIAL.
-
<ファイル名>は任意の名前(変数みたいなもの) - 実際のファイルはそのファイルをディレクトリを書く
-
ORGANIZATION IS LINE SEQUENTIALをつけることで改行区切りになる。これをつけないと環境によっては改行区切りができない。
ここまでまとめるとこうなる。
*---1---------2---------3---------4---------5-----
IDENTIFICATION DIVISION.
PROGRAM-ID. SAMPLE.
*
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT IN-FL ASSIGN "infile.dat"
ORGANIZATION IS LINE SEQUENTIAL.
SELECT OUT-FL ASSIGN "outfile.dat".
今回infile.datの中身は以下のようにする。
HELLOWORLD
SAMPLE PGM
outfile.datは空データである。
データ部
- 新たにファイル節
FILE SECTION.を追加する - ファイル節の中にファイルを定義する
- 2.の直下にファイルのレコード情報を記述する
- 記述方法はデータ項目定義と同じ
- [
WORKING-STORAGE SECTION.にデータの受取先を作る。PICTURE句で指定するサイズの合計は3.で指定したものと同じになるようにする]- これは任意で、作らなかった場合でも3.で定義したデータ項目から参照できる
-
WORKING-STORAGE SECTION.には、PICTURE句X(01)のフラグ用データ項目も作っておく(理由は後述)
FD <ファイル名> [LABEL RECORD STANDARD
BLOCK CONTAINS n RECORDS].
-
[]内は任意(詳細は後述) - 記載なしの場合は
LABEL RECORD STANDARDとみなす -
<ファイル名>は環境部で書いた任意のファイル名
ここまでをまとめるとこんな感じ。
*---1---------2---------3---------4---------5-----
IDENTIFICATION DIVISION.
PROGRAM-ID. SAMPLE.
*
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT IN-FL ASSIGN "infile.dat"
ORGANIZATION IS LINE SEQUENTIAL.
SELECT OUT-FL ASSIGN "outfile.dat".
*
DATA DIVISION.
FILE SECTION.
FD IN-FL LABEL RECORDS STANDARD
BLOCK CONTAINS 0 RECORDS.
01 IN-REC PIC X(10).
FD OUT-FL LABEL RECORD OMITTED.
01 OUT-REC PIC X(10).
WORKING-STORAGE SECTION.
01 IN-DATA.
03 IN-STR PIC X(10).
01 OUT-DATA.
03 OUT-STR PIC X(10).
後述としていた任意箇所について
LABEL RECORD STANDARD
ファイルのラベルの有無を示す。ラベルがあるならSTANDARD、ないならOMITTED。読み込みのデータはSTANDARD、帳票出力はOMITTED使ってねと言われた。
BLOCK CONTAINS n RECORDS
物理レコードのサイズを指定する。nには数値が入る。0にしておけばユーザーに代わってシステムが決定する。
外部ファイルを開く
外部ファイルを開くには、OPEN命令を用いる。
OPEN <INPUT/OUTPUT> <ファイル名>.
読み込みファイルのときにはINPUT、書き込みファイルのときはOUTPUTとする。また、<ファイル名>は環境部で書いた任意のファイル名とする。
外部ファイルを読み書きする
外部ファイルを読み込む
ファイルを読み込む際はREAD命令を用いる。この命令を使用する際には、外部ファイルを開くときにINPUTとしなければいけない。
READ <ファイル名> [INTO <データ名>].
AT END
<EOF時の処理>
NOT AT END
<EOFでないときの処理>
END-READ.
[]内の箇所はデータ部の4.を定義した際に使用する。
ファイルが終了したことは、AT END以外では分からない。なので、先程定義するようにと記載したフラグを使用して、全体でファイルが終了したことを分かるようにする。
外部ファイルに書き込む
ファイルに書き込む際はWRITE命令を用いる。この命令を使用する際には、外部ファイルを開くときにOUTPUTとしなければいけない。
WRITE <レコード名> [FROM <データ名> [AFTER XXXX]].
FROM <データ名>は、ただ単にMOVE <データ名> TO <レコード名>をしているだけなので、別の箇所でうまくやりくりしているのならいらない。
任意の[AFTER XXXX]について
帳票出力とかする際に、改行数を決定する。XXXXは2つ書き方がある。
| 書き方 | 意味 |
|---|---|
1のような数値 |
改行する回数 |
PAGE |
改ページ |
例えば...AFTER PAGE 2.とすると、1行おきにデータが出力される。
ファイルを閉じる
開いたら最後はもちろん閉じる。
CLOSE <ファイル名>.
<ファイル名>は環境部で書いた任意のファイル名とする。
サンプルプログラム
間が空いてしまったが、ここまでをまとめる。ここではinfile.datの中身をoutfile.datに書く。ここではoutfile.datは帳票であると想定する。
*---1---------2---------3---------4---------5-----
IDENTIFICATION DIVISION.
PROGRAM-ID. SAMPLE.
*
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
SELECT IN-FL ASSIGN TO 'infile.dat'
ORGANIZATION IS LINE SEQUENTIAL.
SELECT OUT-FL ASSIGN TO 'outfile.dat'.
*
DATA DIVISION.
FILE SECTION.
FD IN-FL LABEL RECORD STANDARD
BLOCK CONTAINS 0 RECORDS.
01 IN-REC PIC X(10).
FD OUT-FL LABEL RECORD OMITTED.
01 OUT-REC PIC X(10).
WORKING-STORAGE SECTION.
01 IN-DATA.
03 IN-STR PIC X(10).
01 FLG-EOF PIC X(01).
*
PROCEDURE DIVISION.
*-- プログラムノフロー
PGM-FLOW SECTION.
PGM-FLOW-S.
PERFORM PGM-OPEN.
PERFORM PGM-RW
UNTIL FLG-EOF = '1'.
PERFORM PGM-CLOSE.
PGM-FLOW-E.
STOP RUN.
*-- ファイルOPEN AND ショカイファイルREAD
PGM-OPEN SECTION.
PGM-OPEN-S.
OPEN INPUT IN-FL
OUTPUT OUT-FL.
MOVE SPACE TO FLG-EOF.
PERFORM PGM-READ.
PGM-OPEN-E.
EXIT.
*-- ファイルREAD
PGM-READ SECTION.
PGM-READ-S.
READ IN-FL INTO IN-DATA
AT END
MOVE '1' TO FLG-EOF
END-READ.
PGM-READ-E.
EXIT.
*-- ファイルWRITE AND ツギノファイルREAD
PGM-RW SECTION.
PGM-RW-S.
WRITE OUT-REC FROM IN-DATA AFTER 1.
PERFORM PGM-READ.
PGM-RW-E.
EXIT.
*-- ファイルCLOSE
PGM-CLOSE SECTION.
PGM-CLOSE-S.
CLOSE IN-FL
OUT-FL.
PGM-CLOSE-E.
EXIT.
HELLOWORLD
SAMPLE PGM
最初の1行が空いているが、AFTER 1としているからでなので問題ない。不要ならば行数をカウントしておいて、最初の行だけ改行しないようIFで管理してあげればよい。
今回はここまで
ちょっと急ぎ足でまとめたので後日見直して、間違いを見つけたら修正しよう。
研修ではORGANIZATION LINE SEQUENTIALをつけずにうまく行っていたので、いざ家でやったときにうまく行かなかったときは結構悩んだ。逆に言うといい勉強にはなった。
うまくいこうがいかまいが、ORGANIZATION LINE SEQUENTIALにすれば改行区切りになるので、つけておいたほうがいいかもれない。
次回はテーブルの再定義。おそらく次が最終回になりそう。