RPG

164. RPG のエラー・モニター (2)

エラー・モニターとして伝統的に知られているのが INFSR(*PSSR) によるエラー監視である。
*PSSR という名前の特殊なサブルーチンをファイル仕様書に定義しておけば例外的なエラーが
発生したときには制御が *PSSR というサブルーチンに移る。
プラログム状況データ構造 ( SDS ) の値を調べればエラーの起こったCPFMSG のメッセージID と
メッセージ・データを取得することができるのでエラー・メッセージをユーザーで送出することができる。
*PSSR で例外エラーを処理することができるのは良く知られているが具体的なメッセージを取り出す処理は
RPG解説書にも紹介されていないのでここでは 0-除算 を明示的に行って MCH1211 エラーの
エラー・メッセージをどのように取り出すかを示すサンプルを紹介する。

【 RPG : TESTPSSR 】
----------------------------------------------------------------------------------------------------
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 のパラメータをどのように設定すればよいのか、最初は戸惑うはずであるので
あえてサンプルとしてここで紹介した。