VBA-Tips

【解説】VBAプログラミングで覚えるべき「デバッグ」の考え方とやり方

 

VBAで業務効率化マクロを作りたいが、そもそも作り方が分からない。

その第一歩を進めるために必要な知識として「デバッグ」というものがあります。

これはプログラマーやエンジニアはだれしも知っていて、プログラミングをするときは必ず実施している「デバッグ」の考え方とやり方を説明していきます。

 

当記事はVBAを対象にしてますが、プログラムの基本原則は他の言語でも同様になっています。

 

デバッグとはプログラムの不具合を見つけるもの

デバッグとは英語で書くと「debug」→「de + bug」となります。

「de」は減少させるという意味があり、「bug」は虫なので、虫を取り除くという意味になります。

また、コンピュータ用語では「バグ」は「不具合」を示す言葉なので、デバッグとは「不具合(≒予期せぬ動作)を見つけて修正するための行動」のことを指しています。

 

プログラミングというものは、実現したい結果を得るため完璧にコーディングしたつもりでも、ほぼ100%の確立で思ったような結果(=予期している理想の状態)にはなりません。

 

通常のプログラミングでは理想の結果になるために、コードの修正を何度も繰り返して、なるべく完璧に近づけることで、徐々にシステム(≒Excel VBAで言うところのマクロ)を完成に近づけていきます。

 

その際に、コードを修正する必要がある部分は「不具合」と呼び、不具合を直す動作を「デバッグ」と呼びます。

デバッグには、大きく分けて二つあります。

  • 仕様通りに動かない部分を発見して修正すること
  • プログラム上の欠陥(エラー)を発見して修正すること

以下でそれらを解説していきます。

 

仕様通り動かない部分を発見して修正する

まず一つ目の「仕様通り動かない部分を発見して修正する」というのは、例えば以下のような状況です。

Excelで現在開いているシート「Sheet1」のセル「A1」に「テスト」という文字を入れたいが、プログラムを動作させてみると、エラーは起こらなかったが「Sheet2」のセル「A1」に「テスト」という文字が入ってしまった。

つまり、エラーは起こってないが予定していたシートと異なるシートに値が挿入されてしまった

このように思った結果にならなかった場合などにプログラムを修正することです。

つまり、仕様(≒実現させたい結果)通りに動かなかった原因となるプログラムのコード部分(コードの何行目なのか?)を見つけて、仕様通り動くようにコードを書き直すことです。

 

プログラム上の欠陥を発見して修正する

二つ目の「プログラム上の欠陥を発見して修正する」というのは、例えば以下のような状況です。

Excel内の現在表示されているシート「Sheet1」のセル「A1」に「1a」という英数字を入れたいかったが、プログラムを実行させてみると「1」(数値)と「a」(文字)を足し算しようとしてエラーが発生してしまった。

つまり、プログラム上でエラーがあり、それ以降のプログラムに処理が進まなかった

このような場合にエラーが発生しないようにプログラムを修正することです。

このようにプログラムの動作中に予期せぬ状態に陥ってしまってプログラムが正常に動作せずエラー(例:数値と文字列で型が一致しないエラー)が起きてしまった場合に、そもそもエラーが起きないようにするか、エラーでも処理が止まらず処理を続けるようにコードを書き直すことです。

 

【おすすめ6選】最初に覚えるVBAデバッグ手法

覚えるべき手法6選はいずれも多用する手法です。

以下で紹介する方法以外にも手法はありますが特に使用頻度が高いと思う6つを紹介します。

 

ブレークポイントを設定して処理を止める

「ブレークポイント」とは強制的に実行を一旦停止する箇所のことです。

プログラムの処理を途中で止めることができるブレークポイントをコードの途中に設定して処理を一旦止めることができます。

しかし、変数宣言のみの行などブレークポイントが置けない箇所もあります。

  • VBAでのショートカットキー:F9

 

必要に応じて処理を途中で終了させる「リセット」を使用することで、最後まで処理が実行されることを防ぎます。

最後まで実行させると、初期のデータ等が変わってしまい後々面倒くさくなる場合などに「リセット」を使っています。

  • VBAでのショートカットキー:Alt+RR

 

ステップインで1行ずつプログラムを進める

「ステップイン」はプログラムを上から順に1行ずつ進めることができるコマンドです。途中でプロシージャ(プログラム内で処理などを一つにまとめ、他から呼び出し可能にしたもの)があった場合は、そのプロシージャへ処理が移動して1行ずつ進んでいきます。

ステップインを使用すればそのプログラムの全体の流れを把握できるので、わたしは一番多用しています。

  • VBAでのショートカットキー:F8

 

ステップオーバーでプロシージャの中に入らず1行ずつ進める

「ステップオーバー」は途中のプロシージャ内に入らずにプログラムを上から順に1行ずつ実行するコマンドです。

ステップインと同様にプログラムが1行ずつ進めることができますが、途中でプロシージャ(例:Call ●● で呼び出せる処理)があった場合でもプロシージャ内に入らず、現在実行している処理から他の処理のかたまりに大きく移動することがありません。

