VBA入門
Errオブジェクトとユーザー定義エラー

ExcelマクロVBAの基本と応用、エクセルVBAの初級・初心者向け解説
最終更新日:2022-08-09

第134回.Errオブジェクトとユーザー定義エラー


VBA実行時には種々のエラーが発生します。


実行時エラーに関する情報は、Errオブジェクトに入っていますので、
VBA実行でエラー発生した場合は、Errオブジェクトを参照しエラー内容を調べることになります。

Errオブジェクトの使い方と、ユーザー定義エラーの生成方法について解説します。


目次

Errオブジェクト

実行時エラーに関する情報はErrオブジェクトに入っています。
VBA実行でエラーが発生すると、Errオブジェクトのプロパティにはエラーに関する情報が設定されます。

Errオブジェクトは、グローバルなスコープの組み込みオブジェクトです。
VBAコード内にそのインスタンスを作成する必要はありません。

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

プロパティ 説明
Clear Errオブジェクトのプロパティ設定をすべて解除します。
Raise 実行時エラーを生成します。

これらのメソッドについては、後のセクションで詳しく説明します。


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

メソッド 説明
Description エラーに関連付けられている説明の文字列を取得または設定します。
HelpContext ヘルプファイルのトピックに対応するコンテキストIDを含む文字列式を返すか設定します。
HelpFile ヘルプファイルへの完全修飾パスを含む文字列式を設定または返します。
Number エラーを示す数値を取得または設定します。
Numberは、Errオブジェクトの既定のプロパティです。
Source 最初にエラーを生成したオブジェクトまたはアプリケーションの名前を指定する文字列式を取得または設定します。

DescriptionとNumber以外は使う事はないでしょう。


VBA実行エラー時のErrオブジェクトの基本的な使い方

Cells(0, 0) = 1

このVBAを実行すると、以下のエラーが表示されます。

マクロ VBA エラー Errオブジェクト

ここで「デバッグ」をクリックし、イミディエイト ウインドウで、

?Err.Number
?Err.Description

マクロ VBA エラー Errオブジェクト

エラー発生時に、エラー番号とエラーの説明を見ることができます。

On Errorを使う事で、エラーを捕捉しエラー情報をVBAで使う事が出来ます。

On Error Resume Next
Cells(0, 0) = 1
Debug.Print Err.Number
Debug.Print Err.Description

このVBAを実行すると、イミディエイト ウインドウに以下が出力されます。

マクロ VBA エラー Errオブジェクト


Errオブジェクト既定のNumberプロパティ

Errオブジェクトの既定のプロパティはNumberです。
エラー未発生の状態は0です。
つまり、エラー発生時には0以外の値が設定されています。

If Err.Number <> 0 Then
  MsgBox "エラー"
End If

Numberは既定のプロパティなので省略可能です。

If Err <> 0 Then
  MsgBox "エラー"
End If

さらに論理値の判定は、0がFalseで、0以外はTrue
したがって、エラーかどうかの判定だけであれば、以下の記述で判定が可能です。

If Err Then
  MsgBox "エラー"
End If


Errオブジェクトのエラー情報が解除されるのは

Errオブジェクトのエラー情報は、以下により解除(リセット)されます。

On Error Goto 0 が実行されたとき
現在のプロシージャで有効なすべてのエラー ハンドラーが無効になり、Errオブジェクトはリセットされます。

On Error Resume Nextが実行されたとき
On Error GoTo ラベル が実行されたとき
新たにエラー処理ルーチンが有効になり、Errオブジェクトはリセットされます。

ErrオブジェクトのClearメソッドが実行されたとき
Errオブジェクトのプロパティ設定をすべて解除します。
現在のプロシージャで有効なエラー ハンドラーは引き続き有効です。


プロシージャーを抜けるときは、明示的にErrオブジェクトをクリアしてください。

On Error が有効なのは当該プロシージャー内だけです。
呼出元には、On Error の処理は引き継がれません。
ただし、Errオブジェクトのプロパティは残ったままとなります。
On Error を記述したプロシージャーを抜ける場合は、プロシージャー内で発生したエラー情報をクリアしておくようにしてください。
具体的には、
On Error Goto 0
Err.Clear
どちらかをプロシージャーを抜ける前に実行します。
On Error を記述したプロシージャーが他から呼ばれている場合、
呼び出し元のエラー処理に影響を与えないようにエラー情報をリセットしておいた方が良いと言う事です。

Errオブジェクトのエラー情報解除の使用例

