【超初心者向け】エクセルVBAでデバッグをする方法を解説します
エクセルVBAでマクロを作ると、思い通りに動かないことがとても多いです。
そういうときには、何がおかしいのか原因を探って修正する「デバッグ」作業が必要になります。
このページでは「デバッグ」をする基本的な方法を説明していきます。
この記事の目次
デバッグとは何か?
デバッグというのは、プログラムがうまく動かないときに、原因を突き止めて修正する作業のことをいいます。
英語では「debug」と書きます。
プログラムの誤りのことをバグ(bug)というのですが、それを取り除く(=「de」)作業ということで、「debug」と呼ばれています。
また、デバッグをするツールのことをデバッガ(=「debugger」)といいます。
VBAの場合は、エディタ自体にデバッガの機能が付いているので、それを使ってデバッグをしていきます。
デバッグをするときの考え方
デバッグをするときには、次のような手順で考えていきます。
- 直接の原因となっている「場所」を特定する
-
マクロの中で、どこで自分の意図と違う処理がされている、直接の原因となっている「場所」を特定しましょう。
意図せずエラーが出た → エラーが出た「場所」 セルへの書き込み結果が違う → セルへの書き込みをしている「場所」 まずは、この「場所」を特定するのがデバッグの第一歩です。
- 処理をさかのぼって原因を特定する
-
次に、その根本原因を特定しましょう。
多くの場合、直接の原因となっている「場所」で使っている変数やデータの「変化」を追うことで、根本原因が突き止められます。
ブレークポイントを使うことで、変数やデータの「変化」が追いやすくなります。
実際にデバッグをしてみる
たとえば、セルB4に「売上個数×売上単価」の計算をして結果を入れる処理を書いてみましょう。
変数を使わなければ1行で済むプログラムなのですが、説明のため、あえて変数を使って書いています。
不具合があるプログラム
Sub CalculateAmount()
Dim Quantity
Quantity = Cells(2, 2).Value
Dim UnitPrice
UnitPrice = Cells(2, 2).Value
Cells(2, 4).Value = Quantity * UnitPrice
End Sub
上記、プログラムにはバグがあります。そのため、実行してみると次のように想定した結果になりません。
それでは、バグの原因を調べていきましょう。
ブレークポイントの設定
今回、D2セルの結果が意図と違っています。
ですから、エラーの「直接の原因」になっているのは8行目「Cells(2, 4).Value = ...」です。
Sub CalculateAmount()
Dim Quantity
Quantity = Cells(2, 2).Value
Dim UnitPrice
UnitPrice = Cells(2, 2).Value
Cells(2, 4).Value = Quantity * UnitPrice
End Sub
そこで、8行目に「ブレークポイント」を設定してみます。
操作方法
指定した行で、プログラムの実行をいったん止めることができます。
- 「実行を止めたい行」の左側の灰色部分を左クリックする
- 「実行を止めたい行」を選択してF9キーを押す
とブレークポイントが設定でき、該当行が赤くなります。
ブレークポイント設定後マクロを実行する
その後、通常通りマクロを実行してみます。
すると、次のように、ブレークポイントを設定した行が黄色くなります。
これは、その行を実行する直前でマクロが止まっていることを表しています。
ウォッチウィンドウで変数の内容を確かめる
今回のバグの「直接の」原因となっているのは
「Cells(2, 4).Value = Quantity * UnitPrice」
の行です。
この行を実行した結果が違っているということは、右辺の「2つの変数」(=Quantity、UnitPrice)の内容が違っているのではないかと推測できます。
そこで、この2つの変数の内容を確認してみましょう。
ブレークポイント時点での、変数の内容を確かめるには「ウォッチウィンドウ」を使います。
- ウォッチウィンドウを表示する
-
あらかじめメニューの「表示」→「ウォッチウィンドウ」からウィンドウを表示させておきます。
通常、エディタ画面の右下にウォッチウィンドウが表示されます。
- 内容を確認したい変数・データを選択してドラッグアンドドロップ
-
変数をマウスで範囲指定して、ウォッチウィンドウの領域にドラッグアンドドロップします。
これで、ウォッチウィンドウの設定は完了です。
ウォッチウィンドウの設定が終わったら、まずは「値」欄を見てみましょう。
この時点(=黄色い行を実行する直前の状態)での変数の値が表示されます。
元データと見比べてみると、本来は「UnitPrice(単価)」が「150」になっていてほしいのに、ウォッチウィンドウでは「UnitPrice」の値が「100」になってしまっています。
元データ
結局、「UnitPrice」の値が違っていそうだということがわかります。
参考:さまざまな値をウォッチウィンドウで見る
ウォッチウィンドウには、次のように、変数以外の様々な内容を表示できます。
- Cells(2, 2).Value
-
「Cells(2, 2).Value」を丸ごと範囲指定して、ウォッチウィンドウにドラッグアンドドロップすると、B2セルの内容を見ることができます。
- Cells(2, 2)
-
「Cells(2, 2)」を範囲指定してウォッチウィンドウにドラッグアンドドロップすると、B2セルを指すCellsオブジェクトの内容を見ることができます。
オブジェクトの場合は、ウォッチウィンドウで配下のプロパティも合わせて確認することができます。
内容を見たい項目があったら、とりあえず、なんでもウォッチウィンドウに放り込んでみましょう。
デバッグ終了
ブレークポイントを再設定して、マクロを実行し直すために、いったんデバッグを終了させましょう。
画面上部の「青四角」ボタンを押すと、デバッグが終了します。
ブレークポイントの再設定
ブレークポイントを設定し直して、マクロの最初からプログラムの動きを追っていこうと思います。
ブレークポイントが設定されている行で、もう一度、同じ操作(左の端をクリック、あるいは、行を選択してF9)をすれば、ブレークポイントを解除することができます。
そして、「Quantity = ... 」の行にブレークポイントを設定します。
マクロの最初で止めたいときには、実行するSubプロシージャ内の最初の行にブレークポイントをかけましょう。
なお、Dim文にはブレークポイントは設定できません。
Subプロシージャの最初がDim文の場合には、その次の行にブレークポイントを設定しましょう。
ステップ実行
ブレークポイントの再設定をしたら、再度、マクロを実行してみます。
今度は、1行ずつプログラムを実行してみましょう。
- デバッグツールバーの表示
-
この機能を使うためには、あらかじめ「デバッグツールバー」を出します。
その後、出てくるツールバーを使って、「1行ずつプログラムを実行する」など指示をすることができます。
慣れないうちは上の図の「赤色」で書いているボタンを使えるようになりましょう。
- 1行ずつプログラムを実行する
-
今回は、1行ずつプログラムを実行するボタン(=緑色の三角ボタン。正式には「ステップイン」ボタンといいます)を押してみましょう。
すると、次のように黄色い線が次の行に移動していきます。
このとき、右下のウォッチウィンドウの値が順番に変わっていくことを確認してください。
↓次の行を実行
↓次の行を実行
1行ずつプログラムを実行する場合も「Dim文」は無視されます
こうして、1行実行するごとに「変数」の値がどう変化するかを見ていくのが、デバッグの基本です。
このようにして、UnitPriceの動きを見ていくと、
- 「UnitPrice = Cells(2, 2).Value」の行を実行する直前までは、変数に値が格納されていない
- この行を実行した直後(下記画面)の時点で、UnitPriceの値がおかしい
ということがわかります。
繰り返しになりますが、黄色い行で止まっているときには、その「直前の行」まで実行された状態になっている、ということを思い出してください。
このようにして「UnitPrice = Cells(2, 2).Value」の行がおかしそう、ということが絞り込めるわけです。
誤りを修正する
さて、ここで再度元のエクセルシートと見比べてみます。
元データ
元シートを見ると、単価は「C2セル」に入っていました。
ですから、本来は「UnitPrice = Cells(2, 3).Value」と書かないといけませんでした。
この部分を修正すると、プログラムは意図通り動くようになります。
修正後のプログラム
Sub CalculateAmount()
Dim Quantity
Quantity = Cells(2, 2).Value
Dim UnitPrice
UnitPrice = Cells(2, 3).Value
Cells(2, 4).Value = Quantity * UnitPrice
End Sub
その他のデバッグの便利な機能
デバッグをするにあたっては、他にも便利な機能があります。
イミディエイトウィンドウ
イミディエイトウィンドウを使うと、次のようなことができます。
- 通常のマクロとは別画面で、VBAの命令文を実行することができます
-
様々な用途がありますが、代表的な使い方として、最初に「?」を付けて、その後に内容を表示したい「式」を入れると、その「式」の値が表示されます。
イミディエイトウィンドウ
上記画面キャプチャでは、次のような式を入力しています。
入力した式 結果 activecell.Address → $C$2 quantity → 10 quantity*unitprice → 10000 このように、「ブレークポイントでマクロが止まっているとき」や「ステップ実行中」であれば、その時点での「変数」や「式」の値が表示できます。
要は、ウォッチウィンドウの代わりに使うこともできます。
また、次のようなこともできますので、使いこなせると便利です。
- 変数の値を変更する
- Functionプロシージャを実行する
- マクロ内で「Debug.Print文」を使うことで、データを出力することができます。
-
マクロ内で「Debug.Print文」を使うと、イミディエイトウィンドウに、データを出力することができます。
この機能もウォッチウィンドウの代りとして使えます。
ただし、マクロ本体を書き換えないといけませんので、純粋なデバッグ用途のために使うのはあまりおすすめしません。
むしろ、実行時のログ(=実行経過がわかるような情報)の出力用に使うことが望ましいです。
参考
For~Nextループの動きをステップ実行してみる
For~Nextループを、ステップ実行で1行1行動きを追っています。
ループ処理が難しいと感じられるときは、このようにデバッガを使ってみると、動作が理解しやすくなるかもしれません。
元記事はこちら↓
まとめ
VBAでマクロを組もうとすると、意図通りに動かないことは頻繁にあります。
その場合には、このページで説明した機能をうまく使いこなして、デバッグを行いましょう。
次の3つの機能が使いこなせれば、最低限のデバッグはできます。
- ブレークポイント
- ステップ実行
- ウォッチウィンドウ
まずは、この3つの機能を使いこなせるように、練習してみてください。