【VBA基礎⑥】デバッグ処理

皆さんはマクロを作成してエラーが生じると「うわっ、エラーか…」と憂鬱な気持ちになっていませんか?避けられがちな「エラー」ですが、見方を変えれば間違い箇所をプログラム側が教えてくれていると捉えることもできます。エラーへの対処は分かりやすいマクロ作成するための第一歩です。この記事を読めば、エラー対応について理解することができますよ!

この記事はVBAの基礎シリーズです。他の記事は以下のリンクからご覧いただけます!

エラーの種類

マクロのエラーは大きく分けて文法エラー論理エラーの2通りがあります。詳しく確認していきましょう。

文法エラー

文法エラーはVBAの構文を誤った形式で表記した時に表示されます。以下のコードを記述し、実行してみます。

Sub test1()

 cells(1, 1) copy cells(1,2)

End Sub

するとエラーが表示されました。これはメソッドの「Copy」の前に「.」をつけ忘れているからです。

論理エラー

論理エラーは文法的な誤りはないものの、構文の論理的な矛盾によって発生するエラーです。論理エラーはコンパイルエラー(マクロが実行される前に発生するエラー)実行時エラー(マクロ実行後に発生するエラー)に分けられます。

以下のコードを記述し、実行します。

Sub test2()

 For i = 1 To 5
  Cells(1, 1) = i + Cells(1, 1)
 Next i

End Sub

コードを記述して「Enter」を押すと、変数「i」を宣言していないためマクロの実行前に論理的なエラーが発生しました。

2枚目のシートの後ろに新しいシートを追加するコードを記述し、実行します。

Sub test3()

 Worksheets("新規シート").Add After:=Worksheets(2)

End Sub

コードを実行すると実行時エラーが表示されます。これは文法や論理に矛盾がなくても、もともと2枚目のシートが存在しないため、マクロを実行したタイミングでエラーが発生します。

エラーへの対応

On Errorステートメント

On Errorステートメントはエラー発生時にあらかじめ決められた位置に処理をジャンプさせる命令文です。On Errorステートメントは以下のように記述します。On Error Go To以降の処理でエラーが発生するとラベルの位置まで処理がジャンプします。

On Error GoTo ジャンプ先のラベル名

ーーーーーーーーーーーーーーーーーーーーーーーーーーーー

 処理(ここでエラーが起きるとラベル名:へジャンプする)

ーーーーーーーーーーーーーーーーーーーーーーーーーーーー

ラベル名:

構文の例題を見てみましょう。以下のマクロはインプットボックスを使用して分母の値を入力し、割り算をして結果を表示します。この時インプットボックスの値に「0」を入力するとエラーが発生しますが、エラーが生じるとラベル「error01」に処理がジャンプし、メッセージボックスが表示されます。

処理が通常通り実行された場合も最後のメッセージボックスの結果が表示されてしまうので、この例題の場合は「Exit Sub」でマクロから抜け出すようにしておく必要があります。

Sub test4()

 Dim num1 As Double, num2 As Double, result As Double

 num2 = InputBox("分母を入力してください。")
 num1 = 100

 On Error GoTo error01

 result = num1 / num2
 MsgBox "計算結果: " & result

 Exit Sub

 error01:
 MsgBox "ゼロで除算できません。"

End Sub

On Errorステートメントはエラーを無視する命令を出すことも可能です。On Errorの後ろのキーワードにResume Nextを追加することでエラーを無視して処理を通常通り実行します。

以下のマクロでは存在しないシートを削除しようとしてエラーが発生しますが、エラー発生を無視してそのまま処理が進むため、メッセージボックスの内容が表示されます。

Sub test6()

 On Error Resume Next
 Worksheets("NonSheet").Delete
 MsgBox "エラーを無視して処理が実行されました。"

End Sub

Errオブジェクト

エラーが発生すると、エラー情報がErrオブジェクトに格納されます。このErrオブジェクトの中身を調べることでエラーの種類を特定することができます。先ほどと同じようにゼロを分母にした割り算を実施するコードを記述します。

エラー情報はErrオブジェクトに格納されるので、その中身を調べてメッセージボックスで表示します。Numberプロパティはエラーごとに決まった番号を返します。Descriptionプロパティはエラー種類の文字列を返します。

Sub test5()
 Dim num1 As Double, num2 As Double, result As Double

 num1 = 100
 num2 = 0

 On Error GoTo Error01

 result = num1 / num2
 MsgBox "計算結果: " & result

 Exit Sub

 Error01: 
 MsgBox "エラー番号: " & Err.Number & vbCrLf & "エラー内容: " & Err.Description

End Sub

実行するとエラー番号と内容が表示されました。0除算のエラー番号は「11」です。「vbCrLf」は改行を表します。

エラー対策

イミディエイトウィンドウ

イミディエイトウィンドウはマクロが停止中に変数の値やプロパティの値を確認する時に便利です。VBA管理画面の「表示」タブから「イミディエイトウィンドウ」を選択するとウィンドウが開きます。

実際にイミディエイトウィンドウの使用方法を確認してみましょう。

まず、以下のようなコードを記述し、カーソルを目的の場所に合わせて「デバッグ」タブの「ブレークポイントの設定/解除」を選択します。するとカーソル位置にブレークポイントが設定されます。ブレークポイントとはマクロがその行まで実行された時に処理を一時停止する機能です。

ブレークポイントを設定した状態で、マクロを実行します。するとブレークポイントで処理が止まるので、イミディエイトウィンドウに「?num(3)」と入力してみます。すると配列に入力されている「3」が返されます。

このように変数などの直前に?をつけて「?変数名」のようにイミディエイトウィンドウに記述してEnterすることで、その中身を知ることができます。

ウォッチウィンドウ

ウォッチウィンドウは複数の変数などの値の変化をリアルタイムで監視して、設定した値になったらマクロを一時停止するなどの機能があります。「表示」タブの「ウォッチウィンドウ」を選択するとウィンドウが開きます。

実際にウォッチウィンドウを使用してみましょう。コード内で右クリックして「ウォッチ式の追加」をクリックすると「ウォッチ式の編集」が表示されます。その式に「n>32」と入力、ウォッチ式の対象は作業中のプロシージャとモジュールがデフォルトで記入されます。ウォッチの種類は「式がTrueのとき中断」としておきます。

ウォッチ式を編集してOKすると、ウォッチウィンドウに編集したウォッチ式が表示されます。この状態でマクロを実行すると、nが32を超えた時点でデバッグモードになり、処理が一時停止されます。

ウォッチウィンドウはデバッグの「ステップイン」と併用すると便利です。「デバッグ」タブの「ステップイン」を選択すると、マクロがデバッグモードになり、ステップインを実行するごとに1行ずつマクロを動作を確認していくことができます。ステップインとウォッチウィンドウを使用してマクロの動作と変数の値の変化を追うことができるのです。

まとめ

いかがでしたでしょうか?今回はVBAのデバッグ処理についてまとめました。この記事はVBAの基礎シリーズとして今後も発信していきますので、良ければ他の記事も読んでいただければ嬉しいです。それでは最後までお読みいただき、ありがとうございました。