ES000014_VBAエキスパート(ExcelVBAスタンダード)合格講座/第十四回:エラーとデバッグ

VBAエキスパート(ExcelVBAスタンダード)合格講座/第十四回:エラーとデバッグ ExcelVBA Standard

このページの内容について

このページは、VBAエキスパート(ExcelVBAスタンダード)試験合格講座の第十四回記事です。公式テキスト第9章「エラー対策」と第10章「デバッグ」の内容について解説します。自分でも手を動かしながら読み進めてください。主に講座受講者の復習での利用を想定しています。

エラー

エラーの種類

VBAで発生するエラーは2種類に分類することができます。マクロの実行前に発生する「コンパイルエラー」とマクロの実行中に発生する「実行時エラー」です。

コンパイルエラー

マクロの実行前に発生するエラーです。変数の宣言を強制するオプションが設定されているにもかかわらず、変数を宣言していなかったり、関数の引数の入力途中で改行しようとしたりするときに発生するエラーです。これはVBEが常時、構文チェックを実施しており、コードの記述中もしくは、マクロを実行しようとするときに発生するエラーです。

実行時エラー

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

VBEの自動構文チェックは、エラーを発見次第すぐさまメッセージを表示します。しかし、この機能は関数の入力中に、文字列を別の場所からコピーしてきたりするような時にも発生し、手が止まってしまいます。このメッセージは表示させないこともできます。手順は「T0000015_VBAで改行するとエラーになる」を参照してください。

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を超える要素を指定してしまいエラーが発生します。

Labelとは「任意の名前:」で表現されます。エラー発生時だけではなく「GoToステートメント」を使用することで任意のLabelにいつでもジャンプすることができます。非常に便利な機能ですが、ジャンプ処理はプログラムの流れを断ち切ってしまうためコードの可読性が著しく低下します。可能な限り使用しないでおくことをおすすめします。

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」

イミディエイトウィンドウで変数の値を直接確認する場合、マクロの動作をブレイクポイントや「Stopステートメント」で一度止める必要があります。なお、セルの値はいつでも確認できます。

値の代入

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

関数の実行

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

【PR】VBAエキスパート試験対策記事

当サイトでは、オデッセイコミュニケーションズ社が運営する試験であるVBAエキスパートExcel VBA ベーシックExcel VBA スタンダード)の出題範囲をベースに用語や各種関数の解説などを行っています。試験合格に向けて必須と言われる公式テキストに沿って解説をしています。受験をするか悩んでいる方、テキストとは別視点の解説を見てみたい方、受験はしないがExcelVBA(マクロ)に興味がある方へ向けた記事です。

Comment