RPG プログラム内で CHKOBJ などでオブジェクトの存在をチェックすることが
できるのだろうか ?
これに関しては意外と難しいのか海外の記事でも決め手のテクニックはない。
CLP の中では
CHKOBJ OBJ(QTRFIL/SHTEST) OBJTYPE(*FILE) MONMSG CPF9800
または
MONMSG MSGID(CPF0000) EXEC(GOTO ERROR) : CHKOBJ OBJ(QTRFIL/SHTEST) OBJTYPE(*FILE)
のように使用する。
この CLP の MONMSG に相当する RPG の命令が MONITOR であり
MONITOR : ( CHKOBJ ... ) : ON-ERROR : ENDMON
のように使用する。
従って MONITOR を使えばエラーがあれば検知して ON-ERROR が
実行されるはずなので上記の ( CHKOBJ ... )の部分に
QCMDXC や system 関数を使って実行すればエラー・モニターされるはずだと
いうことになるのだが、そうは行かない。
このことについても IBM 解説書には記述がないので実行してみるしかない。
MONITOR
SYSTEM('CHKOBJ OBJ(QTRFIL/SHTEST) OBJTYPE(*FILE)')
'FOUND' DSPLY
LEAVESR
ON-ERROR
'NOT FOUND' DSPLY
ENDMON
と記述しても MONITOR がエラーを検知することはない。
これは QCMDEXC で実行しても同じであり検出はできない。
なぜかというと SNDPGMMSG で送信されるスタックは *PRV であり
ひとつ上の上位のスタックである。
つまりエラー・メッセージは system 関数や QCMDEXC に送られるので
もうひとつ上の RPGプログラムまでは伝わらないのである。
( SNDPGMMSG ではなく QMHSNDPM によってスタックを指定すれば可能だが )
そこで MONITOR 〜 ON-ERROR のあいだに直接プログラムを CALL して
その呼ばれたプログラムから *ESCAPE メッセージを SNDPGMMSG で
戻せば RPG はそのプログラムのひとつ上のスタックになるので
MONITOR はエラーを検知する。
なれば QSYS の CHKOBJ を処理している QSYS のプログラム: QLICKOBJ を
直接、実行すればよいのだが QSYS のプログラムを
コマンドを経由せずに直接、呼び出すと
「ドメイン・エラーが検出された」とのエラーとなって実行は許されない。
QLICKOBJ をユーザー・ライブラリーにコピーしてもよいのだが
(【注】 使用者がコピーして自分自身で使う場合は著作権法では許されている)
これくらいは自前で作った。
「CHKOBJを処理するCHKOBJCL」を参照して欲しい。
CHKOBJCL を使えば次のような RPG によって
オブジェクトの存在を検査することができる。
0001.00 H DATEDIT(*YMD/) COPYRIGHT('(C) OfficeQuattrb Co,.Ltd Japan 2017-')
0002.00 F********** RPG によるオブジェクト存在検査 ****************************
0003.00 F*
0004.00 F**********************************************************************
0005.00 D OBJOBJLIB DS
0006.00 D OBJ 1 10A
0007.00 D OBJLIB 11 20A
0008.00
0009.00 D AUT DS
0010.00 D KOSU 1 2B 0 INZ(1)
0011.00 D AUTR 3 102 DIM(10)
0012.00
0013.00 D CHKOBJ C CONST('QUATTRO/CHKOBJCL')
0014.00 C EXSR CHECK
0015.00 C SETON LR
0016.00 C******************************************************
0017.00 C CHECK BEGSR
0018.00 C******************************************************
0019.00 C MONITOR
0020.00 C MOVEL 'SHOHINZ ' OBJ
0021.00 C MOVEL 'QTRFIL ' OBJLIB
0022.00 C MOVEL '*NONE ' AUTR(1)
0023.00 C*----------------------------------------------------+
0024.00 C CALL CHKOBJ
0025.00 C PARM OBJOBJLIB
0026.00 C PARM '*FILE ' OBJTYPE 10
0027.00 C PARM '*NONE ' MBR 10
0028.00 C PARM AUT
0029.00 C*----------------------------------------------------+
0030.00 C 'FOUND ' DSPLY ANS 1
0031.00 C ON-ERROR *ALL
0032.00 C 'NOT FOUND' DSPLY ANS 1
0033.00 C ENDMON
0034.00 C ENDSR
0001.00 PGM PARM(&OBJOBJLIB &OBJTYPE &MBR &AUT)
0002.00 /*---------------------------------------------------------*/
0003.00 /* CHKOBJCL : オブジェクトの存在チエック */
0004.00 /*---------------------------------------------------------*/
0005.00 DCL VAR(&OBJOBJLIB) TYPE(*CHAR) LEN(20)
0006.00 DCL VAR(&OBJ) TYPE(*CHAR) LEN(10)
0007.00 DCL VAR(&OBJLIB) TYPE(*CHAR) LEN(10)
0008.00 DCL VAR(&OBJTYPE) TYPE(*CHAR) LEN(7)
0009.00 DCL VAR(&OBJTYPEC) TYPE(*CHAR) LEN(8)
0010.00 DCL VAR(&MBR) TYPE(*CHAR) LEN(10)
0011.00 DCL VAR(&AUT) TYPE(*CHAR) LEN(102)
0012.00 DCL VAR(&AUTS) TYPE(*CHAR) LEN(2)
0013.00 DCL VAR(&AUTC) TYPE(*CHAR) LEN(100)
0014.00 DCL VAR(&AUT10) TYPE(*CHAR) LEN(10)
0015.00 DCL VAR(&AUT100) TYPE(*CHAR) LEN(100)
0016.00 DCL VAR(&MSG) TYPE(*CHAR) LEN(132)
0017.00 DCL VAR(&MSGID) TYPE(*CHAR) LEN(7)
0018.00 DCL VAR(&MSGF) TYPE(*CHAR) LEN(10)
0019.00 DCL VAR(&MSGFLIB) TYPE(*CHAR) LEN(10)
0020.00 DCL VAR(&MSGDTA) TYPE(*CHAR) LEN(132)
0021.00 DCL VAR(&TYPE) TYPE(*CHAR) LEN(1)
0022.00 DCL VAR(&TOPGMQ) TYPE(*CHAR) LEN(10)
0023.00 DCL VAR(&MSGTYPE) TYPE(*CHAR) LEN(10) +
0024.00 VALUE('*ESCAPE ')
0025.00 DCL VAR(&APIERR) TYPE(*CHAR) LEN(116) +
0026.00 VALUE(X'000074') /* 2 進数 */
0027.00 DCL VAR(&NULL4) TYPE(*CHAR) LEN(4) +
0028.00 VALUE(X'00000000')
0029.00 DCL VAR(&N) TYPE(*DEC) LEN(4 0)
0030.00 DCL VAR(&POS) TYPE(*DEC) LEN(4 0) VALUE(3)
0031.00 DCL VAR(&POT) TYPE(*DEC) LEN(4 0) VALUE(1)
0032.00 MONMSG MSGID(CPF0000) EXEC(GOTO CMDLBL(ERROR))
0033.00
0034.00 /*( 環境の取得 )*/
0035.00 RTVJOBA TYPE(&TYPE)
0036.00 IF COND(&TYPE *EQ '0') THEN(DO) /* バッチ */
0037.00 CHGVAR VAR(&TOPGMQ) VALUE('*SYSOPR ')
0038.00 ENDDO /* バッチ */
0039.00 ELSE CMD(DO) /* 対話式 */
0040.00 CHGVAR VAR(&TOPGMQ) VALUE('*TOPGMQ ')
0041.00 ENDDO /* 対話式 */
0042.00
0043.00 /*( パラメータの取得 )*/
0044.00 CHGVAR VAR(&OBJ) VALUE(%SST(&OBJOBJLIB 01 10))
0045.00 CHGVAR VAR(&OBJLIB) VALUE(%SST(&OBJOBJLIB 11 10))
0046.00 IF COND(%SST(&OBJTYPE 1 1) *EQ '*') THEN(DO)
0047.00 CHGVAR VAR(&OBJTYPEC) VALUE(&OBJTYPE)
0048.00 ENDDO
0049.00 ELSE CMD(DO)
0050.00 CHGVAR VAR(&OBJTYPEC) VALUE('*' *TCAT &OBJTYPE)
0051.00 ENDDO
0052.00 CHGVAR VAR(&AUTS) VALUE(%SST(&AUT 1 2))
0053.00 IF COND(%BIN(&AUTS) *GT 0) THEN(DO)
0054.00 CHGVAR VAR(&N) VALUE(1)
0055.00 LOOP: CHGVAR VAR(&AUT10) VALUE(%SST(&AUT &POS 10))
0056.00 CHGVAR VAR(%SST(&AUT100 &POT 10)) VALUE(&AUT10)
0057.00 IF COND(&N < %BIN(&AUTS)) THEN(DO)
0058.00 CHGVAR VAR(&N) VALUE(&N + 1)
0059.00 CHGVAR VAR(&POS) VALUE(&POS + 10)
0060.00 CHGVAR VAR(&POT) VALUE(&POT + 10)
0061.00 GOTO LOOP
0062.00 ENDDO
0063.00 ENDDO
0064.00
0065.00 /*( CHKOBJ の検査 )*/
0066.00 CHKOBJ OBJ(&OBJLIB/&OBJ) OBJTYPE(&OBJTYPEC) +
0067.00 MBR(&MBR) AUT(&AUT100)
0068.00 RETURN
0069.00
0070.00 APIERR:
0071.00 CHGVAR VAR(&MSGID) VALUE(%SST(&APIERR 9 7))
0072.00 CHGVAR VAR(&MSGDTA) VALUE(%SST(&APIERR 17 100))
0073.00 CHGVAR VAR(&MSGF) VALUE('QCPFMSG ')
0074.00 CHGVAR VAR(&MSGFLIB) VALUE('QSYS ')
0075.00 GOTO SNDMSG
0076.00
0077.00 ERROR: RCVMSG MSGTYPE(*LAST) RMV(*NO) MSG(&MSG) +
0078.00 MSGDTA(&MSGDTA) MSGID(&MSGID) MSGF(&MSGF) +
0079.00 MSGFLIB(&MSGFLIB)
0080.00 SNDMSG: IF COND(&MSGID *EQ ' ') THEN(DO)
0081.00 SNDPGMMSG MSGID(CPF9897) MSGF(QCPFMSG) MSGDTA(&MSG) +
0082.00 TOMSGQ(&TOPGMQ) MSGTYPE(&MSGTYPE)
0083.00 ENDDO
0084.00 ELSE CMD(DO)
0085.00 SNDPGMMSG MSGID(&MSGID) MSGF(&MSGFLIB/&MSGF) +
0086.00 MSGDTA(&MSGDTA) TOMSGQ(&TOPGMQ) +
0087.00 MSGTYPE(&MSGTYPE)
0088.00 ENDDO
0089.00 ENDPGM