このページの内容について
このページは、VBAエキスパート(ExcelVBAスタンダード)試験合格講座の第十四回記事です。公式テキスト第9章「エラー対策」と第10章「デバッグ」の内容について解説します。自分でも手を動かしながら読み進めてください。主に講座受講者の復習での利用を想定しています。
エラー
エラーの種類
VBAで発生するエラーは2種類に分類することができます。マクロの実行前に発生する「コンパイルエラー」とマクロの実行中に発生する「実行時エラー」です。
コンパイルエラー
マクロの実行前に発生するエラーです。変数の宣言を強制するオプションが設定されているにもかかわらず、変数を宣言していなかったり、関数の引数の入力途中で改行しようとしたりするときに発生するエラーです。これはVBEが常時、構文チェックを実施しており、コードの記述中もしくは、マクロを実行しようとするときに発生するエラーです。

実行時エラー
マクロの実行中に発生するエラーです。存在しないシートを参照しようとしたり、配列の要素の範囲を超えて参照しようとしたり、VBEの構文チェックには引っ掛からなかったものの、実行中の意図しない動作などによって発生するエラーです。「デバッグ」ボタンを押すと、エラーが発生した行を確認することができます。

Errオブジェクト
実行時エラーは発生したときにキャッチしてエラー内容を確認したり、独自のエラーを発生させたりすることができます。VBAに備え付けのErrオブジェクトを使用します。
Numberプロパティ
各種エラーには識別番号が振られており、エラー発生時にErrオブジェクトのNumberプロパティに格納されます。エラーが発生していない場合の初期値は「0」です。
サンプルコード(クリックでコピー)
Private Sub Test_ErrNumber()
Debug.Print VBA.Err.Number
End Sub
実行結果
上記サンプルコードは、ErrオブジェクトのNumberプロパティに格納された値をイミディエイトウィンドウに出力します。エラーは起きていませんので「0」が出力されます。
Raiseメソッド
ErrオブジェクトのRaiseメソッドを使用すれば任意のタイミングで任意のエラーを発生させることができます。
サンプルコード(クリックでコピー)
Private Sub Test_ErrRaise()
Call Err.Raise(16)
End Sub
実行結果
上記サンプルコードは、No.16「式が複雑すぎます」エラーが発生します。
Descriptionプロパティ
エラーが発生するときに表示されるメッセージは、ErrオブジェクトのDiscriptionプロパティに格納されます。
サンプルコード(クリックでコピー)
Private Sub Test_ErrDescriptionWithRun()
Call Err.Raise(16, Description:="ユーザー定義エラー")
End Sub
Private Sub Test_ErrDescriptionPreLoad()
Err.Description = "ユーザー定義エラー"
Call Err.Raise(16)
End Sub
実行結果
上記サンプルコードは、エラーNo16「式が複雑すぎます」が発生しますが、エラーの説明文は「ユーザー定義エラー」に書き変わっていることを確認できます。
実行時エラーの処理
文法エラーはVBEのルールに違反しているために発生しており、エラーの発生を回避するにはルールに従うしかありません。しかし、実行時エラーは「On Error」ステートメントで意図的に回避したり、Errオブジェクトでマクロ処理の一部としてでエラーの内容を確認したりできます。
On Error Goto Label
「On Error Goto」ステートメントは、エラーが発生したときに指定したラベルへ処理を移動することができます。
サンプルコード(クリックでコピー)
Private Sub Test_OnErrorGotoLabel()
Dim arr(1 To 10)
Dim i As Long
On Error GoTo ErrLabel
For i = 1 To 20 Step 1
arr(i) = i * i
Next i
Call MsgBox("このメッセージが表示されることはありません", vbInformation)
Exit Sub
ErrLabel:
Call MsgBox("エラーが発生しました:" & Err.Description)
End Sub
実行結果
上記サンプルコードは、要素数が1~10の配列を作成し、先頭から順番に値を格納していきます。しかし、途中で10を超える要素を指定してしまいエラーが発生します。
On Error Resume Next
「On Error Resume Next」ステートメントを記述すると、それ以降に発生するエラーをすべて無視します。
サンプルコード(クリックでコピー)
Private Sub Test_OnErrorResumeNext()
Dim ws As Worksheet
Dim sheet_name As String
Dim sheet_num As Long
sheet_num = Application.InputBox("シートの番号を入力してください(左から1、2・・・)", "シート番号受付", Type:=1)
On Error Resume Next
Set ws = ThisWorkbook.Worksheets(sheet_num)
sheet_name = ws.Name
Call MsgBox("シート名は" & sheet_name)
End Sub
実行結果
上記サンプルコードは、ユーザーからシート番号の入力を受け付け、シート名をメッセージで表示します。本来は存在しないシート番号が入力された場合、シートを取得できずエラーとなりマクロの動作は停止しますが、エラーは無視され空文字のメッセージが表示されます。
イミディエイトウィンドウの活用
これまで、データの出力によく使用してきたイミディエイトウィンドウですが、実は「Debug.Print」によるデータ出力だけではなく、変数の中身の確認や、関数の実行もイミディエイトウィンドウ上で行うことができます。
値の参照
変数やセルに格納されている値をイミディエイトウィンドウで直接確認することができます。「?」の後ろに確認したいセルや変数の名前を記述し、Enterキーを押します。入力例)「?ws.Cells(r, 2).Value」「?arr(i, 3)」「?name」

値の代入
イミディエイトウィンドウで変数やセルに直接代入することもできます。記述方法はマクロと同じく代入演算子を使用します。

関数の実行
イミディエイトウィンドウで関数を実行することもできます。

Comment