CLPのDCLF宣言でファイルを読み込んで処理するとき
同じプログラム内でもう一度再読み込みしたいときは
どのようにすれば良いのか?
_
そのままでは一度はすべてのレコードを読み取った後で
もう一度読み込んでもファイルの読み取り終了(EOF)と
なるばかりであるが
ファイルを読み取り終了後に CLOSE で明示的に
クローズしておけばよい。
ただしCLP内でDCLFで定義されたファイルを
明示的にオープンする命令はないので
オープンすることはできないが次のRCVFの実行によって
強制的に再オープンされてレコードが最初から
読み取られることになる。
[例] CLPで2回読み取りするTESTFFD
ソースはこちらから
0001.00 PGM 0002.00 /*-------------------------------------------------------------------*/ 0003.00 /* TESTFFD : DSPFFD のテスト */ 0004.00 /* */ 0005.00 /* 2018/02/01 作成 */ 0006.00 /*-------------------------------------------------------------------*/ 0007.00 DCLF FILE(QTEMP/DSPFFD) OPNID(DSPFFD) 0008.00 DCL VAR(&MSG) TYPE(*CHAR) LEN(132) 0009.00 DCL VAR(&STMMSG) TYPE(*CHAR) LEN(132) 0010.00 DCL VAR(&MSGID) TYPE(*CHAR) LEN(7) 0011.00 DCL VAR(&MSGF) TYPE(*CHAR) LEN(10) 0012.00 DCL VAR(&MSGFLIB) TYPE(*CHAR) LEN(10) 0013.00 DCL VAR(&MSGKEY) TYPE(*CHAR) LEN(4) 0014.00 DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(132) 0015.00 DCL VAR(&ERRDTA) TYPE(*CHAR) LEN(132) 0016.00 DCL VAR(&TYPE) TYPE(*CHAR) LEN(1) 0017.00 DCL VAR(&TOPGMQ) TYPE(*CHAR) LEN(10) 0018.00 DCL VAR(&MSGTYPE) TYPE(*CHAR) LEN(10) + 0019.00 VALUE('*ESCAPE ') 0020.00 DCL VAR(&APIERR) TYPE(*CHAR) LEN(116) + 0021.00 VALUE(X'0000007400000000') /* 2 進数 */ 0022.00 DCL VAR(&ERR) TYPE(*CHAR) LEN(1) 0023.00 DCL VAR(&NULL4) TYPE(*CHAR) LEN(4) + 0024.00 VALUE(X'00000000') 0025.00 MONMSG MSGID(CPF9999) EXEC(GOTO CMDLBL(ERROR)) 0026.00 0027.00 /*( 環境の取得 )*/ 0028.00 RTVJOBA TYPE(&TYPE) 0029.00 IF COND(&TYPE *EQ '0') THEN(DO) /* バッチ */ 0030.00 CHGVAR VAR(&TOPGMQ) VALUE('*SYSOPR ') 0031.00 ENDDO /* バッチ */ 0032.00 ELSE CMD(DO) /* 対話式 */ 0033.00 CHGVAR VAR(&TOPGMQ) VALUE('*TOPGMQ ') 0034.00 ENDDO /* 対話式 */ 0035.00 0036.00 /*---------------------------*/ 0037.00 CALLSUBR SUBR(GETFLDINFO) 0038.00 /*---------------------------*/ 0039.00 /*---------------------------*/ 0040.00 CALLSUBR SUBR(GETFLDINFO) 0041.00 /*---------------------------*/ 0042.00 IF COND(%SST(&APIERR 5 4) *NE &NULL4) THEN(DO) 0043.00 SNDPGMMSG MSG('API: + 0044.00 QUIDSPH の実行で次のエラーが発生しました。 + 0045.00 ') TOMSGQ(&TOPGMQ) MSGTYPE(*DIAG) 0046.00 GOTO APIERR 0047.00 ENDDO 0048.00 RETURN 0049.00 0050.00 APIERR: 0051.00 CHGVAR VAR(&MSGID) VALUE(%SST(&APIERR 9 7)) 0052.00 CHGVAR VAR(&MSGDTA) VALUE(%SST(&APIERR 17 100)) 0053.00 CHGVAR VAR(&MSGF) VALUE('Q' *CAT %SST(&MSGID 1 + 0054.00 3) *CAT 'MSG') 0055.00 IF COND(&MSGF *EQ 'QCPEMSG') THEN(CHGVAR + 0056.00 VAR(&MSGF) VALUE('QCPFMSG')) 0057.00 CHGVAR VAR(&MSGFLIB) VALUE('QSYS ') 0058.00 GOTO SNDMSG 0059.00 0060.00 ERROR: RCVMSG MSGTYPE(*FIRST) RMV(*NO) KEYVAR(&MSGKEY) + 0061.00 MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) + 0062.00 SNDMSGFLIB(&MSGFLIB) 0063.00 IF COND(&MSGID *EQ 'CPF9999') THEN(DO) 0064.00 CHGVAR VAR(&ERRDTA) VALUE(&MSGDTA) 0065.00 RCVMSG MSGTYPE(*PRV) MSGKEY(&MSGKEY) RMV(*NO) + 0066.00 MSG(&MSG) MSGDTA(&MSGDTA) MSGID(&MSGID) + 0067.00 MSGF(&MSGF) MSGFLIB(&MSGFLIB) 0068.00 CHGVAR VAR(&STMMSG) VALUE(' プログラム ' *CAT + 0069.00 %SST(&ERRDTA 8 10) *TCAT + 0070.00 ' のステートメント ' *CAT %SST(&ERRDTA + 0071.00 24 8) *CAT ' で次のエラーが発生しました。 ') 0072.00 SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&STMMSG) + 0073.00 TOMSGQ(&TOPGMQ) MSGTYPE(*DIAG) 0074.00 ENDDO 0075.00 SNDMSG: IF COND(&MSGID *EQ ' ') THEN(DO) 0076.00 SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&MSG) + 0077.00 TOMSGQ(&TOPGMQ) MSGTYPE(&MSGTYPE) 0078.00 MONMSG MSGID(CPF2400) EXEC(RETURN) 0079.00 ENDDO 0080.00 ELSE CMD(DO) 0081.00 SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) + 0082.00 MSGDTA(&MSGDTA) TOMSGQ(&TOPGMQ) + 0083.00 MSGTYPE(&MSGTYPE) 0084.00 MONMSG MSGID(CPF2400) EXEC(RETURN) 0085.00 ENDDO 0086.00 /******************************/ 0087.00 SUBR SUBR(GETFLDINFO) 0088.00 /******************************/ 0089.00 NXTFFD: RCVF OPNID(DSPFFD) 0090.00 MONMSG MSGID(CPF0864) EXEC(DO) 0091.00 RCVMSG PGMQ(*SAME) MSGTYPE(*LAST) RMV(*YES) MSG(&MSG) 0092.00 GOTO ENDFFD 0093.00 ENDDO 0094.00 GOTO NXTFFD 0095.00 ENDFFD: CLOSE OPNID(DSPFFD) 0096.00 ENDSUBR 0097.00 ENDPGM
[解説]
0036.00 /*---------------------------*/ 0037.00 CALLSUBR SUBR(GETFLDINFO) 0038.00 /*---------------------------*/ 0039.00 /*---------------------------*/ 0040.00 CALLSUBR SUBR(GETFLDINFO) 0041.00 /*---------------------------*/
とふたつのサブ・ルーチンを連続して実行しているが
このサブ・ルーチンの中では
0089.00 NXTFFD: RCVF OPNID(DSPFFD) 0090.00 MONMSG MSGID(CPF0864) EXEC(DO) 0091.00 RCVMSG PGMQ(*SAME) MSGTYPE(*LAST) RMV(*YES) MSG(&MSG) 0092.00 GOTO ENDFFD 0093.00 ENDDO 0094.00 GOTO NXTFFD 0095.00 ENDFFD: CLOSE OPNID(DSPFFD) 0096.00 ENDSUBR
と EOFになるまで QTEMP/DSPFFD を連続して読み取っているが
EOFになった後では
0095.00 ENDFFD: CLOSE OPNID(DSPFFD)
としてファイルをクローズしているので二度目の読み取りも可能になっている。
_