VBAで例外処理 try-catch-finally を使う方法


やりたい事

VBAで例外処理のtry-catch-finally構文みたいな事をやりたい。

サンプルコード

try-catch-finally構文のサンプルコードです

Sub test()
'エラーが起きたときはErrorHandler:へ飛ぶ
On Error GoTo ErrorHandler

    '何かの処理
    XXXXX
    XXXXX
    XXXXX
    XXXXX

    'Finally:へ飛ぶ
    GoTo Finally

'例外処理
ErrorHandler:

    'エラーメッセージを表示する
    Msgbox "[No:" & Err.Number & "]" & Err.Description, VbCritical & VbOkOnly, "エラー"

    'Finally:へ飛ぶ
    Resume Finally

'最終処理
Finally:

    '必ず通る処理
    XXXXX
    XXXXX

    '変数の開放をするetc..
    If Not XXXXX Is Nothing Then
        Set XXXXX = Nothing
    End If

End Sub

解説

VBAにはtry-catch-finally構文がありません。
なので、「行ラベル」と「On Error ステートメント」を用いてtry-catch-finally構文のようなことをします。

行ラベルとは

Office VBA リファレンス - 行ラベル

1コード行を示すために使用される。

'指定した行ラベルまでジャンプすることができる。
GoTo 行ラベル名
'ラベルは、文字で開始してコロン (:) で終了する必要がある。
行ラベル名:
'行ラベルを使用したサンプルコード
Sub test()

    MsgBox ("hoge1")

    GoTo Label  'Label:に飛ぶ

    MsgBox ("hoge2")    '実行されない

'ここに飛ぶ
Label:

    MsgBox ("hoge1")

End Sub

On Error ステートメントとは

Office VBA リファレンス - On Error ステートメント

エラーが起きたときに、エラーを無視したり、別の処理に分岐したりできる。

'エラーが無視される
On Error Resume Next
'エラーが起きたときに、指定した行ラベルまでジャンプすることができる。
On Error GoTo 行ラベル名
'On Error ステートメントを使用したサンプルコード
Sub test()
'エラーが起きたときはErrorHandler:へ飛ぶ
On Error GoTo ErrorHandler

    MsgBox ("hoge1")

    MsgBox ("hoge2")

    '何もエラーが起きなければここで処理を終了する
    Exit Sub

'もしエラーが起きたらここにとぶ
ErrorHandler:

    MsgBox ("hoge1")

End Sub

おまけ finallyで変数を解放する

VBAでExcelオブジェクトを操作するようなコードを書いていると、気づいたらプロセスにExcelが大量に溜まってしまうことがあると思います。

プロセスが溜まっていくのは、プログラムの実行中にエラーなどで処理が止まってしまい、プロセスが正しく終了されないまま放置されるのが原因です。
なので、エラーが起きたときにもプロセスを解放してあげる必要があります。

try-catch-finally構文を使用すれば、例外が起きようと起きまいとfinallyは必ず通るので、この中で変数の解放をしてあげるとよいと思います。