Sub Clearの使用例()
  Dim i As Long
  On Error Resume Next
  For i = 2 To 10
    Cells(i, 2) = WorksheetFunction.VLookup(Cells(i, 1), Range("D:F"), 2, 0)
    If Err.Number <> 0 Then
      Cells(i, 2) = "検索値なし"
      Err.Clear
    End If
  Next
End Sub

Errオブジェクトのエラー情報は、上述したとき以外はその情報が保持されます。
上記VBAでErr.Clearがないと、
1度エラーが発生すると、そのままではエラー情報が残ったままになってしまいます。
つまり、一度でもVlookupの検索値が無い行が存在すると、それ以降は全て"検索値なし"となってしますます。
このVBAは、以下のように、On Error Resume Nextだけで記述することもできます。

Sub ResumeNextの使用例()
  Dim i As Long
  For i = 2 To 10
    On Error Resume Next
    Cells(i, 2) = WorksheetFunction.VLookup(Cells(i, 1), Range("D:F"), 2, 0)
    If Err.Number <> 0 Then
      Cells(i, 2) = "検索値なし"
      Err.Clear
    End If
  Next
End Sub

Forループの先頭でOn Error Resume Nextしているので、ここでErrオブジェクトがリセットされています。


On Error GoTo の注意点

On Error GoTo は、1度エラー発生した後はエラー処理が無効になり、その後のエラーをトラップすることが出来なくなります。
On Errorが記述されているプロシージャーが終了した後は、新たなエラー処理が有効になります。
ただし、Errオブジェクトの情報はそのまま残ります。

Sub GoToの使用例3()
  Dim i As Long
  For i = 2 To 10
    On Error GoTo ErrLabel
    Cells(i, 2) = WorksheetFunction.VLookup(Cells(i, 1), Range("D:F"), 2, 0)
  Next
  Exit Sub
ErrLabel:
  'エラー情報を使った処理
  On Error Resume Next
  'ここでエラーが発生するとVBAは停止します
  MsgBox "検索値なし"
End Sub

On Error Resume Nextの実行でErrオブジェクトはリセットされますが、
On Error GoTo のエラー処理ルーチンに進んだ後は次に発生するエラーを補足できません。
従って上記において、ErrLabel:の中でエラーが発生するとVBAは停止します。
エラー処理ルーチン(エラーでGoToした先)内ではエラー発生させないようにしてください。

On Error GoTo ラベル でループ内に戻るような記述は使用しない
Sub sample()
  Dim i, j
  For i = 1 To 100
L01:
    On Error GoTo L02
    j = i / 0
L02:
    GoTo L01
  Next
End Sub

極めて単純化した例になりますが、
一見すると、上記VBAは永久ループしそうに見えますが、このVBAはエラー停止します。
On Error GoTo は、1度エラー発生した後はエラー処理が無効になります。
したがって、2度目のエラーは補足されません。

On Error GoTo でエラー発生した後に再度エラー処理を有効にするには
On Error GoTo -1
これを実行することで、再度エラー処理を有効にする事が出来ます。

Sub GoToの使用例3()
  Dim i As Long
  For i = 2 To 10
    On Error GoTo ErrLabel
    Cells(i, 2) = WorksheetFunction.VLookup(Cells(i, 1), Range("D:F"), 2, 0)
  Next
  Exit Sub
ErrLabel:
  'エラー情報を使った処理
  On Error GoTo -1
  On Error Resume Next
  'エラーの可能性がある処理
  MsgBox "検索値なし"
End Sub

On Error GoTo -1
その前までに発生したOn Error GoToのエラー処理を無効にします。
これにより、新たなエラー処理を行う事が出来ます。
上記では、新たにOn Error Resume Nextを入れています。

※ただしこのOn Error GoTo -1は、VBとして存在していてVBAでも使用できますが、
VBAとして正式なドキュメントが見当たらない(どこかにあるかもしれませんが)ので、あまり使用しないようにしてください。

基本的には、エラー処理ルーチンではエラー発生しないようにVBAを記述します。
出来れば、On Error Resume Nextだけを使用してVBAを作成したほうが良いでしょう。

以下のページも参考にしてください。
VBA穴埋め問題「On Error GoToの挙動」
・出題ツイート ・正解発表 ・出題者としての解答 ・サイト内の参考ページ


Err.Raiseメソッド

ErrオブジェクトのRaiseメソッドは、ユーザー定義エラーとして実行時エラーを生成します。

Err.Raise number, source, description, helpfile, helpcontext

引数 説明
number 必須。
エラーの性質を識別する長整数型、0-65535の値を使用します。
範囲外の数値を指定した場合はRaiseメソッドがエラーとなります。
0-512 の値はシステム エラー用に予約されています。
513-65535 の値は、ユーザー定義エラー用に使用できます。

