CL

164. CLPで読むファイルを再読み込みするには?

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)

としてファイルをクローズしているので二度目の読み取りも可能になっている。
_