RPG

429. 実行時のエラーの原因を調べるには

(C G D F) 長さまたは開始桁はストリング操作の範囲外にある。

のような実行時においてエラーが発生したときの対処法について
解説する。

経験あるプログラマーではこのようなエラーを調べるのは
やさしいことであるがまだ経験の浅い方のために
実行時のエラーを調査する方法を紹介する。

まず上記のようなエラーが発生したらすぐにキャンセルなど
してはならない。
プログラムのどこでエラーになっているのかがわからなく
なってしまうからである。

(1) エラーの場所を特定する。

エミュレータのSyste-Requestを実行してシステム要求の
「3. 現行ジョブの表示」を選択する。

(2)呼び出しスタックを調べる。

下記のように活動ジョブ(WRKACTJOB)の表示が表示されるので
「11. 呼び出しスタックの表示 」を選択する

                                 ジョブの表示                                   
                                                          システム :   Sxxxxxxx
 ジョブ :   QPADEV0022     ユーザー :   QTR            番号 :   912836          
                                                                                
 次の 1 つを選択してください。                                                  
                                                                                
      1. ジョブ状況属性の表示                                                   
      2. ジョブ定義属性表示                                                     
      3. ジョブ実行属性の表示(活動状態の場合)                                 
      4. スプール・ファイルの表示                                               
                                                                                
     10. ジョブ・ログ表示(活動状態,ジョブ待ち行列上,または保留中の場合)     
     11. 呼び出しスタックの表示(活動状態の場合)                               
     12. ロックの表示(活動状態の場合)                                         
     13. ライブラリー・リストの表示(活動状態の場合)                           
     14. オープンされたファイルの表示(活動状態の場合)                         
     15. ファイル一時変更の表示(活動状態の場合)                               
     16. コミットメント制御状況の表示(活動状態の場合)                         
                                                                       続く ... 
 選択項目                                                                       
                                                                                
                                                                                
 F3= 終了   F12= 取り消し                                                       

(3)RPGプログラムの呼び出しスタックを確認する。

下記の例であれば RPG : RTVPNL のステートメント: 128900 で
  エラーが発生していることがわかる。

                            呼び出しスタックの表示                             
                                                          システム :   Sxxxxxxx
 ジョブ :   QPADEV0022     ユーザー :   QTR            番号 :   912836         
 スレッド:   00000026                                                             
                                                                               
                                                                               
 タイプ   プログラム              ステートメント            プロシージャー              
       QCMD       QSYS                     /0517                               
       QUICMENU   QSYS                     /00C1                               
    1  QUIMNDRV   QSYS                     /060F                               
    2  QUIMGFLW   QSYS                     /04D7                               
    3  QUICMD     QSYS                     /056E                               
    4  QCMD       QSYS                     /01C8                               
       RTVPNLSRCC QUATTRO       17300      /0164                               
       RTVPNL     QUATTRO                         _QRNP_PEP_RTVPNL             
       RTVPNL     QUATTRO       128900            RTVPNL                       
       QRNXIE     QSYS          11                _QRNX_G_FC_H                 
       QRNXIE     QSYS          2                 _QRNX_DFT_ERROR              
       QRNXIE     QSYS          17                _QRNX_INQ                    
       QRNXIE     QSYS          16                IトヌMヘキ                       

(4) エラー・ルッセージにD(=DUMP)で応答する。

 (C G D F) 長さまたは開始桁はストリング操作の範囲外にある 
                                                      
                                                          
  応答を入力して,実行キーを押してください。              
    応答 . . .   D                                        

(5)RPG : のエラーのあったソース・ステートメンと行を確認する。

         /FREE
          :
1289.00     %SUBST(WORD_DS.STRING:1:LEN2) = %SUBST(WUIK:POS:LEN2);
          :
         /END-FREE

(6) フィールド値に異常がないかとどうかを調べる。
この場合では異常値の可能性があるフィールドは LEN2またはPOSであるので
WRKOUTQ QEZDEBUG でこれらのフィールド値を調べる

                                                    スプール・ファイルの表示               
 ファイル . . . :   QPPGMDMP                                                               
 制御 . . . . . .                                                                          
 検索 . . . . . .                                                                          
 *...+....1....+....2....+....3....+....4....+....5....+....6....+....7....+....8....+....9
                                                                                           
  ILE RPG 定様式ダンプ                                                                     
   プログラム状況域 :                                                                      
   プロシージャー名  . . . . . . . . . . :   RTVPNL                                        
   プログラム名  . . . . . . . . . . . . :   RTVPNL                                        
      ライブラリー . . . . . . . . . . . :   QUATTRO                                       
   モジュール名  . . . . . . . . . . . . :   RTVPNL                                        
   プログラム状況  . . . . . . . . . . . :   00100                                         
               (C G D F) 長さまたは開始桁はストリング操作の範囲外にある。                  
   直前の状況  . . . . . . . . . . . . . :   00000                                         
   エラーのステートメント  . . . . . . . :   00128900                                      
    :
    :
 LEN2C                 DS                                            
   LEN2                UNS(5)               388              '0184'X 

 POS                   INT(10)              1384             '00000568'X 

  WORD_DS               DS                                               
   LEN                 BIN(4,0)             0388.            '0184'X    
   M                   PACKED(5,0)          00000.           '00000F'X  
   OFFSET              CHAR(2)              ' キ'             '0567'X    
   STRING              CHAR(256)            '                           

これによって

%SUBST(WORD_DS.STRING:1:LEN2) が WORD_DS.STRING 256桁を LEN2 = 388 がオーバーしていることが
わかった。
これがエラーの原因である。