最初のページに戻ります。

総合の目次があるページに戻ります。

よく使うマニュアルです

Wiki

updated on 2004.06.23

7.19.*PSSRは不便?

[ Previous ] [ HOME ] [ Upper ] [ Next ]


*PSSRは、RPG38からあるのですが、利用するチャンスは余りないかもしれません。ツールなどを作っていると、使うことがあります。最近iSUCに参加したら、*PSSRを知らない人がいました。「エラーが起きると*PSSRにうつって、そこから終わりにすることも出来るし、続けることも出来ます」と説明すると、「じゃあ、0除算エラーにIFNEは要らなかったんだ」といいます。変な事言うナー、と思っていたのですが、後で、彼が勘違いをしていることに、気づきました。

*PSSRは、例外エラーが起きた場合、定義してある場合、*PSSRに制御権が移ります。有る程度そこで、エラーハンドリングが出来ますが、以下のことに注意して下さい。

     H DEBUG DATEDIT(*YMD/)
     C**************************************************************************
     C*             M A I N -  R O U T I N E                
     C**************************************************************************
     C                   Z-ADD     0             S                 2 0
     C*
     C                   EVAL      S=100
     C                   EVAL      S=10
     C                   EVAL      S=1.005
     C*
     C                   MOVE      *ON           *INLR
     C                   RETURN
     C*-------------------------------------------------------------------------
     C     *PSSR         BEGSR
     C*-------------------------------------------------------------------------
     C*
     C                   ENDSR     '*DETL'
                    

このプログラムは永久ループします。理由は、*PSSRの戻り点は、自由に決めることは出来無いからです。上のソースでは、EVAL S=100でエラーが起きます(00103)。そこで、*PSSRに進みますが、なにもしていません。そして戻り点、*DETLは、早い話、C仕様書の最初です。すると、再び、Z-ADD 0 S に戻ります。そして、エラーをおこし、を繰り返します。*PSSRを指定しただけだと、このようになるのです。

マニュアルを見てみましょう。


ENDSR 命令はファイル例外/エラー・サブルーチン中の最後の指定でなければならず、次のように指定することが必要です。

位置 記入項目
6 C
7〜11 ブランク
12〜25 サブルーチン内の GOTO 指定で使用するラベルを入れることができます。
26〜35 ENDSR
36〜49 任意指定の記入項目で、サブルーチンの処理後に制御が戻される地点を指定します。この記入項目は6桁の文字フィールド、リテラル、または配列要素でなければならず、その値によって以下の戻り点の1つが指定されます。

注: 戻り点をリテラルとして指定する場合には、アポストロフィで囲む必要があります。名前付き固定情報として指定する場合には、その固定情報は文字でなければならず、先行ブランクのない戻り点だけが含まれていることが必要です。フィールドまたは配列要素の中に指定する場合には、フィールドまたは配列要素の中で値を左寄せしなければなりません。

*DETL 明細行の先頭に続きます。
*GETIN 入力レコードの入手ルーチンに続きます。
*TOTC 合計演算の先頭に続きます。
*TOTL 合計行の先頭に続きます。
*OFL オーバーフロー行の先頭に続きます。
*DETC 明細演算の先頭に続きます。
*CANCL プログラムの処理を取り消します。(註「プログラムメッセージを出します。」)
ブランク RPG IV の省略時のエラー処理プログラムへ制御を戻します。演算項目2がブランクの値および演算項目2が指定されていない場合でも、これが適用されます。サブルーチンがEXSR 命令によって呼び出され、演算項目2がブランクであった場合には、次の順次命令に制御が戻されます。ブランクは実行時にのみ有効です。
50〜76 ブランク

さて、このループを止めるのは簡単です。W1ERRがそれを制御します。2度目に*PSSRが出たら、*CANCL(プログラムメッセージを出す)にしています。あるいは、H1等をオンにして、プログラム終了も良く行う方法です。あとでデバッグに役立つように、DUMP(デバッグオプションをH仕様書に指定)するのも役立つでしょう。

     H DEBUG DATEDIT(*YMD/)
     D                SDS
     D  ##STSC                11     15
     C**************************************************************************
     C*             M A I N -  R O U T I N E                
     C**************************************************************************
     C                   Z-ADD     0             S                 2 0
     C*
     C                   EVAL      S=100
     C                   EVAL      S=10
     C                   EVAL      S=1.005
     C*
     C                   MOVE      *ON           *INLR
     C                   RETURN
     C*-------------------------------------------------------------------------
     C     *PSSR         BEGSR
     C*-------------------------------------------------------------------------
     C     W1ERR         IFEQ      *ON
     C                   MOVE      *OFF          W1ERR             1
     C                   MOVE      '*CANCL'      RTNPNT
     C                   ELSE
B001 C     ##STSC        IFEQ      '00103'
 001 C                   MOVE      '*DETL '      RTNPNT            6
     C                   MOVE      *ON           W1ERR
+001 C                   ELSE
 001 C                   MOVE      '*CANCL'      RTNPNT
