V7R4 又は PTF適用済み V7R2以上 で使用可能な新命令 「ON-EXIT」。
「ON-EXIT」の特徴は、サブプロシージャ内が終了する際には ”必ず実行される” という点。
これまで、辛かったのは、もし MONITOR していない例外が発生した場合がある場合は、*PSSR を定義したりで例外をキャッチしていたが、例外が例外を起こす悪夢や、発生元をSDSに頼るなど、処理が煩雑になりがち。
しかし、「ON-EXIT」 を使う事で、そのサブプロシージャの処理に準じた例外を等をハンドリング出来たり、中途半端な状況の顛末処理を必ず実行させる事が出来る。以下は、使用例。
QII0130R.rpgle
H DFTACTGRP(*NO) ACTGRP(*NEW)
F*- ---<< ファイル定義 >>-----*
FITEM UF A E K DISK
D*- ---<< 変数定義 >>-----*
D MSG S 40A
C*- ***************************************************************
C*- * KLIST **
C*- ***************************************************************
C ITEMKEY1 KLIST
C KFLD K@CODE 5 0 商品コード
C*- ***************************************************************
C*- * メインロジック **
C*- ***************************************************************
C Z-ADD 99999 K@CODE 商品コード
C EVAL MSG = SUBPROC1()
C MSG DSPLY
C*
C Z-ADD 90000 K@CODE 商品コード
C EVAL MSG = SUBPROC1()
C MSG DSPLY
C*
C SETON LR
C RETURN
P*- ***************************************************************
P*- * サブプロシージャ **
P*- ***************************************************************
P SUBPROC1 B
D SUBPROC1 PI 1A
D*- ---<< 変数定義 >>-----*
D NOMON S N 監視外例外
C*
C* // サブロジック
C*
C MONITOR
C ITEMKEY1 CHAIN ITEMR 90
C N90 WRITE ITEMR
C ON-ERROR *ALL
C EVAL MSG = '[ERROR:*ALL]'
C + %CHAR(%STATUS)
C + '*ALL 監視エラー '
C MSG DSPLY
C RETURN 'E'
C ENDMON
C*
C Z-ADD *ZERO W#ZERO 3 0
C 100 DIV W#ZERO W#ZERO
C*
C RETURN 'S'
C*
C* // 必ずサブプロシージャで通過する終了処理
C ON-EXIT NOMON
C N90 UNLOCK ITEM
C EVAL MSG = '[EXIT]'
C + ' 全ての処理が通過する '
C + %CHAR(NOMON)
C MSG DSPLY
C*
C* 監視外の例外が発生している場合
C IF NOMON
C* ログなど ...
C RETURN 'E'
C ENDIF
P E
上記例では、監視外のゼロ除算を行うとMSGW
になるが、C:キャンセル
で応答した場合でも、「ON-EXIT」は必ず最後に実行される。以下スクリーンショット。
まだ、試していないが、マニュアルによると呼び出しスタックの上位がキャンセルされても、実行される様。これは、結構便利かも!
注意点は
- サブプロシージャ限定であること。メインプロシージャでは使えない。
- DFTACTGRP(*YES) では使えない
- 幾つかのAPIが使えない。CEEDOD、CEEGSI、CEETSTA
- 幾つかの命令が使えない。BEGSR、DUMP、EXSR、GOTO、RESET、TAG
上記、以外もマニュアルには記載されていますが、割愛。例外監視していないエラーの場合DUMP
は使えたら良かったのになぁーって感じです。