【VBA】エラーの種類を判別して処理を分岐する方法 (Errオブジェクト)

目次

はじめに

VBAのエラー処理において、On Error GoTo はエラーが発生したら一律で同じ場所にジャンプするため、エラーの種類に応じた細かい対応がしにくい場合があります。一方で On Error Resume Next はエラーを無視するだけなので、エラーが起きたこと自体に気づきにくいです.

しかし、On Error Resume Next と、VBAの組み込みオブジェクトである Err オブジェクトを組み合わせることで、「発生したエラーの種類を判別し、そのエラー番号に応じて処理を分岐させる」という、より高度で柔軟なエラーハンドリングが可能になります。

この記事では、Errオブジェクトの主要なプロパティと、それを使って特定のエラーに対応する方法を解説します。


Errオブジェクトを使ったエラー処理のサンプルコード

このマクロは、セル C2 の値をセル D2 の値で割る、という処理を行います。On Error Resume Next を使ってエラーを一旦無視し、直後に Err.Number をチェックして、発生したエラーが「ゼロ除算(エラー番号: 11)」であれば専用のメッセージを、それ以外のエラーであれば汎用的なメッセージを表示します。

完成コード

' Errオブジェクトを使って、特定のエラーに対応する
Sub HandleSpecificError()

    Dim result As Double
    
    ' これ以降のエラーを無視して、次の行へ進む
    On Error Resume Next
    
    '--- エラーが発生する可能性のある処理 ---
    result = Range("C2").Value / Range("D2").Value
    
    '--- 直後にErr.Numberをチェックして、エラーの種類を判別 ---
    Select Case Err.Number
        Case 0
            ' エラーなし (Err.Numberが0は正常終了)
            Range("E2").Value = result
            MsgBox "計算が正常に完了しました。", vbInformation
            
        Case 11
            ' エラー番号11: 「0で除算しました。」エラー
            MsgBox "計算エラー: 割る数が0になっています。", vbCritical, "ゼロ除算エラー"
            
        Case 13
            ' エラー番号13: 「型が一致しません。」エラー (例: 文字列で割ろうとした)
            MsgBox "計算エラー: 数値以外の値がセルに含まれています。", vbCritical, "型不一致エラー"
            
        Case Else
            ' 上記以外の予期せぬエラー
            MsgBox "予期せぬエラーが発生しました。" & vbCrLf & _
                   "エラー番号: " & Err.Number & vbCrLf & _
                   "エラー内容: " & Err.Description, vbCritical, "不明なエラー"
    End Select
    
    '--- Errオブジェクトをクリアして、エラー状態をリセット ---
    Err.Clear
    
    '--- エラーハンドリングを通常の状態に戻す ---
    On Error GoTo 0

End Sub

コードの解説

Err オブジェクトとは?

Err は、VBA全体で共有されるグローバルなオブジェクトで、発生した実行時エラーに関する情報を保持しています。主要なプロパティは以下の通りです。

  • .Number: エラーを一意に識別するためのエラー番号(整数)を返します。エラーが発生していない場合は 0 になります。
  • .Description: エラーの内容を説明する文字列(例: “0で除算しました。”)を返します。
  • .Clear: Err オブジェクトの情報を手動でリセットし、.Number0 に戻します。

On Error Resume Next との組み合わせ

On Error Resume Next を使うと、エラーが発生してもプログラムは停止せず、次の行に進みます。しかし、エラーが発生したという情報は Err オブジェクトに記録されています。

そのため、エラーが発生しうる処理の直後If Err.Number <> 0 ThenSelect Case Err.Number を使って Err.Number の値を調べることで、「エラーは起きたか?」「もし起きたなら、それはどの種類のエラーか?」を判別し、適切な対応をとることができます。

Err.Clear の重要性

Err オブジェクトは、一度エラー情報を保持すると、次に別のエラーが発生するか、Err.Clear で明示的にクリアされるまで、その情報を保持し続けます。

もし、エラー処理が終わった後に Err.Clear を実行しないと、その後の別の処理で Err.Number をチェックした際に、過去のエラー情報を誤って検知してしまう可能性があります。そのため、エラーの判別と処理が終わったタイミングで Err.Clear を呼び出し、エラー状態をリセットするのが安全な作法です。


まとめ

今回は、Err オブジェクトを使って、発生したエラーの種類を特定し、処理を分岐させる高度なエラーハンドリング手法を解説しました。

  • On Error Resume Next でエラー発生後も処理を続行させる。
  • 直後に Err.Number を調べて、発生したエラーの番号を特定する。
  • Select CaseIf で、エラー番号に応じた処理を記述する。
  • 処理が終わったら、Err.Clear でエラー情報をリセットする。

この手法をマスターすれば、単にエラーを無視したり、一律の処理を行ったりするだけでなく、エラーの原因に応じてより的確なフィードバックをユーザーに返す、非常に堅牢で親切なプログラムを作成することができます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次