E001 C                   END
E001 C                   END
     C*
     C                   ENDSR     RTNPNT
                    

しかし、ここで、RTNPNTをなにに変えても、EVAL S=10に進むことは出来ません。つまり、次の行へ、RESUMEする事は無いのです。どのようにしたら、S=100のエラーを無視して、次の行に進めるのでしょうか?S=100をエラーにならないようにする(桁を増やす)、か、その行を、Z-ADDに変更する、しか手は無いのでしょうか?ふーむ。ロチェスタの人は、出来ると言い張っていたのですが...。


マニュアルの記載によれば、「サブルーチンがEXSR 命令によって呼び出され、演算項目2がブランクであった場合には、次の順次命令に制御が戻されます。」とあります。これを利用したらどうでしょうか?

     H DEBUG DATEDIT(*YMD/)
     C**************************************************************************
     C*             M A I N -  R O U T I N E                
     C**************************************************************************
     C                   Z-ADD     0             S                 2 0
     C*
     C                   EVAL      S=100
     C                   EXSR      *PSSR
     C*
     C                   EVAL      S=10
     C                   EVAL      S=1.005
     C*
     C                   MOVE      *ON           *INLR
     C                   RETURN
     C*-------------------------------------------------------------------------
     C     *PSSR         BEGSR
     C*-------------------------------------------------------------------------
     C*
     C                   ENDSR     
                    

結局、だめです。EVAL S=100の直後、*PSSRに進みますが、なにもせず、戻りますので、*PSSRのENDSRの後で、エラーになります。そこで、ENDSRの演算項目2に、何かを入れて、スキップしたいところですが、*DETL他では、結局、後続の、EVAL=10に進みません。つまり、いったんエラーが起きたら、その明細サイクルはスキップしてしまい、次へ進むのです。BASICのON ERROR GOSUBとは、動きが違います。

EVALの桁あふれエラーは、どうにもなりません。何とかして欲しいです。


参考:プログラム状況コード(RPGiv)

通常のコード
コード 条件
00000 例外/エラーは起こっていない。
00001 呼び出されたプログラムから LR 標識がオンになって戻った。
例外/エラーのコード
コード 条件
00100 ストリング操作の範囲外の値
00101 負の平方根
00102 ゼロによる除算
00103 中間結果が結果を入れるだけ大きくない。
00112 日付/時刻、または時刻スタンプの値が正しくない。
00113 日付オーバーフローまたは下位桁あふれ。(たとえば、日付演算の結果が*HIVAL より大きいかまたは *LOVAL より小さい数になる場合。)
00114 日付が4文字の年から2文字の年にマップされ、日付の範囲が 1940〜2039にない日付マッピング・エラー。
00120 テーブルまたは配列の順序が違っている。
00121 配列指標が正しくない。
00122 OCCUR が範囲外
00123 プログラムの初期設定ステップでリセットしようとした。
00202 呼び出されたプログラムまたはプロシージャーが正常に実行されず、停止標識 (H1〜H9) はオンでない。
00211 呼出しプログラムまたはプロシージャーのエラー
00222 ポインターまたはパラメーター・エラー
00231 呼び出されたプログラムまたはプロシージャーから停止標識がオンになって戻った。
00232 このプログラムで停止標識がオンになった。
00233 RETURN 命令の実行時に停止標識がオンになった。
00299 RPG IV 定様式ダンプが正常に実行されなかった。
00333 DSPLY 命令のエラー
00401 IN/OUT で指定されたデータ域が見つからない。
00402 事前開始でないジョブに対しては *PDA は無効
00411 データ域のタイプまたは長さが一致しない。
00412 データ域が出力用にロックされていない。
00413 IN/OUT 命令のエラー
00414 ユーザーにデータ域を使用する権限がない。
00415 ユーザーにデータ域を変更する権限がない。
00421 UNLOCK 命令のエラー
00431 データ域は別のプログラムによってすでにロック済みである。
00432 データ域は同じ処理内のプログラムによってロック済みである。
00450 文字フィールド全体がシフト・アウトおよびシフト・イン文字で囲まれていない。
00501 分類順序検索の障害
00502 分類順序変換の障害
00802 コミットメント制御は活動状態になっていない。
00803 ロールバック操作が正常に実行されなかった。
00804 COMMIT 命令でエラーが起こった。
00805 ROLBK 命令でエラーが起こった。
00907 10 進数データ・エラー(数字または符号が無効)
00970 プログラムの生成に使用されたコンパイラーのレベル番号が、RPG IVの実行時サブルーチンのレベル番号と一致しない。
09998 ILE RPG OS/400 用コンパイラーまたは実行時サブルーチンの内部障害
09999 システム・ルーチン内のプログラム例外
 

[ Previous ] [ HOME ] [ Upper ] [ Next ]

You are at K's tips-n-kicks of AS/400

 

SEO [PR] 爆速!無料ブログ 無料ホームページ開設 無料ライブ放送