はじめに
デバッグは、プログラムが思った通りの動作をしない場合、その不具合を探すために行います。
デバッグの機能はVBEに備えられており、主に2つの機能があります。
・プログラムを途中で止める
・変数やオブジェクトの中身を見る事ができる
この機能を使って、プログラムを1工程づつ進めるなど、繰り返しや条件分岐の動向を確認しながら点検していく作業です。
デバッグの使い方については、以下のページでも解説しています。
・デバッグ
ここでは、サンプルをもとにデバッグのやり方を解説します。
プログラムを一時停止する
途中でプログラムを停止させるには、ブレークポイントを設置します。
ブレークポイントの設置・解除は簡単で、コードウインドウの左側をクリックすればOKです。
(設置しているブレークポイントを解除するには設置ポイントを再度クリックします。)

ただし、Dimなどの変数の定義部分やプログラムが書いていない行はブレークポイントを設置できません。
プログラムを実行すると、ブレークポイントの行で停止しますが、
停止した時点では、その行を実行する直前の状態になります。
(止まった行のプログラムは実行されていません。)
ステップ・イン(F8キー)
ブレークポイントで一時停止している状態から、F8キーを押すと、一行づつプログラムを進めていく事ができます。
この機能をステップ・インと言います。
その他にもある程度まとめてプログラムを進める ステップ・オーバー、ステップ・アウトなどがあります。
変数やオブジェクトの中身を見る
ブレークポイントでプログラムを一時停止した状態で、マウスカーソルをかざすと、変数やオブジェクトの値が表示されます。


また、ローカルウインドウを開いておけば、現在の変数の値を確認する事ができます。

デバッグ・プリント
Debug.Print は既に紹介していますが、デバッグ用のコマンドです。
繰り返し回数が多くなる場合、ブレークポイントを設置して、一行づつプログラムを実行していては効率が悪くなります。
そのような時は、Debug.Print を書いておきイミディエイトウィンドウに値を出力させて変化を観察するなど、使い方はアイデア次第です。
デバッグを体験してみる
まずは正常に動くプログラムでデバッグ機能を体験してみましょう。
以下のプログラムを標準モジュールに書いて、ブレークポイントを設置してF8を押して一行づつプログラムを実行させてみましょう。
Sub FizzBuzz()
Dim i As Long
Dim str As String
str = ""
For i = 1 To 15
If i Mod 15 = 0 Then
str = str & "FizzBuzz" & vbCrLf
ElseIf i Mod 3 = 0 Then
str = str & "Fizz" & vbCrLf
ElseIf i Mod 5 = 0 Then
str = str & "Buzz" & vbCrLf
Else
str = str & i & vbCrLf
End If
Next i
MsgBox str
End Sub
一時停止した状態で、マウスカーソルをかざすと、黄色で選択されていない変数やオブジェクトでも値が表示されます。
途中で止めたい場合は、メニューの四角ボタン(リセット)を押せば終了します。
上手く動作しないプログラム
以下のプログラムは以前出てきた上手く動かないプログラムです。
n = 4 の所にブレークポイントを設置してF8で一行づつ実行させてみましょう。
Sub IfSample()
Dim n As Long
n = 4
If n Mod 2 = 0 Then
MsgBox "2で割り切れます。"
ElseIf n Mod 3 = 0 Then
MsgBox "3で割り切れます。"
ElseIf n Mod 4 = 0 Then
MsgBox "4で割り切れます。" 'ここには来ない!
Else
MsgBox "割り切れませんでした。"
End If
End Sub

このように、最初のIf文で条件をクリアしてしまい
ElseIf n Mod 4 = 0 Then を通ることはありません。
If ElseIf Else は上から評価されていくというルールが確認できました。
正しく動作させたい場合は、以下のように書き変えなければいけません。
n = 4 の部分を色々な数値に替えて動作を確認してみましょう。
Sub IfSample()
Dim n As Long
n = 4
If n Mod 4 = 0 Then
MsgBox "4で割り切れます。"
ElseIf n Mod 3 = 0 Then
MsgBox "3で割り切れます。"
ElseIf n Mod 2 = 0 Then
MsgBox "2で割り切れます。"
Else
MsgBox "割り切れませんでした。"
End If
End Sub
上手く動作しないプログラム(中級)
次のプログラムは、以下の表から7月分のスイカの合計金額を求めるというものです。

Sub Macro()
Dim i As Long
Dim total As Long
Dim myday
total = 0
For i = 2 To 20
myday = Cells(i, "B")
If Cells(i, "C") = "スイカ" And #8/1/2023# > myday Then
total = total + Cells(i, "D")
End If
Next i
Debug.Print total
End Sub
このプログラムの問題点は、答えが 9500 となるはずが、6500 と表示されてしまう点です。
問題は、B11セルが、「7月32日」とあり得ない日付になっているためです。
実は、ここだけが日付型ではなく文字列型になっています。
(左寄せになっている事からもわかります。)
もっと問題なのは、プログラムで「型が一致しません」とエラーを出さない事でしょう。
プログラム上で問題なのは、myday変数が型を省略しているためバリアント型になっており、If文でエラーが出ずに処理が進んでしまうためです。
プログラムをきちんと動作させるためには、意図しない事が起こった場合、すぐにエラーを出してくれるように書くべきです。
このプログラムの場合は、myday をきちんとDate型にしておくべきでした。
Dim myday As Date
このようにしておくと、「型が一致しません」とエラーが出てくれます。

「デバック」ボタンを押すと、問題の場所が黄色となります。
カーソルを i の所にかざすと値が表示されます。

i = 11 となっているので、B11セルを見に行くと、値がおかしいと気付く事ができます。
今回のミスから得られること
プログラミングはミスを克服する事で、不具合を起こさないようなプログラムが書けるようになってきます。
今回は以下のような点に注意するべきだったと気付くはずです。
・変数をむやみにバリアント型にしない
・セルには様々な型の値があると思った方が良い
・例外的な事が起こったらエラーで発見できるようにしておく
まとめ
デバッグには、その他にもたくさんの機能があります。
初心者にとっては、専門的になってしまうため荷が重いでしょう。
今回は入門講座ですので、デバッグの内容は最小限にとどめました。
それでも、ここまでの知識で大いに役立つはずです。
結局のところプログラミングには慣れが必要で、それには年月がかかります。
それに伴って、デバッグの必要性が身に染みてきて使い方をマスターしていくという順番になります。
デバッグを疎かにして良いという事ではないのですが、
まずはブレークポイント、ステップ・イン、Debug.Print だけで良いので十分に慣れて頂きたいと思います。
入門講座 目次
・開発環境を整える
・VBAプログラムの基礎
・VBAプログラムの基礎2
・セルの使い方
・ブックやシートの参照
・プログラムでの日付の扱い方
・プロシーシャの使い方
・「マクロの記録」を利用する
・デバッグのやり方
・やりたい事の調べ方と解決方法
・自力でプログラムを書いてみる
・別ブックのデータを集計
・別ブックのデータを集計 2
コメント