これの続き。先日いよいよ配属が決まり、研修が終わればバリバリ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
にすれば改行区切りになるので、つけておいたほうがいいかもれない。
次回はテーブルの再定義。おそらく次が最終回になりそう。