メイン処理の途中にある別のプロシージャではどのような処理が行われているか把握できていて不具合もないことが判明している場合は、「ステップオーバー」を使って実行しているプログラムを先へ進めていきます。

  • VBAでのショートカットキー:Shift + F8

 

プログラムの実行でプログラムの最後まで処理する

「プログラムの実行」は途中でとまることなくプログラムを最後まで一気に実行させることができるコマンドです。

※プログラムの実行という言葉は、普通に会話で使われる単語なので混乱してしまいますが、そのような文言のコマンドがあります。

コードを上から順に1行ずつ進むということがないため、途中でブレークポイントがなければ処理が終了するまでプログラムが流れます。

プログラムに不具合がありそうな個所(デバッグしようとしたコード)を通過した後に、その後のコードを確認する必要がない場合に「プログラムの実行」を使います。

  • VBAでのショートカットキー:F5

 

ウォッチウィンドウで変数やプロパティの値を確認する

ウォッチウィンドウ」はプログラムで使用されている変数やプロパティの値を調べる際に使われる機能です。

プログラム実行中に変数(値を格納できる入れ物)に想定している値が正しく入っているかを確認する際に使用します。

 

VBEの上部メニューの「表示」→「ウォッチ ウィンドウ」をクリックすると表示されます。

またはVBE上でショートカットキー:AltVHでウォッチウィンドウを開くことができます。

 

コード上の変数を選択して、右クリック→「ウォッチ式の追加」を選択するとウォッチウィンドウに変数が追加されます。この状態でデバッグを行えば、ウォッチウィンドウにある変数に何の値が入っているかを常時確認できます。

 

注意点として、ウォッチウィンドウで確認したい変数がある行の処理が通過していないと、対象の変数内に値が入っていませんので、必ず行を通過した後に値を確認してください。

 

イミディエイトウィンドウで処理の結果を確認する

「イミディエイトウィンドウ」は変数の値を出力したり、ステートメントを実行できる機能です。

変数の値はもちろん、変数を使用した計算結果などを自由に表示させることができます。

 

VBEの上部メニューの「表示」→「イミディエイト ウィンドウ」をクリックすると表示されます。

またはVBE上でショートカットキー:CtrlGでイミディエイトウィンドウを開くことができます。

 

この部分では、処理の結果であったり、debug.print関数で出力した結果を表示できます。

また、イミディエイトウィンドウには直接値を入力することができるため、例えば変数の値を調べたい場合は、「?変数名」と入力してEnterキーを押すと、変数名の値が表示されます。

処理の結果を出力する場合は、MsgBox関数を使用するのも簡単で良いと思います。

プログラム上で、「MsgBox 変数名」を記載すればポップアップで別ウィンドウが立ち上がり変数の値が表示されます。

 

デバッグの具体的な手順

デバッグに決められた手順はないですが、私は主に以下の手順で行っています。

  1. プログラムの最初に「ブレークポイント(F9)」を置く。
  2. ブレークポイントで実行が止まった行から「ステップイン(F8)」を繰り返して、処理の全体の流れを見ながら、部分的に予期せぬ結果になっていないか細かく確認します。
  3. 部分的に予期せぬ結果になっていた場合は、その原因がどこにあるかをウォッチウィンドウに変数の結果を表示させたり、イミディエイトウィンドウに計算結果を表示させて原因となっているコードを突き止めてプログラムを修正します。
  4. 問題がなければ、「ステップオーバー」などで次の処理群まで実行中の行を進めてて、改めて部分的に予期せぬ結果になってないか確認をします。
  5. 途中の問題ないことが判明したプログラム部分があった場合は、その後に「ブレークポイント(F9)」を置いて、「プログラムの実行(F5)」により現在の実行中の行を先にあるその後の処理群まで飛ばします。

大まかに、この①~⑤を繰り返し行うことでデバッグができ、本来の実現したい状態に近づけていきます。

 

またVBEと実行結果(例えばExcel)を横並びで画面に表示させながら実行すると、並行して結果が正しいか確認しながら進めることができ、効率的にデバッグができると思います。

 

おまけ:人間は予期せぬ動作をするもの

作ったマクロを使う人間が予期せぬ動作をした場合でも、プログラムが止まらず動作するように作成しなければいけません。

例えば、数値を入力すべきところを、誤って文字列を入力してしまうことなど往々にしてあります。

ただ、ある程度は想像を働かせて問題なく動くように対応できますが、人間の行動というのは無数に存在していて全てを対応していてはきりがないので、システムを使う人間のリテラシーや範囲などを考えて作ればよいと思います。

 

デバッグをする以外でも気を付けること

デバッグはそのプログラムが問題なく動き、実現したい結果になるための方法ですが、動けばなんでも良いかというとそうではありません。

プログラムのもう一つの目指す姿は自分以外の人がそのプログラムを見たときに理解しやすいプログラムです。

綺麗なプログラムを作るよう心掛けて下さい。