VBScript - エラー処理

スクリプトの実行中にエラーが起きた場合、通常、その時点でスクリプトは強制終了される。

実行時エラーに対して独自のエラー処理をするときは、`On Error Resume Next` ステートメントと `Err` オブジェクトを使う。

エラー処理の基本

`On Error Resume Next` ステートメントを使うと、エラー処理が有効になる。

エラー処理が有効な状態では、実行時エラーが起きても強制終了せず、そのまま処理を継続する。

エラー処理を無効にするには `On Error GoTo 0` ステートメントを使う。


実行時エラーの発生有無は `Err` オブジェクトの `Number` プロパティで判定できる。

`Number` プロパティは、エラーがなければ 0 に、あれば 0 以外になる。


基本的なエラー処理の流れは次のとおり。

  1. エラーの発生が想定される処理の前に `On Error Resume Next` ステートメントを置いて、エラー処理を有効化

  2. 処理を実行

  3. `Err.Number <> 0` だったらエラー処理する

  4. `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

いいなと思ったら応援しよう!