クラス モジュール内で独自のエラーコードを設定する場合は、エラーコード番号をvbObjectError定数に加えます。
例えば、 エラー番号513を生成するには、vbObjectError + 513を設定します。
source 省略可能。
エラーを生成したオブジェクトまたはアプリケーションの名前を示す文字列式です。
description 省略可能。
エラーを説明する文字列式です。
指定しない場合、Numberの値が調べられ対応するメッセージが使われます。
Numberに対応するVBAエラーがない場合、"アプリケーション定義またはオブジェクト定義のエラーです。"が使用されます。
helpfile 省略可能。
このエラーに関するヘルプを確認できるヘルプ ファイルへの完全修飾パスです。
指定しない場合、VBAのヘルプ ファイルのドライブ、パス、およびファイル名が使用されます。
helpcontext 省略可能。
エラーに関するヘルプを提供するhelpfile内のトピックを識別するコンテキスト ID です。
省略した場合、Numberプロパティに対応するエラーに応じた、VBAヘルプ ファイルのコンテキスト ID が使用されます。

Err.Raiseの使用例
以下では、On Errorがない場合に表示されるメッセージを掲載しています。

Descriptionを省略
Err.Raise 513

マクロ VBA エラー Err.Clear

Descriptionが未指定かつNumberに対応するVBAエラーがないので、"アプリケーション定義またはオブジェクト定義のエラーです。"となります。

Descriptionを指定
Err.Raise Number:=513, Description:="ユーザー定義エラーです"

マクロ VBA エラー Err.Clear

指定したNumberが、VBA実行エラーコードにある場合は、そのDescriptionが表示されます。

システム予約のエラー番号を使用
Err.Raise 6

マクロ VBA エラー Err.Clear

システム予約されているエラー番号、かつ、descriptionを省略しているので、
システムで定義されたメッセージになります。


Errorステートメント

エラーの発生をシミュレートします。

Error エラー番号

通常はErr.Raiseを使用する為、このErrorステートメントを使用することはほぼありません。

Err.Raise 513

Error 513

この2つのVBAは、結果としては同じになります。
Errorステートメントは、Number以外を指定できない為、
使用用途としては、VBAに用意されたエラーをシミュレーション目的で発生させる場合に使う事になります。


Error関数

指定したエラー番号に対応するエラー メッセージを返します。

Error [ (errornumber) ]

errornumber引数は省略可能です。
errornumberを省略した場合は、最後に発生した実行時エラーに対応するメッセージが返されます。

任意の有効なエラー番号を指定できます。
errornumberが有効でない場合(65536以上)はエラーが発生します。

定義されていないerrornumberの場合は、"アプリケーション定義またはオブジェクト定義のエラーです。"が返されます。
実行時エラーが発生していない場合、またはerrornumberが0の場合は、長さ0の文字列("")が返されます。

Debug.Print Error(13)

この結果は、イミディエイト ウィンドウに、
「型が一致しません。」
このように出力されます。


CVErr関数

CVErr関数は、指定した数値(エラー番号)を、バリアント型のエラー値に変換した値を返す変換関数です。

CVErr(errornumber)

CVErr 関数を使用して、作成したプロシージャ内でユーザー定義のエラーを作成できます。
CVErr 関数を使用することにより、どのような動作が行われたのかを知らせるエラー番号を返すことができます。
たとえば、CVErr 関数の戻り値をバリアント型以外の変数に直接代入することはできません。

詳細および使用例については以下を参照してください。
CVErr関数|VBA関数
・CVErr関数 ・CVErr関数の使用例 ・実行時エラー関連記事 ・データ型変換関数一覧


エラー番号およびエラーメッセージ

マクロVBA実行時に発生するエラーの番号とエラーメッセージおよび簡単な理由と対策については以下を参照してください。

実行時にトラップ可能なエラー番号一覧
・マクロVBAでのエラーとは ・VBA実行時のエラー番号一覧 ・実行時にトラップ可能なエラー番号一覧の最後に

以下は、VBAのシステムエラー番号とメッセージの一覧を簡易的に取得するVBAです。

Sub ErrList()
  Dim i As Long
  On Error Resume Next
  For i = 1 To 65535
    Error i
    Cells(i + 1, 1) = i
    Cells(i + 1, 2) = Err.Description
  Next
End Sub

これを実行すると、アクティブシートの2行目からエラーの一覧が出力されます。
出力された一覧を見ると、

