はじめに
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
オブジェクトの情報を手動でリセットし、.Number
を0
に戻します。
On Error Resume Next
との組み合わせ
On Error Resume Next
を使うと、エラーが発生してもプログラムは停止せず、次の行に進みます。しかし、エラーが発生したという情報は Err
オブジェクトに記録されています。
そのため、エラーが発生しうる処理の直後に If Err.Number <> 0 Then
や Select Case Err.Number
を使って Err.Number
の値を調べることで、「エラーは起きたか?」「もし起きたなら、それはどの種類のエラーか?」を判別し、適切な対応をとることができます。
Err.Clear
の重要性
Err
オブジェクトは、一度エラー情報を保持すると、次に別のエラーが発生するか、Err.Clear
で明示的にクリアされるまで、その情報を保持し続けます。
もし、エラー処理が終わった後に Err.Clear
を実行しないと、その後の別の処理で Err.Number
をチェックした際に、過去のエラー情報を誤って検知してしまう可能性があります。そのため、エラーの判別と処理が終わったタイミングで Err.Clear
を呼び出し、エラー状態をリセットするのが安全な作法です。
まとめ
今回は、Err
オブジェクトを使って、発生したエラーの種類を特定し、処理を分岐させる高度なエラーハンドリング手法を解説しました。
On Error Resume Next
でエラー発生後も処理を続行させる。- 直後に
Err.Number
を調べて、発生したエラーの番号を特定する。 Select Case
やIf
で、エラー番号に応じた処理を記述する。- 処理が終わったら、
Err.Clear
でエラー情報をリセットする。
この手法をマスターすれば、単にエラーを無視したり、一律の処理を行ったりするだけでなく、エラーの原因に応じてより的確なフィードバックをユーザーに返す、非常に堅牢で親切なプログラムを作成することができます。