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

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

第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が記述されているプロシージャーが終了するときにErrオブジェクトはリセットされます。
Exit Sub、Exit Function、Exit Propertyの実行後、または、End Sub、End Function、End Propertyの実行後にリセットされます。

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


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

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


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.Cleaがないと、
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 Resume Next を使ってください。

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 'ここでErrオブジェクトはリセットされます
  'エラーの可能性がある処理
  MsgBox "検索値なし"
End Sub

On Error Resume Nextの実行でErrオブジェクトはリセットされてしまいますので、
必要なエラー情報はその前に取得しておく必要があります。
また、上記VBAで、On Error Resume Nextが無い場合、
その後の処理でエラー発生した場合、VBAはエラー停止してしまいます。

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度目のエラーは補足されません。
これをさける方法もあるようですが、このような使い方はしないことです。

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関数 CVErr(errornumber) errornumberには、任意の数値(エラー番号)を指定します。この引数は必ず指定します。

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

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

実行時にトラップ可能なエラー番号一覧
マクロVBA実行時に発生するエラーのエラー番号とエラーメッセージおよび簡単な理由と対策の一覧です。以下の表にあるエラーはトラップ(捕捉)できるエラー一覧になります。OnErrorステートメントおよびErrオブジェクトのNumberロパティを使用して、エラーへの対処を行うことができます。

以下は、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を記述出来ればそれに越したことはありませんが、一切エラーを出さないようにVBAを書くことはかなり困難なものです。
第61回.「On Error GoTo」と「Exit Sub」
「OnErrorGoTo行ラベル」このステートメントは、実行時エラーが発生した時に、制御を指定の行ラベルに移動させるものです。マクロVBAは、エラーが発生するとその時点で停止してしまいます。VBAが実行不能となった場合に、エラー発生したVBAコードで停止します。
第62回.「On Error Resume Next」とErrオブジェクト
「OnErrorResumeNext」ステートメントは、実行時エラーが発生してもマクロVBAを中断せずに、エラーが発生したステートメントの次のステートメントから実行を継続します。マクロVBAは、エラーが発生するとその時点で停止してしまいます。
実行時にトラップ可能なエラー番号一覧と対処
マクロVBA実行時に発生するエラーのエラー番号とエラーメッセージおよび簡単な理由と対策の一覧です。以下の表にあるエラーはトラップ(捕捉)できるエラー一覧になります。OnErrorステートメントおよびErrオブジェクトのNumberロパティを使用して、エラーへの対処を行うことができます。
よくあるVBA実行時エラーの解説と対応
VBAを書き終えて、いざ実行したら意味不明なメッセージが… ここでは初心者向けに、代表的な実行時エラーの解説とその対応について説明します。中級者以上の方は、実行時にトラップ可能なエラー番号一覧と対処 こちらを参考に、エラー対応(OnError等)を実装してください。



同じテーマ「マクロ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 ・・・新着記事一覧を見る

import文(パッケージ・モジュールのインポート)|Python入門(9月24日)
例外処理(try文)とexception一覧|Python入門(9月23日)
リスト内包表記|Python入門(9月22日)
Pythonの引数は参照渡しだが・・・|Python入門(9月21日)
lambda(ラムダ式、無名関数)と三項演算子|Python入門(9月20日)
関数内関数(関数のネスト)とスコープ|Python入門(9月18日)
関数の定義(def文)と引数|Python入門(9月18日)
組み込み関数一覧|Python入門(9月17日)
辞書(dict型)|Python入門(9月16日)
入力規則への貼り付けを禁止する|VBA技術解説(9月16日)


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

1.最終行の取得(End,Rows.Count)|VBA入門
2.RangeとCellsの使い方|VBA入門
3.変数宣言のDimとデータ型|VBA入門
4.マクロって何?VBAって何?|VBA入門
5.セルのコピー&値の貼り付け(PasteSpecial)|VBA入門
6.Range以外の指定方法(Cells,Rows,Columns)|VBA入門
7.繰り返し処理(For Next)|VBA入門
8.セルに文字を入れるとは(Range,Value)|VBA入門
9.とにかく書いてみよう(Sub,End Sub)|VBA入門
10.マクロはどこに書くの(VBEの起動)|VBA入門




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


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



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