VBScript - エラー処理
スクリプトの実行中にエラーが起きた場合、通常、その時点でスクリプトは強制終了される。
実行時エラーに対して独自のエラー処理をするときは、`On Error Resume Next` ステートメントと `Err` オブジェクトを使う。
エラー処理の基本
`On Error Resume Next` ステートメントを使うと、エラー処理が有効になる。
エラー処理が有効な状態では、実行時エラーが起きても強制終了せず、そのまま処理を継続する。
エラー処理を無効にするには `On Error GoTo 0` ステートメントを使う。
実行時エラーの発生有無は `Err` オブジェクトの `Number` プロパティで判定できる。
`Number` プロパティは、エラーがなければ 0 に、あれば 0 以外になる。
基本的なエラー処理の流れは次のとおり。
エラーの発生が想定される処理の前に `On Error Resume Next` ステートメントを置いて、エラー処理を有効化
処理を実行
`Err.Number <> 0` だったらエラー処理する
`On Error GoTo 0` ステートメントでエラー処理を無効化
不適切なエラー処理はスクリプトの暴走につながる。注意すること。
次のサンプルは、ユーザーに入力された数値で 100 を割り、結果を表示する。
エラーが起きた場合は、エラー情報を通知して終了する。
Dim y
y = InputBox("100を割る数を入力してください")
'★エラー処理を有効化
On Error Resume Next
Dim ret
ret = 100 / y
If Err.Number <> 0 Then
'★エラー処理
WScript.Echo "Error # " & CStr(Err.Number) & " : " & Err.Description
WScript.Quit 1
End If
'★エラー処理を無効化
On Error GoTo 0
'計算結果を表示
WScript.Echo "100 ÷ " & y & " = " & ret
計算の前に入力チェックするべきだが、まぁサンプルということで。
エラー情報(Err オブジェクト)の内容
実行時エラーの内容は `Err` オブジェクトに格納される。
`Err` オブジェクトは以下のプロパティとメソッドを持つ。
Number プロパティ
エラー番号。正常なら 0 、異常なら 0 以外。
Description プロパティ
エラーの説明。
HelpFile プロパティ
ヘルプファイルのパス。
HelpContext プロパティ
ヘルプファイルのトピックを表すコンテキスト番号。
HelpFile プロパティを指定した場合、HelpContext プロパティで指定したトピックが自動的に表示される。
Source プロパティ
エラーを最初に発生させたオブジェクトの名前。
Clear メソッド
Err オブジェクトが持つすべてのプロパティの値をクリアする。
Raise メソッド
実行時エラーを生成する。
Err.Raise number [, source] [, description] [, helpFile] [, helpContext]
source:
エラーを生成したオブジェクトまたはアプリケーションの名前を指定する。
省略可能。description:
エラーの説明を指定する。
省略可能。helpFile:
ヘルプファイルのパスを指定する。
省略可能。helpContext:
ヘルプファイル内のトピックを識別するコンテキストIDを指定する。
省略可能。
エラー処理の適用範囲
On Error Resume Next ステートメントは使用したプロシージャにのみ適用される。
エラー処理が無効なプロシージャで実行時エラーが発生した場合、エラー処理が有効なプロシージャまで処理が渡る。
もしエラー処理が有効なプロシージャがなければ、そのままエラー情報が表示され、スクリプトは終了される。
例1)エラー処理が有効なプロシージャからエラー処理が無効なプロシージャを呼び出した場合
FuncA → FuncB で呼び出し、FuncB で実行時エラーが起きた場合、FuncA に処理が渡る。
'エラー処理が有効なプロシージャ FuncA
Sub FuncA
On Error Resume Next
Dim ret
ret = FuncB
'FuncB で実行エラーが起きた場合、ここ(FuncB を呼び出した行の次行)に処理が渡る
'エラー処理
If Err.Number <> 0 Then
WScript.Echo "Error # " & CStr(Err.Number) & " : " & Err.Description
WScript.Quit 1
End If
End Sub
'エラー処理が無効なプロシージャ FuncB
Function FuncB
'ゼロ除算エラーを起こす
FuncB = 100 / 0
End Function
例2)呼び出しの階層が深くなっても考え方は同じ
FuncA → FuncB → FuncC で呼び出し、FuncC で実行時エラーが起きた場合、FuncA に処理が渡る。
'エラー処理が有効なプロシージャ FuncA
Sub FuncA
On Error Resume Next
Dim ret
ret = FuncB
'FuncB/C で実行エラーが起きた場合、ここ(FuncB を呼び出した行の次行)に処理が渡る
'エラー処理
If Err.Number <> 0 Then
WScript.Echo "Error # " & CStr(Err.Number) & " : " & Err.Description
WScript.Quit 1
End If
End Sub
'エラー処理が無効なプロシージャ FuncB
Function FuncB
FuncB = FuncC
End Function
'エラー処理が無効なプロシージャ FuncC
Function FuncC
'ゼロ除算エラーを起こす
FuncC = 100 / 0
End Function
確実にエラー処理できるようにするには
実行時エラーによってスクリプトを強制終了されないようにするには、メインルーチンで `On Error Resume Next` ステートメントを使う。
そうすることで処理されなかったすべてのエラーをキャッチできるようになる。
'メインルーチン
On Error Resume Next
Call Main
If Err.Number = 0 Then
'正常終了
WScript.Quit 0
Else
'異常終了(処理されなかったすべてのエラーをここでキャッチできる)
WScript.Echo "Error # " & CStr(Err.Number) & " : " & Err.Description
WScript.Quit 1
End If
On Error GoTo 0
'サブルーチン
Sub Main
'TODO: 処理を書く
End Sub
サブルーチンのエラーをメインルーチンで処理する
サブルーチンで発生したエラーを、メインルーチンで処理するようにもできる。
そうする場合、サブルーチンはエラー処理を有効化しておく。
メインルーチンは無効のままで良い。
'メインルーチン
WScript.Echo Divide(100, 0)
If Err.Number <> 0 Then
'★サブルーチンで発生したエラーの処理
WScript.Echo "Divide Error # " & CStr(Err.Number) & " : " & Err.Description
WScript.Quit 1
End If
'サブルーチン
Function Divide(ByVal a, ByVal b)
'★エラー処理を有効化
On Error Resume Next
'実行時エラーが起きるかもしれない処理を実行
Divide = a / b
End Function
VBScript ではラベルによるエラー処理はできない
VBScript では VB6 や VBA にあるラベルによるエラー処理は利用できない。
以下のように `On Error GoTo 〈ラベル名〉` と指定して、エラー発生時に指定したラベルへ飛ばす書き方は不可能。
'Notice: VBScript ではサポートされていない書き方
'エラーが起きたら ErrHandler ラベルに飛ばす
On Error GoTo ErrHandler
Dim ret
ret = 100 / 0
MsgBox ret
ExitHandler:
Exit Sub
ErrHandler:
MsgBox "Error # " & CStr(Err.Number) & " : " & Err.Description
GoTo ExitHandler