CLPの中で、そのままOPNQRYFを利用する例です。つまり、OPNQRYFを実行するCLPそのものが、オープンされたファイルを読み込むわけです。以下の例では、DSPFDのメンバーリストを、OPNQRYFで選択して、その選択結果を、RCVFで読み込んでいます。当然、RCVFの時点でファイルメンバーが存在しなければ、エラーです。逆に、RCVFの前にデータメンバーを準備しておけばいいことになります。
尚、CLPでは、最初のRCVFで、ファイルメンバーをオープンします。(OPNQRYFでは実質このコマンド時点と考えられますが、OPNQRYFが無い場合は、RCVFの時点です。)ファイルメンバー全般のルールで、ファイルメンバーオープンの前に、指定変更や、OPNQRYFをしなくてはいけません。
AS/400 CL(制御言語)解説書 バージョン3 1.6.145 RCVF(ファイル受取り)コマンド
DCLFコマンドに指定されたレコード様式中の1つだけを、RCVFコマンドのそれぞれに指定することができます。前のRCVF、SNDRCVF、またはSNDFコマンドによりオープンされていない場合は、そのファイルは、このコマンドによってオープンされます。前のRCVFコマンドでファイル終了条件が生じてファイルがすでにクローズされている場合は、エラーが生じます。このコマンドに指定したファイルは、そのファイルのオープンの前に一時変更コマンドを入力することによって指定を変更することができます。プログラムのコンパイル時にDCLFコマンドに指定されたファイルが表示装置ファイルである場合には、ファイルを他の表示装置ファイルにのみ一時変更することができます。ファイルがデータベース・ファイルである場合には、そのファイルは1つのレコード様式を備えた他のデータベース・ファイルにのみ一時変更することができます。ただし、指定された各CL変数に対応したものでなければならないことに注意してください。 |
PGM
DCLF QAFDMBRL
DSPFD Y2K/Y2KSRC *MBRLIST OUTPUT(*OUTFILE) OUTFILE(QTEMP/MBRL)
OVRDBF QAFDMBRL QTEMP/MBRL SHARE(*YES)
OPNQRYF MBRL +
QRYSLT('MLSEU2="CLP " & %SST(MLNAME 1 1) *NE "@"') KEYFLD(MLNAME)
\READ:
RCVF *N QWHFDML
MONMSG CPF0864 *N GOTO \EOF
CRTCLPGM PCDOBJ/&MLNAME &MLLIB/&MLFILE
GOTO \READ
\EOF:
CLOF MBRL
DLTOVR *ALL
RETURN
ENDPGM
これで、ソースタイプがCLPで、ソースメンバー名の頭が@をはずした、メンバーリストを読み込めます。(RPG、CLP、DSPFなどが、一個のソースファイルの場合、便利ですね。@が付くのは、私の場合、不要になったソースメンバーを意味しています。)
さて、では、CLPでいくつも、ファイルメンバーをオープンしましょう。うまくいくのでしょうか?
PGM
DCLF QAFDMBRL
DCL &SRCF *CHAR 10 'Y2K'
DCL &SRCL *CHAR 10 'TKY2K'
/*--------------------------------*/
/* MBR LIST */
/*--------------------------------*/
DSPFD &SRCL/&SRCF *MBRLIST OUTPUT(*OUTFILE) OUTFILE(QTEMP/MBRL)
/*--------------------------------*/
/* DSPF */
/*--------------------------------*/
OVRDBF QAFDMBRL QTEMP/MBRL SHARE(*YES)
OPNQRYF MBRL +
QRYSLT('MLSEU2="DSPF " & %SST(MLNAME 1 1) *NE "@"') KEYFLD(MLNAME)
\DSPF:
RCVF *N QWHFDML
MONMSG CPF0864 *N GOTO \DSPFEOF
...
GOTO \DSPF
\DSPFEOF:
CLOF MBRL
DLTOVR *ALL
/*--------------------------------*/
/* CLP */
/*--------------------------------*/
OVRDBF QAFDMBRL QTEMP/MBRL SHARE(*YES)
OPNQRYF MBRL +
QRYSLT('MLSEU2="CLP " & %SST(MLNAME 1 1) *NE "@"') KEYFLD(MLNAME)
\CLP:
RCVF *N QWHFDML
MONMSG CPF0864 *N GOTO \CLPEOF
...
GOTO \CLP
\CLPEOF:
CLOF MBRL
DLTOVR *ALL
/*--------------------------------*/
/* RPG */
/*--------------------------------*/
OVRDBF QAFDMBRL QTEMP/MBRL SHARE(*YES)
OPNQRYF MBRL +
QRYSLT('MLSEU2="RPG " & %SST(MLNAME 1 1) *NE "@"') KEYFLD(MLNAME)
\RPG:
RCVF *N QWHFDML
MONMSG CPF0864 *N GOTO \RPGEOF
...
GOTO \RPG
\RPGEOF:
CLOF MBRL
DLTOVR *ALL
\END:
RETURN
ENDPGM
実は、これは、動きません。最初の、ループ部分のみで、他の2つのループはすぐに抜けて(オープン直後に、EOFになって、)しまいます。これは、同じCLPでは、一回、EOFなると、ファイルカーソルは元に戻らない為です。(マニュアルで、「オープン出来ません」と出ていますが、「オープンは出来るけど、データの読み込みは出来ません」、の方が適切です。)OVRDBFでPOSITION(*START)や、POSDBFも使っても、効果はありません。
AS/400 アドバンスト・シリーズ CL(制御言語)プログラミング バージョン
3 5.2.2 CL プロシージャーでのファイルのオープンとクローズ
CL サポートを使用している場合、1 つのプロシージャーまたは OPM
プログラムで参照できるファイルは 1
つだけです。参照されたファイルは、最初の送信操作、受信操作、送信/受信操作を実行した時点で暗黙的にオープンされます。オープンされた表示装置ファイルは、それをオープンしたプロシージャーや
OPM
プログラムが制御権を戻すか、あるいは他のプロシージャーやプログラムに制御権を移すまで、オープンされた状態になっています。オープンされたデータベース・ファイルは、ファイルの終りに達するか、そのファイルをオープンしたプロシージャーやOPM
プログラムが制御権を戻すか、または他のプロシージャーやプログラムに制御権を移した時点でクローズされます。データベース・ファイルはいったんクローズされると、そのプロシージャーまたは
OPM
プログラムと同じ呼出し中に、再度オープンすることはできません。 |
そこで、このような場合は、2つのプログラムを準備します。最初のプログラムCRTALLPGMは、ファイルを準備して、CRTALLPGM2を呼び出します。このCRTALLPGM2の中では、OPNQRYFを実行して、処理をEOFまで行います。そして、RETRUNで、制御権をCRTALLPGMに戻します。これにより、再び。CRTALLPGM2は、再度OPNQRYFを実行して、適切な処理を行えます。
CRTALLPGM
PGM
DCL &SRCF *CHAR 10
DCL &SRCL *CHAR 10
CHGVAR &SRCF 'Y2K'
CHGVAR &SRCL 'TKY2K'
DSPFD &SRCL/&SRCF *MBRLIST OUTPUT(*OUTFILE) OUTFILE(QTEMP/MBRL)
CALL CRTALLPGM2 'DSPF '
CALL CRTALLPGM2 'CLP '
CALL CRTALLPGM2 'RPG '
CALL CRTALLPGM2 'RPGLE '
\END:
RETURN
ENDPGM
|
CRTALLPGM2
PGM (&SEU2)
DCLF QAFDMBRL
DCL &SEU2 *CHAR 10
OVRDBF QAFDMBRL QTEMP/MBRL SHARE(*YES)
OPNQRYF MBRL +
QRYSLT('MLSEU2="'|<&SEU2|<'" & %SST(MLNAME 1 1) *NE "@"') +
KEYFLD(MLNAME)
\READ:
RCVF *N QWHFDML
MONMSG CPF0864 *N GOTO \EOF
IF (&SEU2='DSPF ') CRTDSPF OBJLIB/&MLNAME &MLLIB/&MLFILE
ELSE IF (&SEU2='CLP ') CRTCLPGM OBJLIB/&MLNAME &MLLIB/&MLFILE
ELSE IF (&SEU2='RPG ') CRTRPGPGM OBJLIB/&MLNAME &MLLIB/&MLFILE
ELSE IF (&SEU2='RPGLE ') CRTBNDRPG OBJLIB/&MLNAME &MLLIB/&MLFILE
GOTO \READ
\EOF:
CLOF MBRL
DLTOVR *ALL
RETURN
ENDPGM
|
1998/10/24
|