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 によって
オブジェクトの存在を検査することができる。
【 TESTCHK: CHKOBJ を行うサンプル・ソース】
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
【 CHKOBJCL: オブジェクトの存在を検査するCLP 】
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