VBAのエラー – エラー処理のベストプラクティス

Written by

Mel Jenkins

Reviewed by

Steve Rynearson

Translated by

masahiro yoshida

Last updated on 4月 18, 2022

VBAエラーのチートシート

エラー

説明
VBAコード
エラー発生時にコードを停止し、エラーを表示する
On Error GoTo 0
エラー発生時にエラーをスキップして実行を継続する
On Error Resume Next
エラー発生時にコード [Label] の行に移動する
On Error GoTo [Label]
エラーをクリア(リセット)する
On Error GoTo -1
エラー番号を表示する
MsgBox Err.Number
エラーの内容を表示する
MsgBox Err.Description
独自のエラーを発生させる関数
Err.Raise

VBAのチートシートや無料のPDFダウンロードをもっと見る

VBAのエラー処理

VBAのエラー処理とは、VBA実行時エラー(ランタイムエラー)を予測し、検出し、解決するプロセスのことです。VBAのエラー処理プロセスは、実際にエラーが発生する前に、コードを書くときに発生します。

VBA実行時エラーとは、コードの実行中に発生するエラーのことです。実行時エラーの例としては、以下のようなものがあります。

  • 存在しないワークブック、ワークシート、またはその他のオブジェクトを参照している。(実行時エラー1004
  • 無効なデータ、例えば、エラーを含むExcelセルを参照している。(型の不一致 – 実行時エラー13
  • ゼロで割ろうとしている

VBA On Errorステートメント

VBAのエラー処理のほとんどは、On Errorステートメントで行われます。On Errorステートメントは、VBAがエラーに遭遇した場合の処理を指示します。On Errorステートメントには、3つの種類があります。

  • On Error GoTo 0
  • On Error Resume Next
  • On Error GoTo Line

On Error GoTo 0

On Error GoTo 0はVBAのデフォルト設定です。以下のコード行を追加することで、このデフォルト設定を復元することができます。

On Error GoTo 0

On Error GoTo 0でエラーが発生した場合、VBAはコードの実行を停止し、標準のエラーメッセージボックスを表示します。

vba runtime error 13 実行時エラー

多くの場合、On Error Resume Nextエラー処理(次のセクション)を追加した後にOn Error GoTo 0を追加します。

Sub ErrorGoTo0()

On Error Resume Next
    ActiveSheet.Shapes("Start_Button").Delete
On Error GoTo 0

'さらなるコードの実行

End Sub

On Error Resume Next

On Error Resume Nextは、エラーを含むコード行をスキップして、次の行に進むようにVBAに指示します。

On Error Resume Next

注:On Error Resume Nextは、エラーを修正したり、解決したりするものではありません。これは、エラーを含むコード行が存在しないかのように処理を進めるようにVBAに指示するだけです。On Error Resume Nextの不適切な使用は、意図しない結果をもたらす可能性があります。

On Error Resume Nextを使うのに最適なのは、存在するかどうかわからないオブジェクトを扱うときです。例えば、ある図形を削除するコードを書きたいが、その図形がすでに削除されているときにそのコードを実行すると、VBAはエラーを投げることになります。代わりに、On Error Resume Nextを使用して、図形が存在する場合にそれを削除するように VBA に指示することができます。

On Error Resume Next
    ActiveSheet.Shapes("Start_Button").Delete
On Error GoTo 0

エラーの可能性があるコードの行の後にOn Error GoTo 0を追加していることに注意してください。これは、エラー処理をリセットするものです。 次のセクションでは、Err.Numberを使ってエラーが発生したかどうかをテストする方法を紹介し、より高度なエラー処理のオプションを提供します。

Err.Number、Err.Clear、そしてエラーの捕捉

エラーを含む行を単にスキップするのではなく、On Error Resume NextErr.Number を使用してエラーをキャッチすることができます。 Err.Numberは検出されたエラーの種類に対応するエラー番号を返します。エラーがない場合は、Err.Number= 0です。 例えば、このプロシージャでは、発生したエラーは実行時エラー’11‘なので、”11 “を返します。

Sub ErrorNumber_ex()

On Error Resume Next
ActiveCell.Value = 2 / 0
MsgBox Err.Number

End Sub

vba run-time error 11 err.number 実行時エラー

Err.Numberによるエラー処理

Err.Numberの真の威力は、エラーが発生したかどうか(Err.Number<> 0)を検出する能力にあります。 以下の例では、Err.Numberを使って、シートが存在するかどうかをテストする関数を作成しました。

Sub TestWS()
    MsgBox DoesWSExist("test")
End Sub
Function DoesWSExist(wsName As String) As Boolean
    Dim ws As Worksheet
    
    On Error Resume Next
    Set ws = Sheets(wsName)
    
    'エラーが発生すれば、そのワークシートは存在しない
    If Err.Number <> 0 Then
        DoesWSExist = False
    Else
        DoesWSExist = True
    End If

    On Error GoTo -1
End Function

注:最後にOn Error GoTo –1を追加し、Err.Numberを0にリセットしています(2つ下のセクションを参照ください)。 On Error Resume Nextと Err.Numberを使えば、他のプログラミング言語にある「Try」「Catch」機能を再現することができます。

On Error GoTo Line

On Error GoTo Lineは、エラーが発生したときに、ラベルの付いたコード行に「移動」するようにVBAに指示します。 Go Toステートメントは次のように宣言します。(errHandlerは移動先の行ラベルです。)

On Error GoTo errHandler

そして、次のような行ラベルを作成します。

errHandler:

注:これは、通常のVBAのGoToステートメントで使用するラベルと同じです。 以下では、On Error GoTo Lineを使ってプロシージャを終了させるデモを行います。

On Error Exit Sub

On Error GoTo Line を使って、エラーが発生したときにサブプロシージャを終了させることができます。 エラー処理用の行ラベルをプロシージャの末尾に配置することで実現できます。

Sub ErrGoToEnd()

On Error GoTo endProc

'あるコード
    
endProc:
End Sub

またはExit Subコマンドを使用します。

Sub ErrGoToEnd()

On Error GoTo endProc

'あるコード
GoTo skipExit
    
endProc:
Exit Sub
skipExit:

'その他のコード

End Sub

Err.Clear、On Error GoTo -1、およびErr.Numberのリセット

エラー処理後は、今後のエラー処理の問題を防ぐために、一般的にエラーをクリアする必要があります。

エラー発生後 Err.ClearOn Error GoTo -1の両方を使用してErr.Number を0 にリセットできますが、1つだけ非常に重要な違いがあります。Err.Clearは、実際のエラーそのものをリセットするのではなく、Err.Numberをリセットするだけです。

どういうことでしょうか? Err.Clearを使用すると、エラー処理の設定を変更することができなくなります。この違いを見るには、このコードをテストして、On Error GoTo -1Err.Clear に置き換えてみてください。

Sub ErrExamples()

    On Error GoTo errHandler:
        
    '「型が一致しません」エラー
    Error(13)
    
Exit Sub
errHandler:
    ' エラーをクリアする
    On Error GoTo -1
    
    On Error GoTo errHandler2:
    
    '「アプリケーション定義またはオブジェクト定義の」エラー
    Error(1034)
    
Exit Sub
errHandler2:
    Debug.Print Err.Description
End Sub

通常、Err.Clearを使用する正当な理由がない限り、On Error GoTo -1 を常に使用することをお勧めします。

VBAエラー時のMsgBox

また、エラー時にメッセージボックスを表示させたい場合もあります。 この例では、エラーが発生した場所によって、異なるメッセージボックスを表示します。

Sub ErrorMessageEx()
 
Dim errMsg As String
On Error GoTo errHandler

    'ステージ1
    errMsg = "コピー&ペーストステージでエラーが発生しました。"
    'Err.Raise (11)
    
    'ステージ2
    errMsg = "データ検証ステージでエラーが発生しました。"
    'Err.Raise (11)
     
    'ステージ3
    errMsg = "損益計算書作成および上書きコピーステージでエラーが発生しました。"
    Err.Raise (11)
     
    'ステージ4
    errMsg = "セットアップページでインポートを記録しようとしたときにエラーが発生しました。"
    'Err.Raise (11)

    GoTo endProc
    
errHandler:
    MsgBox errMsg
   
endProc:
End Sub

ここでは、Err.Raise (11)を実際のコードに置き換えます。

VBA IsError

エラーを処理するもう一つの方法は、VBAのISERROR関数を使ってエラーをテストすることです。ISERROR関数は、式にエラーがあるかどうかをテストし、エラーが発生した場合はTRUEまたはFALSEを返します。

Sub IsErrorEx()
    MsgBox IsError(Range("a7").Value)
End Sub

If Error VBA

ExcelのIFERROR関数を使ってエラーを処理することもできます。 IFERROR関数には、WorksheetFunctionクラスを使ってアクセスする必要があります。

Sub IfErrorEx()

Dim n As Long
n = WorksheetFunction.IfError(Range("a10").Value, 0)

MsgBox n
End Sub

これは、セルA10の値を出力し、値がエラーの場合は、代わりに0を出力します。

VBAのエラーの種類

実行時エラー

上記の通りです。 VBA実行時エラーとは、コードの実行中に発生するエラーのことです。実行時エラーの例としては、以下のようなものがあります。

  • 存在しないワークブック、ワークシート、またはその他のオブジェクトを参照している
  • 無効なデータ、例えばエラーを含むExcelのセルを参照した場合
  • ゼロで割ろうとする

vba runtime error 13 実行時エラー

実行時エラーを「エラー処理」するには、前述した方法を使用します。

シンタックスエラー

VBA Syntax Errorsは、コードの記述に伴うエラーです。シンタックスエラーの例としては、以下のようなものがあります。

  • 誤字脱字
  • 句読点の欠落または不正確な句読点

VBAエディタは、多くの構文エラーを赤いハイライトで識別します。

vba syntax error example 構文エラー

VBA Editorには、「Auto Syntax Check」というオプションもあります。

vba syntax error option 構文エラー

これをチェックすると、コード入力後に構文エラーを警告するメッセージボックスが生成されます。

vba syntax compile error コンパイルエラー

個人的には非常に煩わしいので、この機能は無効にしています。

コンパイルエラー

プロシージャを実行しようとする前に、VBAはそのプロシージャを「コンパイル」します。コンパイルは、プログラムをソースコード(目に見えるもの)から実行形式(目に見えないもの)に変換するものです。 VBAのコンパイルエラーは、コードがコンパイルできないエラーです。

コンパイルエラーの典型的な例は、変数宣言の欠落です。

vba compile error コンパイルエラー

vba compile error variable コンパイルエラー

その他にも、以下のような例があります。

  • Forに対してNextがない
  • Selectに対してEnd Selectがない
  • Ifに対してEnd Ifがない
  • 存在しないプロシージャを呼び出している

vba compile error example コンパイルエラー

シンタックスエラー(前項)は、コンパイルエラーのサブセットです。

デバッグ > コンパイル

コンパイルエラーは、プロシージャを実行しようとしたときに表示されます。しかし、理想的には、プロシージャを実行しようとする前に、コンパイルエラーを確認することです。 これは、前もってプロジェクトをコンパイルしておくことで可能です。これを行うには、[デバッグ] > [VBAプロジェクトをコンパイル]を選択します。

vba debug compile デバッグ コンパイル

コンパイラは、最初のエラーに “Go to”します。そのエラーを修正したら、プロジェクトを再度コンパイルします。すべてのエラーが修正されるまで、これを繰り返してください。 VBAプロジェクトのコンパイルがグレーアウトするので、すべてのエラーが修正されたことが分かります。 vba compile vbaproject コンパイル デバッグ

オーバーフローエラー

VBAのオーバーフローエラーは、大きすぎる値を変数に入れようとしたときに発生します。例えば、整数型変数には、-32,768から32,767までの値しか入れることができません。それ以上の値を入力すると、オーバーフローエラーになります。

vba overflow error オーバーフロー エラー

この場合、Long型変数を使用して大きな数値を格納する必要があります。

その他のVBAエラー用語

VBA キャッチエラー

他のプログラミング言語と異なり、VBAにはCatchステートメントがありません。しかし、On Error Resume Nextや If Err.Number <> 0 Thenを使えば、Catchステートメントを再現することができます。これについては、「Err.Numberを使ったエラー処理」で説明しています。

VBA エラーを無視する

VBAでエラーを無視するには、単純に On Error Resume Nextステートメントを使用します。

On Error Resume Next

ただし、前述のとおり、この文はエラーを修正するものではなく、エラーを含むコード行を単に無視するだけなので、使用には注意が必要です。

VBA Throw Error / Err.Raise

VBAでエラーを処理するには、Err.Raiseメソッドを使用します。 このコードの行は、「実行時エラー’13’: 型が一致しません」を発生させます。

Err.Raise (13)

vba runtime error 13 実行時エラー

VBAエラートラッピング

VBAエラートラッピングはVBAエラー処理の別名です。

VBAのエラーメッセージ

VBAのエラーメッセージは次のようなものです。

vba runtime error 13 実行時エラー

「デバッグ」をクリックすると、エラーを発生させているコードの行が表示されます。

vba raise error エラー

VBA ループ内のエラー処理

ループ内でエラー処理を行うには、On Error Resume NextErr.Numberを使ってエラーが発生したかどうかを検出します(エラーが発生するたびにErr.Clear を使ってエラーをクリアすることを忘れないでください)。

以下の例では、2つの数値(A列とB列)を割ってC列に結果を出力しています。

Sub test()
Dim cell As Range

On Error Resume Next
For Each cell In Range("a1:a10")

    'セルの値を設定する
    cell.Offset(0、2).Value = cell.Value / cell.Offset(0, 1).Value
    
    'Cell.ValueがErrorの場合、0をデフォルトとする
    If Err.Number <> 0 Then
         cell.Offset(0, 2).Value = 0
         Err.Clear
    End If
Next
End Sub

AccessのVBAエラー処理

上記の例はすべて、Access VBAでもExcel VBAとまったく同じように動作します。

Function DelRecord(frm As Form)
'この関数は、フォームからテーブルのレコードを削除するために使用される
   On Error GoTo ending
   With frm
      If .NewRecord Then
         .Undo
         Exit Function
      End If
   End With
   With frm.RecordsetClone
      .Bookmark = frm.Bookmark
      .Delete
      frm.Requery
   End WIth
   Exit Function
   ending:
   End
End Function

vba-free-addin

VBA Code Examples Add-in

Easily access all of the code examples found on our site.

Simply navigate to the menu, click, and the code will be inserted directly into your module. .xlam add-in.

(No installation required!)

Free Download

Return to VBA Code Examples