VBAによる自動化ツールの作成において、Errオブジェクトの使いどころを解説します。この記事は、VBAのエラーをトラップする事ができるErrオブジェクトを取り上げています。エクセルのErrorクラスとは別モノなのでご注意下さい。
目次
Errオブジェクトの使い方
Errオブジェクトは、実行時エラーが発生した際にエラーの種類を表すエラー番号をプロパティに持つオブジェクトです。このことから、デバッグの差異や、エラーが起きてそれをトラップする事を前提にプログラムを作成するときに使います。
インスタンスを自分で生成する必要はありません。Sheetsとかのオブジェクトと同様、すでに実態がそこにあるオブジェクトです。
実行時エラーのエラートラップを行う
実行時エラーが発生するプログラムを作成する前に、エラーについて簡単に知識を整頓しておきます。VBAによるプログラミングのエラーには、以下の2種類が存在します。
- コンパイルエラー
- 実行時エラー
Errオブジェクトでトラップできるのは実行時エラーのみです。エラーオブジェクトのサンプルコード解説の前に2つのエラーについて簡単に意味をおさらいします。
コンパイルエラーとは
コンパイルエラーとはキーワードや識別子*1の綴りを間違ってしまうなど、プログラムの文法自体が間違っていること。VBAではプログラムを記述していいる最中の改行をする都度とプログラムを実行する時に各プロシジャが始まる直前の2段階でプログラミングの中身が間違っていないかの判断を行っています。
この段階で検出できるエラー、つまりプログラムを実行していないときに検出されるエラーコンパイルエラーです。コンパイルエラーのサンプルを挙げます。
Sub エラーが発生する() msgbx "こんにちは" End Sub
「こんにちは」と表示するメッセージボックスを出そうとしたところ、MsgBoxの綴りを間違えてしまいました。このプロシジャを実行するとコンパイルエラーが発生します。
実行時エラーとは
次に実行時エラーです。実行時エラーとはプログラムの一行一行の記述は文法的に間違っていないものの、実行しようとすると、実行できないエラーのことです。例えば、ブックを開こうとしたものの、指定されたブックのフルパスのファイルが存在しない、とか、存在しないシート名のシートをコピーしようとしたと言ったエラーです。文法的に合っていても、そのファイルやシートが存在するかどうかは実際に実行してみないと分かりません。このように実行時に発生するエラーを実行時エラーと言います。
いか、実行時エラーが発生するプログラムを作成して解説を進めていきます。
Numberプロパティ
それではErrオブジェクトの使い方を見て行きます。まず、実行時エラーが発生するプログラムを作成します。
Sub 実行時エラーが発生する() Workbooks.Open Filename:="こんな変な名前のファイルありませんよ" End Sub
実行すると、下記の様な実行エラーが発生します。
WorkbooksクラスのOpenメソッドはFilename引数で受け取ったフルパスのファイルを開こうとします。フルパスと言う事は「ディレクトリ名¥ファイル名」と言うような文字列です。今回は「こんな変な名前のファイルありませんよ」という存在しないフルパスを指定しているのでエラーになっています。プログラムを記述しているときは分からなかったが、実行してみて始めて存在しないフルパスだと言うことに気づくという実行時エラーが発生しました。
実行時エラーのメッセージボックスの一行目に、実行時エラー '1004': と言う記述があります。この1004の部分がどのようなエラーか、エラーの種類を表す番号です。これがErrオブジェクトのNumberプロパティとなります。この実行時エラーの番号をトラップできるように、先ほどのプログラムを書き換えてみます。
Sub 実行時エラーが発生する() On Error Resume Next Workbooks.Open Filename:="こんな変な名前のファイルありませんよ" Debug.Print Err.Number 'イミディエイトウィンドウに1004と表示される End Sub
On Errorステートメントはエラーが発生したときに処理の流れをコントロールします。Resume Next ステートメントは次に戻ると言う意味です。つまり、On Error Resume Nextで、「エラーが発生した場合にはその行は実行せずに次の行から処理を再開せよ」と言う意味となります。
今回はそのままだとWorkbooks.Openの部分で実行時エラーが発生して、処理が止まってしまうため、On Error Resume NextをWorkbooks.Openの直前に記述する事によって、エラーで処理が止まらないようにしています。そして、その直後にDebug.Pringメソッドでイミディエイトウィンドウにエラー番号を表示させています。
このように、デバッグ時にエラーの種類を特定することができます。
Descriptionプロパティ
次にDescriptionプロパティを利用します。実行時エラーの時に表示されるメッセージボックスの3行名以降に表示されるエラー内容の説明文がErrオブジェクトのDescriptionプロパティに格納されている値です。Descriptionプロパティの内容を取得してみます。
Sub 実行時エラーが発生する() On Error Resume Next Workbooks.Open Filename:="こんな変な名前のファイルありませんよ" Debug.Print Err.Description '「申し訳ございません。~」がイミディエイトウィンドウに表示される End Sub
Workbooks.Openでよく見かけるエラーが今回のサンプルのように存在しないファイルを開こうとした場合です。このときのエラーをトラップする目的ならこのようにDescriptionプロパティを使う事ができます。
Sub 実行時エラーをトラップして処理を分岐する() On Error Resume Next Workbooks.Open Filename:="こんな変な名前のファイルありませんよ" If InStr(Err.Description, "見つかりません") <> 0 Then MsgBox "ファイルが見つかりません。処理を中断します。" End End If End Sub
これはInstr関数を使って、エラーメッセージに「見つかりません」の文字列が含まれている場合は、実行時エラーのメッセージボックスと処理の中断を発生させずに、自分で用意したメッセージボックスを表示して、処理を中断するプログラムです。
Descriptionプロパティはこのような処理の分岐に使う事もできますが、やや邪道な感はあると思います、ここからは主観になりますが、次の項で理由を説明したいと思います。
On Error Resume Nextの注意点
前項で、On Error Resume Nextをつかって実行時エラーを無視し、Descriptionプロパティでエラー内容をトラップしました。もちろんコレでもエラーを検出する事はできます。しかし、On Error Resume NextはVLOOKUPで検索範囲内に検索値が存在しない値がある事が想定できる場合のように、エラーが発生することが分かっていても防げない場合に利用を限定すべきだと考えます。
理由としてはエラーが発生することが分かっているのであれば、エラーが発生しないようにプログラムを組むのが基本的な考え方だと思うからです。というわけで、Descriptionプロパティでエラー内容をトラップすることも可能ですが、あくまでデバッグに使うのが基本の考え方であると、このブログでは解説を結論づけたいと思い思います。
Errオブジェクトのまとめ
今回の解説の内容をまとめます。
- エラーの種類には大きく分けてコンパイルエラーと実行時エラーが存在する
- Errオブジェクトは実行時エラーをトラップする
- ErrオブジェクトのプロパティにはNumberとDescriptionが存在する
- NumberやDescriptionプロパティを使えば実行時エラーの種類が特定できる
- Errオブジェクトのプロパティを使って処理を分岐することができるが、あくまでデバッグ用に使う事を推奨する
以上、Errオブジェクトの使い所でした。デバッグ作業を効率化して、開発効率を高めていきましょう!
<関連記事>
<お知らせ>
Excel VBAでクラスやオブジェクトの概念と使い方を丁寧に解説し、ワンランク上の実力を目指すガイドを書きました。この本で本物の実力を身に付けて一皮むけてみませんか?
books.rakuten.co.jp
*1:メソッドやプロパティ名、既定のオブジェクト名やステートメントの名前のこと