【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


インプットボックスはユーザーは任意の文字や数字を入力することができる関数です。InputBoxの()内にあらかじめ表示させる文字列などを設定できます。
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の基礎シリーズとして今後も発信していきますので、良ければ他の記事も読んでいただければ嬉しいです。それでは最後までお読みいただき、ありがとうございました。