エラー・モニターとして伝統的に知られているのが INFSR(*PSSR) によるエラー監視である。
*PSSR という名前の特殊なサブルーチンをファイル仕様書に定義しておけば例外的なエラーが
発生したときには制御が *PSSR というサブルーチンに移る。
プラログム状況データ構造 ( SDS ) の値を調べればエラーの起こったCPFMSG のメッセージID と
メッセージ・データを取得することができるのでエラー・メッセージをユーザーで送出することができる。
*PSSR で例外エラーを処理することができるのは良く知られているが具体的なメッセージを取り出す処理は
RPG解説書にも紹介されていないのでここでは 0-除算 を明示的に行って MCH1211 エラーの
エラー・メッセージをどのように取り出すかを示すサンプルを紹介する。
----------------------------------------------------------------------------------------------------
0001.00 H DATEDIT(*YMD/) DFTNAME(TESTPSSR)
0002.00 F********** *PSSR によるエラー監視 ************************************
0003.00 FSHOHIN IF E K DISK
0004.00 F INFSR(*PSSR)
0005.00 F**********************************************************************
0006.00 D KINGAKU S 7S 0 INZ(8000)
0007.00 D SURYO S 4S 0 INZ(0)
0008.00 D TANKA S 7S 0
0009.00
0010.00 D CPFMSGLIB S 20A INZ('QCPFMSG *LIBL ')
0011.00 D PGMSTKCNT S 10I 0 INZ(1) 小数
0012.00 D EXCP_LEN S 10I 0 INZ(80) 小数
0013.00 D APIERR DS
0014.00 D GETBYT 1 4B 0 INZ(160)
0015.00 D AVLBYT 5 8B 0 INZ(0)
0016.00 D MSG_ID 9 15
0017.00 D MSG_DTA 17 160
0018.00
0019.00 D*( プログラム状況データ構造 )
0020.00 D INFDSP SDS
0021.00 D 512A
0022.00 D CPFID 7A OVERLAY(INFDSP:40)
0023.00 D PGMID 10A OVERLAY(INFDSP:334)
0024.00 D EXCP_ID 4A OVERLAY(INFDSP:171)
0025.00 D EXCP_DATA 80A OVERLAY(INFDSP:91)
0026.00
0027.00 C* 単価 = 金額 / 数量 を計算 ( 数量は 0 である )
0028.00 C EVAL TANKA = KINGAKU / SURYO
0029.00 C SETON LR
0030.00 C RETURN
0031.00 C READ SHOHIN
0032.00 C******************************************************
0033.00 C *PSSR BEGSR
0034.00 C******************************************************
0035.00 C CPFID IFNE *BLANKS CPFID<>*BLK
0036.00 C*----------------------------------------------------+
0037.00 C CALL 'QMHSNDPM'
0038.00 C PARM CPFID |
0039.00 C PARM CPFMSGLIB |
0040.00 C PARM EXCP_DATA |
0041.00 C PARM EXCP_LEN |
0042.00 C PARM '*COMP ' MSGTYPE 10 |
0043.00 C PARM '*PGMBDY ' PGMQUE 10 |
0044.00 C PARM PGMSTKCNT |
0045.00 C PARM MSGKEY 4 |
0046.00 C PARM APIERR
0047.00 C*----------------------------------------------------+
0048.00 C END
0049.00 C ENDSR '*CANCL'
----------------------------------------------------------------------------------------------------
最初にまず、
0003.00 FSHOHIN IF E K DISK 0004.00 F INFSR(*PSSR)
によって *PSSR があることを定義している。 *PSSR は不便なことに、どれかのファイル仕様書の
継続行に定義しなければならない。
ファイルの定義がないと *PSSR は定義することができないので、このサンプルはダミーとして
0003.00 FSHOHIN IF E K DISK
を定義しているが SHOHIN が読まれることは絶対に発生しない。
次に 0-除算 は
0027.00 C* 単価 = 金額 / 数量 を計算 ( 数量は 0 である ) 0028.00 C EVAL TANKA = KINGAKU / SURYO
の演算で発生するよう仕掛けられている。数量は
0007.00 D SURYO S 4S 0 INZ(0)
として 0 で定義されているからである。
この演算が実行されると MCH1211 のエラーが発生して、制御は *PSSR へジャンプして移される。
そこで SNDPGMSG を実体であるプログラム・メッセージ送信 API: QMHSNDPM によって
0036.00 C*----------------------------------------------------+ 0037.00 C CALL 'QMHSNDPM' 0038.00 C PARM CPFID | 0039.00 C PARM CPFMSGLIB | 0040.00 C PARM EXCP_DATA | 0041.00 C PARM EXCP_LEN | 0042.00 C PARM '*COMP ' MSGTYPE 10 | 0043.00 C PARM '*PGMBDY ' PGMQUE 10 | 0044.00 C PARM PGMSTKCNT | 0045.00 C PARM MSGKEY 4 | 0046.00 C PARM APIERR 0047.00 C*----------------------------------------------------+
として メッセージID : CPFID, メッセージ・データ : EXCP_DATA の組み合わせによって
エラー・メッセージが送出される。
API : QMHSNDPM のパラメータをどのように設定すればよいのか、最初は戸惑うはずであるので
あえてサンプルとしてここで紹介した。