エラーの種類
コンパイルエラーは、VBAコードをコンパイルする時に論理矛盾が発生するとコードを実行する前に発生します。
実行時エラーは、コードを実行して初めて分かるエラーです。指定しているシートが無いとか、配列の要素数がおかしいとかそんな感じです。
Errオブジェクト
エラーが発生すると、VBAはエラーに関する情報を”Errオブジェクト”に格納します。
Errオブジェクトのプロパティ
No | プロパティ名 | 説明 |
---|---|---|
① | Description | エラーに関連付けられている説明を取得または設定する。 |
② | HelpContext | ヘルプファイルのトピックに対応するコンテキストIDを含む文字列式を取得するか設定する。 |
③ | HelpFile | ヘルプファイルへの完全修飾パスを含む文字列式を設定または取得します。 |
④ | Number | エラー番号の取得または設定する。 |
⑤ | Source | 最初にエラーを生成したオブジェクトまたはアプリケーションの名前を指定した文字列を取得または設定する。 |
次のコードを実行してエラーを発生させてみましょう。
実行しているEXCELブックには、「エラーシート」という名前のシートは無いとします。
Sub sample()
'シートの指定
Dim sheet As Worksheet
Set sheet = ThisWorkbook.Sheets("エラーシート")
End Sub
指定したシート名が無いので、次のようなエラーが発生します。
この図で言う、「9」が④のNumberプロパティ、「インデックスが有効位な範囲にありません。」が①のDescriptionになります。
他のプロパティもイミディエイトウィンドウで調べてみましょう。
エラーのポップアップの「デバッグ」ボタンを押します。
エラーの場所の色が変わると思います。
イミディエイトウィンドウでプロパティを確認するには、その状態で
?Err.プロパティ名
あるいは、
Debug.Print Err.プロパティ名
を入力します。
「?」は「Debug.Print」の意味です。
1行入力するごとに、Enterで決定するとその行が実行出来ます。
次のコードを入力して、それぞれ実行してみます。
?Err.Description
インデックスが有効範囲にありません。
?Err.HelpContext
1000009
?Err.HelpFile
C:\Program Files\Common Files\Microsoft Shared\VBA\VBA7.1\1041\VbLR6.chm
?Err.Number
9
?Err.Source
VBAProject
それぞれのプロパティの中身が出てきましたね(^o^)
”Description”と”Number”はよく使うので覚えておいてください。
エラーが発生したときの処理
記述エラーやコンパイルエラーは、通常開発時に修正することが出来ますが、実行時エラーは厄介です。
作ったEXCELツールがシートの値を参照している場合など、ユーザーが予期せぬ入力を行ったり、適切に運用がされなかった場合にも発生します。
エラーが発生した際は、VBEからのメッセージとともに、コードの実行が止まります。VBAを理解している人ならば適切に処理出来ますが、VBAを知らない人には処理するのは難しいでしょう。
VBAは、エラーが発生したことを検知するために、On Errorステートメントが用意されています。
代表的な使い方は、次の2つです。
- On Error Goto ラベル
- On Error Resume Next
On Error Goto ラベルは、エラーを検知したら、ラベルまで次の処理を飛ばします。
先程サンプルコードに、On Error Gotoを付け加えます。
Sub sample()
On Error GoTo Catch
'シートの指定
Dim sheet As Worksheet
Set sheet = ThisWorkbook.Sheets("エラーシート")
Debug.Print "正常終了"
Exit Sub ' 正常終了したときはここで終わり
Catch:
Debug.Print "エラーが発生したよ"
End Sub
ここでは、ラベルを「Catch」としています。このラベルの名前は任意でOKです。分かりやすい名前にしておきましょう!
14行目に「Catch:」とありますが、これがエラーが発生した時に飛んでくるラベルの場所です。ラベル名に続けて「:」を付けてください。
その後に、エラーの場合の処理を記入します。
また、エラーが発生しなかった場合、ラベルの処理を行わないように、ラベルの前でプロシージャを終了させる必要がありますね。
”Exti Sub”を記述することで、ここでプロシージャの処理を終了させることが出来ます。
実行動画を見てみましょう!
最初にエラーが発生するバージョン、次に実際に存在するシート名に変更して、エラーが発生しないバージョンです。
On Error Resume Nextは、エラーを検知したら、無視して次の処理に進みます。
「エラーシート」というシートが無いEXCELブックで次のコードを実行します。
※エラーになります。
Sub sample()
On Error Resume Next
'シートの指定
Dim sheet As Worksheet
Set sheet = ThisWorkbook.Sheets("エラーシート")
Debug.Print "無視して突き進むよ"
End Sub
通常エラーで止まってしまうところを、無視して突き進みましたw
Errオブジェクトをクリアする
Errオブジェクトに格納されたエラー情報は、プロシージャが終了するまで保持されます。
複数のOn Errorステートメントを利用したい場合は、前のエラー情報をClearメソッドで削除しておく必要があります。
Err.Clear
これでOKです。
まとめ
エラーが発生した場合、On Error Gotoで飛ばして、メッセージボックスにエラー情報に加えて「開発担当に連絡してください」と表示するようにしたり、エラー番号によってその後の処理を分けたりなど、場合によっていろいろな処理が出来ると思います(^o^)
コメント