\ お問い合わせはこちら /

【VBA】エラー種類とOn Error文によるハンドリング【エラー処理方法】

VBAを使ってプログラミングをしていると、「エラー」は避けて通れません。

適切にエラー処理(エラーハンドリング)しておかないと、次のような困ったことが起こります。

  • プログラムが途中で止まってしまう
  • 意図しない結果を返す
  • エラーの原因がわからない

本記事では知っておきたいエラーハンドリングの方法と、知っておくと便利な付随知識をご紹介します。

VBAにおけるエラーを理解しよう

VBAのエラーを扱うための基礎知識を解説します。

最初の段階では以下の内容を把握しておけば十分戦えます。

エラー処理が必要な理由

VBAはユーザ操作や外部ファイルとの連携が多いため、実行中に想定外の事態が発生しやすい言語です。

  • 存在しないファイルを開こうとした
  • 数値の0で割り算をした
  • 存在しないシート名を参照した

こうした場合、エラー処理を組み込んでいないとプログラムは強制終了してしまいます。

エラー処理は、ユーザーにとって「親切で安定したプログラム」にするための必須要素 です。

VBAで発生するエラーの種類

VBAのエラーは次の2種類に分けられます。

  • コンパイルエラー
  • 実行時エラー

エラーハンドリングの対象は②の「実行時エラー」です。

順番に解説します。

① コンパイルエラー

コードの実行前に発生するエラーです。

明らかにコードの書き方が間違っている場合に、VBE(VBAのエディタ)が教えてくれます。

開発時に直せばいいので、本番での影響は少なエラーです。

例えばIfを書いたのにEnd Ifを書いていない場合に発生します。

② 実行時エラー

プログラムを実行している最中に発生するエラーです。

例えば存在しないファイルを開こうとする場合などは、これに当たります。

この場合には、On Errorなどを使ったエラーハンドリングを行います。

エラーハンドリングの具体的な方法

VBAで実行時エラーを制御するには On Error 文を使います。

いくつか使い方があるので、適切な方法で使い分けましょう。

1. On Error GoTo [ラベル]

エラーがあった場合に、ラベルとして設定した箇所にジャンプします。

以下の場合は、エラー時にErrorHandlerにジャンプすることになります。

VB
On Error GoTo ErrorHandler

Dim x As Integer
x = 10 / 0   ' エラー発生

Exit Sub

ErrorHandler:
    MsgBox "エラーが発生しました: " & Err.Description

実務的には最も使われるエラーハンドリングの方法です。

2. Resumeステートメント

Resumeステートメントはエラー発生時の挙動を制御するもので、On Error GoTo と組み合わせて使います。

種類は以下の3つがあります。

ステートメント効果
Resumeエラーが出た行を再実行する
Resume Nextエラーが出た次の行から再開
Resume [ラベル]指定ラベルにジャンプして再開

例えばResume Nextを使う場合は以下のようになります。

VB
On Error GoTo ErrorHandler

Dim x As Integer
x = 10 / 0

Exit Sub

ErrorHandler:
    MsgBox "エラー: " & Err.Description
    Resume Next   ' ← ここで挙動を制御

上記の場合には4行目でエラーが出るので、MsgBoxを表示した後に6行目が実行されます。

3. On Error Resume Next

エラー行があっても無視する方法です。

VB
On Error Resume Next
x = 10 / 0   ' ← 本来はエラーだが、次の行へ進む
Debug.Print "処理継続"

この方法ではエラーに気づくことができないので、あまり使う機会はありません。

ある行からエラー無視を解除したい場合には、On Error GoTo 0を書きます。

VB
On Error Resume Next
x = 10 / 0   ' エラー無視
On Error GoTo 0
y = 10 / 0   ' ここでは通常通りエラーで停止

エラーハンドリングに関する追加の知識

エラーハンドリングの具体的な方法でご紹介した3つの方法だけでもエラーハンドリングはできますが、より高度な操作をするなら他の機能も組み合わせることが必要です。

順番に解説していきます。

1. Errオブジェクトのプロパティ

例えば以下のような形でプロパティを指定すると、Errオブジェクトの情報を取得できます。

VB
On Error GoTo ErrorHandler

Dim x As Integer
x = 10 / 0

Exit Sub

ErrorHandler:
    MsgBox "番号: " & Err.Number & vbCrLf & _
           "内容: " & Err.Description

その他のプロパティについては、以下のようなものがあります。

プロパティ名内容
Numberエラー番号(整数値)。0はエラーなし
Descriptionエラー内容(文字列)。人間が理解できるメッセージ
Sourceエラーの発生元(モジュール名やオブジェクト名)。Err.Raiseで設定可能
HelpFileエラーに関連付けられたヘルプファイルのパス
HelpContextヘルプファイル内のトピックID(整数)
LastDllError外部DLL呼び出しでのエラーコード

NumberDescriptionはよく使うので、この二つを覚えておけば問題ありません。

2. Errオブジェクトのメソッド

Errオブジェクトを操作することもでき、以下のようなメソッドを使います。

メソッド説明
ClearErr.NumberErr.Description をリセットする
Raise任意のエラーを発生させる(番号・発生元・メッセージを指定可能)

使用例も掲載します。

VB
On Error Resume Next
x = 10 / 0
If Err.Number <> 0 Then
    Debug.Print "エラー発生: "; Err.Description
    Err.Clear
End If

5行目の段階でErrオブジェクトはリセットされることになります。

3. エラー処理のスコープ

On Errorの効力は、同じプロシージャ内のみ有効です。

つまり、あるSubプロシージャを抜けるとErrがリセットされます。

4. エラーハンドリングのベストプラクティス

以下の内容に気をつけると良いです。

  1. 必要な範囲でのみエラーハンドリングを使う
    Resume Nextの使用は最小限にすること。
    ・意図しない挙動を見逃す。
  2. エラー後はリソースを解放する
    ・開いたファイルは閉じる
    ・DB接続を開いたら閉じる
  3. ユーザーに分かりやすいメッセージを提示する
    ・例:「売上データのファイルが見つかりません。フォルダを確認してください。」

5. そもそもエラーハンドリングをしないようにする

「存在しません」系のエラーは、そもそも存在確認をしておけばエラーハンドリングは不要です。

VB
Sub ファイルを開く()
    Dim fPath As String
    fPath = "C:\Test\data.xlsx"
    
    ' 存在確認
    If Dir(fPath) = "" Then
        MsgBox "ファイルが存在しません: " & fPath
        Exit Sub
    End If
    
    ' 存在するので開く
    Workbooks.Open fPath
End Sub

上記はファイルの例ですが、シートの存在確認などでも使えます。

まとめ

本記事ではエラーハンドリングの基本を解説してきました。

実務で使う内容としては本記事で大体網羅できているので、ぜひ全て使いこなせるように頑張ってみてください!

次回は「デバッグ術:ブレークポイント設定・ウォッチウインドウ活用法」で、実際にエラー箇所を効率的に特定するテクニックを解説予定です。

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

この記事を書いた人

はじめまして。旅行をこよなく愛するITエンジニアのNommyです。
現在、婚活中。
これまでUberEatsの配達員、金融業界、ミステリーショッパーなど色々なお仕事を経験してきました。
本ブログでは僕が経験してきたことなどを執筆していきます。

コメント

コメントする

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)