735 一時ファイルに保存できません。
744 検索文字列が見つかりませんでした。
746 置換後の文字列が長すぎます。

このように513以降にも定義済のエラーが存在してるのが見て取れます。
実際にこれらがどのように使われているかは不明です。
また、
VBA実行では、この出力した一覧にないエラーも存在します。

Cells(0, 0) = 123

これを実行すると、以下のエラーが表示されます。
このエラーは、VBAにおいてはかなり頻繁に発生するものですが、上記では取得されません。

マクロ VBA エラー Err.Raise

したがって、
「513-65535 の値は、ユーザー定義エラー用に使用できます。」
となっていますが、実際には、上で紹介したエラー番号は避けたほうが良いでしょう。
ユーザー定義のエラー番号としてシステム予約の番号を使用しても、区別がつかない事以外の不都合はありませんが、一般的には使用しない事をお勧めします。


実行時エラー関連記事

第60回.エラー処理(On Error)
・マクロVBAのエラー発生例 ・エラー処理のステートメント ・実行時エラー関連記事
第61回.「On Error GoTo」と「Exit Sub」
・On Error GoTo 行ラベル ・Exit Sub ・On Error の有効範囲とその動作について ・最後に
第62回.「On Error Resume Next」とErrオブジェクト
・On Error Resume Next ・Errオブジェクト ・On Error Resume Next の使用例 ・「On Error Resume Next」の最後に
実行時にトラップ可能なエラー番号一覧と対処
・マクロVBAでのエラーとは ・VBA実行時のエラー番号一覧 ・実行時にトラップ可能なエラー番号一覧の最後に
よくあるVBA実行時エラーの解説と対応
・データ型のエラー ・計算時のエラー ・インデックスのエラー ・オブジェクトの設定エラー ・メソッド・プロパティのエラー ・引数のエラー ・実行時エラー関連記事




同じテーマ「マクロVBA入門」の記事

第125回.Worksheetのイベントプロシージャー
第130回.テーブル操作の概要(ListObject)
第131回.テーブル操作のVBAコード(ListObject,DataBodyRange)
第142回.テーブル全件処理とデータ最終行(ListObject,DataBodyRange)
第127回.他のブックのマクロを実行(Runメソッド)
第128回.マクロをショートカットで起動(OnKeyメソッド)
第129回.レジストリの操作(SaveSetting,GetSetting,GetAllSettings,DeleteSetting)
第133回.引数の数を可変にできるパラメーター配列(ParamArray)
第134回.Errオブジェクトとユーザー定義エラー
第138回.外部ライブラリ(ActiveXオブジェクト)
第140回.Property {Get|Let|Set} ステートメント


新着記事NEW ・・・新着記事一覧を見る

構成比を合計しても100%にならないと言われた…|ツイッター出題回答 (2022-09-01)
一覧から複数条件(部分一致、範囲)に合致するデータを抽出する|ツイッター出題回答 (2022-08-30)
縦横スピルしないXLOOKUP代替(MATCH+INDEX,FILTER,CHOOSEROWS)|エクセル入門(2022-08-27)
IF関数の論理式で比較演算子を省略したCOUNT系関数を書くのは|ツイッター出題回答 (2022-08-23)
LAMBDA以降の新関数の使用例|エクセル入門(2022-08-22)
数珠順列(配置に条件付き)を全て出力する|ツイッター出題回答 (2022-08-20)
日付時刻のマイナス表示に対応する方法|ツイッター出題回答 (2022-08-17)
LAMBDA以降の新関数について|エクセル入門(2022-08-16)
条件付きの最大値と中央値("A"が2文字の条件)|ツイッター出題回答 (2022-08-14)
VBAマクロと操作対象データの分離について|ツイッター出題回答 (2022-08-11)


アクセスランキング ・・・ ランキング一覧を見る

1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.繰り返し処理(For Next)|VBA入門
5.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
6.Excelショートカットキー一覧|Excelリファレンス
7.並べ替え(Sort)|VBA入門
8.マクロって何?VBAって何?|VBA入門
9.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
10.エクセルVBAでのシート指定方法|VBA技術解説




このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。


記述には細心の注意をしたつもりですが、
間違いやご指摘がありましたら、「お問い合わせ」からお知らせいただけると幸いです。
掲載のVBAコードは動作を保証するものではなく、あくまでVBA学習のサンプルとして掲載しています。
掲載のVBAコードは自己責任でご使用ください。万一データ破損等の損害が発生しても責任は負いません。



このサイトがお役に立ちましたら「シェア」「Bookmark」をお願いいたします。
本文下部へ