見出し画像

VBAでエラーを無視する方法

概要

VBA(Visual Basic for Applications)などのプログラミングでは、エラーが度々生じます。中でも無視したいエラーも多数あるかと思います。
VBAには、On Error ステートメントを使用してエラー処理を行うためのいくつかの方法があります。以下に、どのようなエラーが存在するのかや、基本的なVBAのエラー処理の手法などについていくつか紹介していきます。


VBAのエラーについて

一般的なVBAのエラーには、次のようなものがあります。

構文エラー

構文エラーは、VBAコードの文法が正しくない場合に発生します。つまり、VBAがコードを解釈できない形式で書かれた場合に発生します。構文エラーは、コンパイル時に検出され、コードを実行する前に修正する必要があります。

構文エラーの一般的な原因には以下が含まれます:

括弧やクオーテーションの不足:コード内で開き括弧 ( が閉じられていない場合や、文字列がクオーテーションで囲まれていない場合が該当します。

' 括弧が閉じられていない
If x > 0 Then
    ' 何らかの処理
End If

不正なキーワードの使用:VBAでは予約されたキーワードや関数名を適切に使用しなければなりません。また、スペルミスも含まれます。

' 間違ったキーワード
Forr i = 1 To 10
    ' 何らかの処理
Next i

変数やオブジェクトの宣言の不足:変数やオブジェクトを使用する前に、それらを宣言していない場合に発生します。

' 変数が宣言されていない
Sub Example()
    x = 10
    ' 何らかの処理
End Sub

インデントの不一致:コード内のインデントが一貫していない場合、VBAは構文エラーを発生させることがあります。

' インデントが不一致
Sub Example()
If x > 0 Then
    ' 何らかの処理
End Sub

実行時エラー

実行時エラーは、VBAコードが実行される際に発生するエラーです。コンパイル時の構文エラーとは異なり、実行時エラーはコードの文法的な正しさではなく、実行時の状況に関連する問題に起因します。以下は、実行時エラーの一般的な原因とその例です:

ゼロでの割り算:ゼロで割るという操作は定義されていないため、ランタイムエラーが発生します。

Sub Example()
    Dim x As Integer
    Dim y As Integer

    x = 10
    y = 0

    Debug.Print x / y  ' ゼロでの割り算
End Sub

存在しないオブジェクトにアクセス:存在しないオブジェクトにアクセスしようとすると、オブジェクト参照エラーが発生します。

Sub Example()
    Dim ws As Worksheet
    Set ws = Worksheets("Sheet2")  ' 存在しないワークシートにアクセス
End Sub

配列の範囲外アクセス:配列のインデックスが範囲外の場合、ランタイムエラーが発生します。

Sub Example()
    Dim arr(1 To 3) As Integer
    Debug.Print arr(4)  ' 配列の範囲外にアクセス
End Sub

オブジェクトの解放後にアクセス:解放されたオブジェクトに再度アクセスしようとすると、オブジェクト参照エラーが発生します。

Sub Example()
    Dim ws As Worksheet
    Set ws = Worksheets("Sheet1")
    Set ws = Nothing

    Debug.Print ws.Name  ' 解放されたオブジェクトにアクセス
End Sub

オブジェクト参照エラー

オブジェクト参照エラーは、VBAでプログラムが実行されている際に、存在しないオブジェクトにアクセスしようとしたときに発生します。これは、オブジェクトが存在しない、またはすでに解放されている場合に発生します。以下は、オブジェクト参照エラーの一般的な原因と例です

存在しないオブジェクトへのアクセス:存在しないオブジェクトにアクセスしようとすると、エラーが発生します。たとえば、存在しないワークシートや存在しないオブジェクトへの参照が該当します。

Sub Example()
    Dim ws As Worksheet
    Set ws = Worksheets("Sheet2")  ' 存在しないワークシートにアクセス
End Sub

オブジェクトが解放された後のアクセス:オブジェクトが解放(Nothingに設定)された後に、そのオブジェクトへのアクセスが試みられると、オブジェクト参照エラーが発生します。

Sub Example()
    Dim ws As Worksheet
    Set ws = Worksheets("Sheet1")
    Set ws = Nothing  ' オブジェクトを解放

    Debug.Print ws.Name  ' 解放されたオブジェクトにアクセス
End Sub

ランタイムエラー

ランタイムエラーは、VBAコードが実行されている際に発生するエラーで、コンパイル時には検出されないエラーです。つまり、コードの文法的な正しさはある程度保証されている状態で、実際にコードが実行される際に問題が発生した場合に発生します。以下は、ランタイムエラーの一般的な原因と例です:

ゼロでの割り算:ゼロで割ることはできません。ゼロで割る操作が含まれている場合に発生します。

Sub Example()
    Dim x As Integer
    Dim y As Integer

    x = 10
    y = 0

    Debug.Print x / y  ' ゼロでの割り算
End Sub

存在しないオブジェクトにアクセス:存在しないオブジェクトにアクセスしようとすると、ランタイムエラーが発生します。

Sub Example()
    Dim ws As Worksheet
    Set ws = Worksheets("Sheet2")  ' 存在しないワークシートにアクセス
End Sub

配列の範囲外アクセス:配列のインデックスが範囲外の場合、ランタイムエラーが発生します。

Sub Example()
    Dim arr(1 To 3) As Integer
    Debug.Print arr(4)  ' 配列の範囲外にアクセス
End Sub

オブジェクトの解放後にアクセス:解放されたオブジェクトに再度アクセスしようとすると、ランタイムエラーが発生します。

Sub Example()
    Dim ws As Worksheet
    Set ws = Worksheets("Sheet1")
    Set ws = Nothing

    Debug.Print ws.Name  ' 解放されたオブジェクトにアクセス
End Sub

エラー処理には大きく2種類

On Error Resume Next

これは、エラーが発生した場合に処理を継続させる方法です。エラーが発生すると、実行はエラーの発生地点から次の行に進みます。

On Error Resume Next

' エラーが発生する可能性のあるコード

' エラー処理後に実行されるコード

この方法はエラーを無視することになりますが、エラーの有無を確認することはできます。(エラー有無を確認する方法は下記)

On Error GoTo ラベル

これは、エラーが発生した場合に指定したラベルにジャンプする方法です。ラベルはエラー処理のための特別なサブルーチンまたは関数の開始地点です。

On Error GoTo ErrorHandler

' エラーが発生する可能性のあるコード

' エラー処理後に実行されるコード

Exit Sub  ' エラーが発生しなかった場合、エラー処理をスキップ

ErrorHandler:
' エラー処理のコード

エラーに対してアクションを起こす

上記のエラー構文はともにエラー発生箇所を無視または飛ばす処理です。
そのため、デメリットとして何が起こったのかわかりません。
Errオブジェクトを活用することでどこでエラーが起きたのかを参照することができます。コードを記述するときは大変面倒ではありますが、このような細かい作業を事前にしておくと、あとあとデバック作業が楽になります。

Err オブジェクト

Err オブジェクトは、エラーに関する情報を提供します。エラー番号、説明、発生した行などが含まれます。

On Error Resume Next

' エラーが発生する可能性のあるコード

If Err.Number <> 0 Then
    MsgBox "エラーが発生しました: " & Err.Description
    Err.Clear  ' エラー情報をクリア
End If

エラー0は「エラーなし」または「正常終了」を表します。つまり、Err.Numberが0の場合は、直前の処理がエラーなく正常に完了したことを示します。通常、エラーが発生しなかったときにErr.Numberが0になります。

エラーコードの意味

VBAのErr.Numberに関連するエラーコードには、様々なものがあります。一いくつかのエラーコードとその意味を紹介します。

エラー 1: Division by zero

Err.Numberが1の場合、ゼロで割り算が行われたことを示します。

"Division by zero"(ゼロでの割り算)エラーは、数学的に不可能な操作であるゼロでの割り算が試みられたときに発生します。プログラムが実行されている際に、0で割り算を行う操作が含まれている場合にこのエラーが発生します。VBAでは、このような操作を許可せず、エラーが発生します。

以下は、ゼロでの割り算エラーの一般的な例です:

Sub Example()
    Dim x As Integer
    Dim y As Integer

    x = 10
    y = 0

    Debug.Print x / y  ' ゼロでの割り算
End Sub

このコードでは、変数 y に0が代入されています。その後、 x / y の操作で y が0で割られています。これは数学的に不可能な操作であり、VBAはこの操作に対して "Division by zero" エラーを発生させます。

このエラーを回避するためには、ゼロでの割り算が発生しないようにプログラムを設計する必要があります。たとえば、0で割り算を行う前に y の値が0でないかを確認し、条件分岐を使ってエラーを回避することができます。また、必要に応じてエラー処理を実装して、エラーが発生した場合に適切に対処することも重要ですね。

エラー 5: Invalid procedure call or argument

Err.Numberが5の場合、関数やプロシージャの呼び出しに無効な引数が含まれていることを示します。

"Invalid procedure call or argument"(無効な手続き呼び出しまたは引数)エラーは、VBAで使用された手続きが無効な引数を受け取った場合や、無効な手続きが呼び出された場合に発生します。つまり、関数やサブルーチンが正しく呼び出されていないか、または与えられた引数が無効な値である場合にこのエラーが発生します。

このエラーの一般的な原因としては、以下のようなものがあります:

無効な引数の渡し方:関数やサブルーチンに対して、その定義と異なる数や型の引数を渡す場合に発生します。

Sub Example()
    Dim result As Double
    result = CalculateSquareRoot("abc")  ' 文字列を引数として渡す
End Sub

Function CalculateSquareRoot(ByVal x As Double) As Double
    CalculateSquareRoot = Sqr(x)
End Function

存在しない関数やサブルーチンの呼び出し:存在しない関数やサブルーチンを呼び出すと、このエラーが発生します。

Sub Example()
    Call NonExistentSub()  ' 存在しないサブルーチンを呼び出す
End Sub

オブジェクトのメソッドを使用する際の無効な呼び出し:オブジェクトのメソッドを無効な方法で呼び出すと、このエラーが発生します。

Sub Example()
    Dim ws As Worksheet
    Set ws = Worksheets("Sheet1")
    ws.PrintOut Copies:=5, Collate:=True  ' 存在しないプロパティを使用する
End Sub

このエラーを解決するためには、コードを検証し、関数やサブルーチンの呼び出し方や引数の渡し方が正しいか確認してください。また、存在しない関数やサブルーチンを呼び出していないか、またはオブジェクトのメソッドを正しく使用しているかも確認してください。デバッグやエラー処理を行って、問題を特定し、修正することが重要です。

エラー 7: Out of memory

Err.Numberが7の場合、メモリ不足により操作を完了できないことを示します。

"Out of memory"(メモリ不足)エラーは、VBAが使用しようとしているメモリがシステムの利用可能なメモリ量を超えている場合に発生します。つまり、プログラムが必要なメモリを確保できないために発生します。
このエラーの一般的な原因としては、次のようなものが考えられます:

  1. 大量のデータの処理:プログラムが大きなデータセットを処理しようとしている場合や、大量のメモリを必要とする計算を実行しようとしている場合に、メモリ不足エラーが発生することがあります。

  2. 無限ループ:無限ループが発生し、メモリを無駄に消費している場合に、メモリ不足エラーが発生することがあります。

  3. 再帰関数の深さ:再帰関数が深い再帰を行っている場合、スタックメモリが消費され、メモリ不足エラーが発生することがあります。

  4. オブジェクトの解放を怠る:オブジェクトが解放されず、メモリリークが発生している場合に、メモリ不足エラーが発生することがあります。

  5. 他のアプリケーションが大量のメモリを消費している:同時に実行されている他のアプリケーションが大量のメモリを消費しており、VBAが必要なメモリを確保できない場合に、メモリ不足エラーが発生することがあります。

メモリ不足エラーに対する対策は例えば下記のようなものです。

  • メモリの使用量を最適化する。

  • 不要なデータを削除する。

  • メモリを効率的に利用するアルゴリズムを使用する。

  • 再帰関数の深さを減らす。

  • オブジェクトの解放を適切に行う。

  • システム全体でのメモリ使用量を監視し、必要に応じて他のプロセスを終了する。

エラー 9: Subscript out of range

Err.Numberが9の場合、配列の境界外にアクセスしようとしたことを示します。

"Subscript out of range"(範囲外のサブスクリプト)エラーは、VBAで配列やコレクションの範囲外にアクセスしようとしたときに発生します。具体的には、配列やコレクションのインデックスがその範囲を超えている場合にこのエラーが発生します。

このエラーの一般的な原因としては、次のようなものが考えられます:

配列の範囲外アクセス:配列のインデックスがその定義された範囲を超えている場合に発生します。

Sub Example()
    Dim arr(1 To 3) As Integer
    Debug.Print arr(4)  ' 配列の範囲外にアクセス
End Sub

コレクションの範囲外アクセス:コレクション内の項目が存在しないインデックスにアクセスしようとした場合に発生します。

Sub Example()
    Dim ws As Worksheet
    Set ws = Worksheets("Sheet5")
    Debug.Print ws.Cells(6, 1).Value  ' 存在しない行にアクセス
End Sub

オブジェクトが存在しない場合の参照:オブジェクトが存在しない場合に、そのオブジェクトにアクセスしようとした場合に発生します。

Sub Example()
    Dim ws As Worksheet
    Set ws = Worksheets("Sheet5")  ' 存在しないワークシートにアクセス
End Sub

このエラーを解決するためには、コードを検証し、配列やコレクションへのアクセスがその範囲内に収まるように確認してください。また、オブジェクトが存在するかどうかを事前に確認してからアクセスすることも重要です。デバッグやエラー処理を行って、問題を特定し、修正することが重要です。

エラー 13: Type mismatch

Err.Numberが13の場合、データ型が予期しない方法で一致しないことを示します。

"Type mismatch"(型の不一致)エラーは、VBAで変数や式が予期しない型である場合に発生します。つまり、変数や式が期待される型と異なる型である場合にこのエラーが発生します。

このエラーの一般的な原因としては、次のようなものが考えられます:

異なるデータ型の変数間での代入:異なるデータ型の変数間での代入が行われた場合に発生します。

Sub Example()
    Dim x As Integer
    Dim y As String

    x = "Hello"  ' 文字列を整数型の変数に代入
End Sub

関数や演算子に対して不正な型の引数を渡した場合:関数や演算子に対して、その定義された型と異なる型の引数を渡した場合に発生します。

Sub Example()
    Dim x As Integer
    Dim y As String

    x = Mid(y, 1, 2)  ' 文字列型の引数が期待されているが、整数型の変数を渡す
End Sub

コンパイル時に型が不明確な変数を使用する場合:コンパイル時に型が不明確な変数を使用する場合、実行時に型の不一致エラーが発生することがあります。

Sub Example()
    Dim x
    x = "Hello"
    Debug.Print x + 10  ' 文字列と整数の演算が行われる
End Sub

このエラーを解決するためには、変数や式が期待される型と一致するように確認してください。適切な型の変数を使用し、関数や演算子に適切な型の引数を渡すことが重要です。また、コンパイル時に型が不明確な変数を使用しないようにすることも重要です。デバッグやエラー処理を行って、問題を特定し、修正することが重要です。

エラー 53: File not found

Err.Numberが53の場合、指定されたファイルが見つからなかったことを示します。

"File not found"(ファイルが見つかりません)エラーは、VBAが指定されたファイルを見つけることができなかった場合に発生します。これは、ファイルパスが正しくない、または指定されたファイルが存在しない場合に発生します。
このエラーの一般的な原因としては、次のようなものが考えられます:

誤ったファイルパス:ファイルパスが正しくない場合、VBAはファイルを見つけることができず、エラーが発生します。

Sub Example()
    Dim filePath As String
    filePath = "C:\Users\Example\File.txt"  ' 存在しないファイルパス
    Open filePath For Input As #1 
End Sub

指定されたファイルが存在しない:指定されたファイルが存在しない場合、VBAはファイルを見つけることができず、エラーが発生します。

Sub Example()
    Dim filePath As String
    filePath = "C:\Users\Example\File.txt"  ' 存在しないファイル
    Open filePath For Input As #1 
End Sub

このエラーを解決するためには、正しいファイルパスを指定し、ファイルが存在することを確認してください。ファイルパスが正しい場合でもエラーが発生する場合は、ファイルにアクセスできる権限があるかどうかも確認してください。また、ファイルが存在することを確認するために、ファイルエクスプローラーなどのツールを使用することもできます。デバッグやエラー処理を行って、問題を特定し、修正することが重要です。

まとめ

On Error ステートメントやErr オブジェクトを巧みに使用することで、エラーが発生しても対処できます。
具体的なエラーコードには、ファイルが見つからないことを示すエラー2や、ゼロで割り算が行われたことを示すエラー1などがあります。
これらの知識を活用することで、プログラム開発の品質向上に役立てることに繋がりますので是非参考にしていただけましたらとおもいます。

この記事が参加している募集

仕事について話そう

この記事が気に入ったらサポートをしてみませんか?