非構造化例外処理の概要
更新 : 2007 年 11 月
非構造化例外処理では、コードのブロックの先頭に配置する On Error ステートメントによって、そのブロック内で発生するすべてのエラーが処理されます。On Error ステートメントの実行後にプロシージャ内で例外が発生すると、On Error ステートメントの引数 line で指定した行にプログラムが分岐します。引数 line には、例外ハンドラの場所を示す行番号または行ラベルを指定します。
元のプロシージャから他のプロシージャが呼び出され、呼び出されたプロシージャで例外が発生することがあります。このような場合、呼び出されたプロシージャによって例外が処理されないと、例外が呼び出し元のプロシージャに戻されて、引数 line で指定した行に実行が分岐します。
メモ : |
---|
On Error を使った非構造化のエラー処理では、アプリケーションのパフォーマンスの低下を招いたり、コードのデバッグや管理が難しくなったりする可能性があります。構造化例外処理を使用することをお勧めします。詳細については、「Visual Basic の構造化例外処理の概要」を参照してください。 |
On Error GoTo Line
On Error GoTo Line ステートメントでは、必須の line 引数で指定した行でエラー処理コードが開始されると想定されています。ランタイム エラーが発生すると、引数で指定した行ラベルまたは行番号に制御が分岐して、エラー ハンドラがアクティブになります。On Error GoTo Line ステートメントと同じプロシージャ内の行を指定する必要があります。それ以外の行を指定すると、Visual Basic でコンパイル エラーが発生します。行ラベルを使ったエラー ハンドラの使用例を次に示します。
Sub TestSub
On Error GoTo ErrorHandler
' Code that may or may not contain errors.
Exit Sub
ErrorHandler:
' Code that handles errors.
Resume
End Sub
この例には、ErrorHandler というエラー ハンドラが含まれています。TestSub サブルーチン内のコードがエラーを生成すると、ErrorHandler ラベルに続くコードがすぐに Visual Basic で実行されます。エラー処理ブロックの最後に、Resume ステートメントによって、最初にエラーが発生したコードの行に制御が戻されます。その後、エラーが発生しなかった場合と同じように、サブルーチンの残りのコードが実行されます。
メモ : |
---|
エラー処理ブロックの直前に Exit Sub ステートメントを配置する必要があります。そうしないと、Visual Basic によってサブルーチンの最後にエラー処理コードが実行され、予想外の結果になる可能性があります。 |
On Error Resume Next
On Error Resume Next ステートメントを使用すると、ランタイム エラーが発生した場合に、エラーが発生したステートメントの次のステートメントに制御が渡されます。この時点では引き続き実行され、On Error Resume Next ステートメントによって、プロシージャ内の他の場所に制御を移す代わりに、エラーが発生する可能性がある場所にエラー処理ルーチンを配置できます。
メモ : |
---|
プロシージャによって他のプロシージャが呼び出された場合、呼び出されたプロシージャの実行中に、On Error Resume Next ステートメントが非アクティブになります。このため、呼び出されるプロシージャごとに、必要に応じて On Error Resume Next ステートメントを配置する必要があります。これは、Resume Next の動作が、On Error Resume Next ステートメントを含むプロシージャにしか適用されないためです。呼び出されたプロシージャで処理できないエラーが発生すると、例外が呼び出し元のプロシージャに戻され、その呼び出しの次のステートメントから実行が再開されます。この場合、エラーは処理されません。 |
Resume は、On Error ステートメントの外で、単独で使用することもできます。Resume を単独で使用すると、Visual Basic によって、エラーを引き起こしたステートメントに制御が返されます。Resume は、通常、エラー ハンドラがエラーを修正した後に使用されます。
Visual Basic には、エラーが発生した行の次の行に制御を移す Resume Next ステートメントも用意されています。Resume Next は、エラーによってアプリケーションが停止しない場合に使用できます。また、エラーによってサブルーチンの結果が変わらない場合にも使用できます。
Resume ステートメントでの他のバリエーションには、On Error GoTo Line に類似した Resume Line があります。Resume Line によって、line 引数で指定した行に制御が渡されます。Resume Line を使用できるのは、エラー ハンドラの中だけです。
メモ : |
---|
コードをデバッグするときは、On Error Resume Next ステートメントを無効にする必要があります。 |
On Error GoTo 0
On Error GoTo 0 ステートメントにより、現在のプロシージャのエラー ハンドラが無効化されます。On Error GoTo 0 ステートメントがなくても、例外ハンドラを含むプロシージャが終了すると、エラー ハンドラは無効になります。
メモ : |
---|
On Error GoTo 0 ステートメントは、プロシージャに行番号 0 の行が含まれている場合でも、エラー処理コードの開始行として行 0 を指定するわけではありません。 |
On Error GoTo -1
On Error GoTo -1 ステートメントにより、現在のプロシージャの例外ハンドラが無効化されます。On Error GoTo -1 ステートメントがなくても、プロシージャが終了すると例外は自動的に無効になります。
メモ : |
---|
On Error GoTo -1 ステートメントは、プロシージャに行番号 -1 の行が含まれている場合でも、エラー処理コードの開始行として行 -1 を指定するわけではありません。 |
非構造化例外処理の例
DivideByZero という例外ハンドラが特定のエラー (この場合は 0 による除算) を処理する例を次に示します。これ以外のエラーが発生すると、Visual Basic でランタイム エラーが発生してアプリケーションが停止します。
Sub ErrorTest ()
' Declare variables.
Dim x As Integer, y As Integer, z As Integer
' The exception handler is named "DivideByZero".
On Error GoTo DivideByZero
' The main part of the code, which might cause an error.
x = 2
y = 0
z = x \ y
' This line disables the exception handler.
On Error GoTo 0
Console.WriteLine(x & "/" & y & " = " & z)
' Exit the subroutine before the error-handling code.
' Failure to do so can create unexpected results.
Exit Sub
' This is the exception handler, which deals with the error.
DivideByZero:
' Include a friendly message to let the user know what is happening.
Console.WriteLine("You have attempted to divide by zero!")
' Provide a solution to the error.
y = 2
' The Resume statement returns to the point at which
' the error first occurred, so the application
' can continue to run.
Resume
End Sub