エラー処理サブルーチンを作成する時には、次の 2 つのことを行います。
このサブルーチン・エラー処理プログラムは例外を処理して、制御をユーザー のサブルーチンに渡します。
エラー処理サブルーチンを使用して、起こったエラーに基づいて特定の処置を 取るか、あるいは一般処置 (例えば、すべてのエラーに照会メッセージを出 すなど) を取ることができます。
エラー処理サブルーチンには次の考慮事項が適用されます。
このようなループを避けるためのエラー処理サブルーチンのコーディング方法 については、 エラー処理サブルーチンでのループの防止を参照してください。
メイン・プロシージャーでファイル・エラーまたは例外を処理するためには、 ファイル・エラー処理 (INFSR) サブルーチンを作成することができます。 ファイル例外が起こると、次のようになります。
ファイル・エラー処理サブルーチンは複数のファイルでエラーを処理すること ができます。
次の制約事項が適用されます。
プログラムにファイル・エラー処理サブルーチンを追加するためには、 次のステップを行ってください。
図 132 には、INFSR エラー処理サブルーチンを使った例外処理の例が 示してあります。 プログラム TRNSUPDT は単純な在庫更新プログラムです。このプログラムはトランザクション・ファイル TRANSACT を使用して 在庫マスター・ファイル PRDMAS を更新します。入出力エラーが起こった場合には、INFSR エラー処理サブルーチンが呼び出さ れます。 レコード・ロック・エラーの場合には、そのレコードがバックログ・ファイル に書き出されます。 そうでない場合には、照会メッセージが出されます。
PRDMAS のファイル仕様書は INFDS を識別するとともに、それに関連した INFSR を識別するということに注意してください。
TRANSACT ファイルの各レコードに対して次のことが行われます。
*=================================================================* * TRNSUPDT: このプログラムは簡単な在庫更新プログラムです。 * * トランザクション・ファイル (TRANSACT) が連続的に処理されます。 * * トランザクションにある製品番号が、マスター・ファイル (PRDMAS) * * にランダムにアクセスするキーとして使用されます。 * * 1. レコードが見つかった場合には、在庫数量が * * 更新されます。 * * 2. レコードが見つからなかった場合には、報告書にエラーが * * 印刷されます。 * * 3. 現在レコードがロックされている場合には、トランザクションは * * トランザクション受注残ファイルに書き出され、 * * 後で処理されます。 * * 4. それ以外の予期しないエラーが起こった場合には、実行時エラー・ * * メッセージが出されます。 * *=================================================================* *-----------------------------------------------------------------* * ファイルの定義: * * 1) PRDMAS - 製品マスター・ファイル * * 2) TRANSACT - トランザクション・ファイル * * 3) TRNBACKLG - トランザクション受注残ファイル * * 2) PRINT - エラー報告書 * *-----------------------------------------------------------------* FPRDMAS UF E K DISK F INFSR(PrdInfsr) F INFDS(PrdInfds) FTRANSACT IP E DISK FTRNBACKLG O E DISK FPRINT O F 80 PRINTER *-----------------------------------------------------------------* * ファイル PRDMAS のファイル情報データ構造を定義します。 * * *STATUS フィールドは取るべき処置を決めるために使用されます。 * *-----------------------------------------------------------------* D PrdInfds DS D PrdStatus *STATUS *-----------------------------------------------------------------* * 予期される例外をリストします。 * *-----------------------------------------------------------------* D ErrRecLock C CONST(1218)
*-----------------------------------------------------------------* * トランザクションの製品番号を使用して、製品マスター・ファイルに * * アクセスします。 * *-----------------------------------------------------------------* C TRNPRDNO CHAIN PRDREC 10 *-----------------------------------------------------------------* * レコードが見つかった場合、マスター・ファイルの数量を更新します。* *-----------------------------------------------------------------* C IF NOT *IN10 C SUB TRNQTY PRDQTY C UPDATE PRDREC *-----------------------------------------------------------------* * レコードが見つからない場合には、エラー報告書を書き出します。 * *-----------------------------------------------------------------* C ELSE C EXCEPT NOTFOUND C ENDIF C SETON LR *-----------------------------------------------------------------* * エラー処理ルーチン。 * *-----------------------------------------------------------------* C PrdInfsr BEGSR *-----------------------------------------------------------------* * 現在マスター・レコードがロックされている場合、トランザクション・* * レコードを受注残ファイルに書き次のトランザクションにスキップ。 * *-----------------------------------------------------------------* C PrdStatus DSPLY C IF (PrdStatus = ErrRecLock) C WRITE TRNBREC C MOVE '*GETIN' ReturnPt 6 *-----------------------------------------------------------------* * 予期しないエラーが起こった場合、照会メッセージが出されます。 * *-----------------------------------------------------------------* C ELSE C MOVE *BLANK ReturnPt C ENDIF C ENDSR ReturnPt *-----------------------------------------------------------------* * エラー報告書の形式。 *-----------------------------------------------------------------* OPRINT E NOTFOUND O TRNPRDNO O 29 'NOT IN PRDMAS FILE'
制御がエラー処理サブルーチンに渡されると、次のことが起こります。
レコード・ロック・エラーの検査は、PRDMAS の INFDS の *STATUS サブフィールドを、 レコード・ロック状況コードの値によって定義される ErrRecLock フィールドと突き合わせることによって 行われるということに注意してください。 他のエラーを定義し、 そのエラーを検査し、適切な処置を取ることによって、 他のタイプの入出力エラーを処理できるように INFSR を拡張することができます。
プログラム・エラーまたは例外を処理するためには、プログラム・エラー処理 サブルーチン (*PSSR) を作成することができます。 プログラム・エラーが起こると、次のようになります。
ファイル仕様書でキーワード INFSR の後に *PSSR を指定することによって、 ファイル・エラーの後でプログラム・エラー処理サブルーチンに明示的に制御を渡すことができます。
モジュールのプロシージャーのどれか (あるいはすべて) に *PSSR をコーディングすることができます。 各 *PSSR は、それがコーディングされているプロシージャーに固有です。
プログラムに *PSSR エラー処理サブルーチンを追加するためには、 次のステップを行ってください。
図 133 には、 メイン・プロシージャーのプログラム・エラー処理サブルーチンの例を示して あります。
*-----------------------------------------------------------------* * プログラム状況データ構造の対応する部分を定義します。 * *-----------------------------------------------------------------* D Psds SDS D Loc *ROUTINE D Err *STATUS D Parms *PARMS D Name *PROC *-----------------------------------------------------------------* * コーディングの本体部分 * ゼロによる除算が行なわれるとエラーが発生します。 * *PSSR サブルーチンに制御が渡されます。 *-----------------------------------------------------------------* *=================================================================* * *PSSR: メイン・プロシージャーのエラー処理サブルーチン。状況が * 102 であるかどうかをチェックすることにより、ゼロによる * 除算エラーをチェックします。エラーがあれば、除数に 1 を * 加算し、*GETIN を ReturnPt に転送して続行します。 *=================================================================* C *PSSR BEGSR C IF Err = 102 C ADD 1 Divisor C MOVE '*GETIN' ReturnPt 6 *-----------------------------------------------------------------* * 予期しないエラーが起こったため、 * *CANCL を ReturnPt に転送してプロシージャーを終了させます。 *-----------------------------------------------------------------* C ELSE C MOVE '*CANCL' ReturnPt C ENDIF C ENDSR ReturnPt
プログラム状況データ構造は、定義仕様書で定義されます。 事前定義のサブフィールドの *STATUS, *ROUTINE, *PARMS, および *PROGRAM が指定され、 各サブフィールドには名前が割り当てられています。
*PSSR エラー処理サブルーチンは、演算仕様書でコーディングされています。 プログラム・エラーが起こると、ILE RPG は制御を *PSSR エラー処理サブルーチンに渡します。 このサブルーチンは、除数がゼロの除算命令が原因で例外が起こったかどうかを判別します。 そうであった場合には、除数 (Divisor) に 1 が加算され、 フィールド ReturnPt にリテラル '*DETC' が転送され、 明細演算ルーチンの始めからプログラムが処理を再開することを示します。
例外がゼロによる除算でなかった場合には、リテラル '*CANCL' が フィールド ReturnPt に転送され、プロシージャーが終了します。
図 134 および 図 135 では、 サブプロシージャーの類似したプログラム・エラー処理サブルーチンを コーディングする方法を示しています。1 つの例として、GOTO を、 他の例としては、RETURN 命令をコーディングします。
*-----------------------------------------------------------------* * サブプロシージャー定義の開始 *-----------------------------------------------------------------* P SubProc B D SubProc PI 5P 0 ... *-----------------------------------------------------------------* * 回復コードを含むコーディング本体 *-----------------------------------------------------------------* C TryAgain TAG C X DIV Divisor Result C Return Result *-----------------------------------------------------------------* * ゼロによる除算が行なわれるとエラーが発生します。 * *PSSR サブルーチンに制御が渡されます。 *-----------------------------------------------------------------* C *PSSR BEGSR *-----------------------------------------------------------------* * これがゼロによる除算のエラーの場合は、除数に 1 を加算して、 * 再試行します。 *-----------------------------------------------------------------* C IF Err = 102 C ADD 1 Divisor C GOTO TryAgain C ENDIF *-----------------------------------------------------------------* * 制御が ENDSR に達すると、プロシージャーは正常に実行されません。 *-----------------------------------------------------------------* C ENDSR P E
*-----------------------------------------------------------------* * サブプロシージャー定義の開始 *-----------------------------------------------------------------* P SubProc B D SubProc PI 5P 0 ... *-----------------------------------------------------------------* * 除算命令を含むコーディング本体 *-----------------------------------------------------------------* C X DIV Divisor Result C Return Result *-----------------------------------------------------------------* * ゼロによる除算が行なわれるとエラーが発生します。 * *PSSR サブルーチンに制御が渡されます。 *-----------------------------------------------------------------* C *PSSR BEGSR *-----------------------------------------------------------------* * これがゼロによる除算エラーの場合、サブプロシージャーから * 0 が戻されます。 *-----------------------------------------------------------------* C IF Err = 102 C RETURN 0 C ENDIF *-----------------------------------------------------------------* * 制御が ENDSR に達すると、プロシージャーは正常に実行されません。 *-----------------------------------------------------------------* C ENDSR P E
前の例では、*PSSR でエラーが起こるため、ループの起こる可能性は少なくなっています。 しかし、*PSSR がどのように書かれるかによって、*PSSR の処理中に例外が起こるとループが起こる可能性があります。
このようなループを避ける 1 つの方法として、 サブルーチンに初回の実行を示すスイッチを設定することができます。 サブルーチンの初回の実行でない場合には、ENDSR 命令の演算項目 2 に *CANCL などの 適切な戻り点を指定することができます。
図 136 には、*PSSR サブルーチン内でのループを避ける方法を 示すために例外を生成するように設計されたプログラム NOLOOP を示してあります。 このプログラムは例外を次の 2 回生成します。
*=================================================================* * NOLOOP: *PSSR サブルーチンの反復を回避する方法を示します。 * *=================================================================* *-----------------------------------------------------------------* * エラーを起こすために使用する配列 * *-----------------------------------------------------------------* D Arr1 S 10A DIM(5) *-----------------------------------------------------------------* * 配列の範囲外エラーを生成し、制御を *PSSR に渡します。 * *-----------------------------------------------------------------* C Z-ADD -1 Neg1 5 0 C MOVE Arr1(Neg1) Arr1(Neg1) C MOVE *ON *INLR *=================================================================* * *PSSR: プロシージャーのエラー処理サブルーチン。PSSR の反復を検出* * するために変数 InPssr を使用します。 * * 反復を検出した場合には、プロシージャーを *CANCL します。 * *=================================================================* C *PSSR BEGSR C IF InPssr = 1 C MOVE '*CANCL' ReturnPt 6 C Z-ADD 0 InPssr 1 0 C ELSE C Z-ADD 1 InPssr * * * サブルーチンがプロシージャーを取り消す方法を見るために * * ここで PSSR に別のエラーを生成します。 * * * C MOVE Arr1(Neg1) Arr1(Neg1) * * * Neg1 がまだ負の場合には、次の 2 つの命令は処理されない * * ことに注意してください。 * * * C MOVE '*GETIN' ReturnPt C Z-ADD 0 InPssr C ENDIF C ENDSR ReturnPt
図 136 のソースを使ってプログラムを作成し、そのデバッグを 始めるには、次の入力をします。
CRTBNDRPG PGM(MYLIB/NOLOOP) DBGVIEW(*SOURCE) STRDBG PGM(MYLIB/NOLOOP)
*PSSR サブルーチンの BEGSR 行に中断点を設定することにより、*PSSR サブルーチンを ステップスルーすることができます。
プログラムを呼び出すと、次のことが起こります。
ループを避けるためにここで用いた方法は、INFSR エラー処理サブルーチン内でも使用することができます。
(C) Copyright IBM Corporation 1992, 2006. All Rights Reserved.