アナログCPU:5108843109

ゲームと音楽とプログラミング(酒と女とロックンロールのノリで)

('ω') < イザユケエンジニャー

ExcelVBA入門 #7:デバッグのコツ

シリーズもくじはこちら

ExcelVBA入門 もくじ - アナログCPU:5108843109

今回から応用編です。

はじめに

エラーが出たときや想定外の結果になったとき…
サンプルのような数行のプログラムであれば、コードをよく見直せば間違いに気付くのも簡単です。
しかし、長いプログラムを書くようになってくると、なかなかそうはいかないケースがよくあります。

今回は、そういうときのデバッグのコツをいくつか紹介します。
実際に試しつつご覧ください。

まずデバッグ以前に…

エラーが出たとき、プログラムは実行中のままエラー箇所で一時停止(中断)している場合があります。

f:id:honey8823:20150902125813p:plain

このように、タイトルバーに[中断]と出ていたり、黄色い矢印とハイライトが出ている状態が目印です。
黄色い行の直前までは実行済みです。
この状態のまま再度実行しようとすると、黄色い行から再開されます。
(実行操作については通常の実行と同じです)

このままデバッグをしたいときはそれでよいのですが、最初から実行したいときは一度終了させる必要があります。
 実行>リセット
を選択するか、赤丸で囲んだ■を押すと止めることができます。

また、中断状態のままコードを修正することもできますが、修正中に以下のメッセージが出ることがあります。
(例えば、変数宣言部分の変更などで出ます)

f:id:honey8823:20150902125825p:plain

よくわからない文章ですが、意訳すると「この修正するなら中断中のプログラムは終了させるよ」ということです。
なので、「OK」なら修正を反映しつつ実行中だったプログラムを終了、「キャンセル」なら修正内容が破棄されて実行状態はそのままになります。
また、キャンセルを選んで破棄されるのはその時修正した行だけなので、大量に修正している途中でも大丈夫です。

もうひとつ、実行中にフリーズしてしまったとき。
これは諦めてExcel自体を強制終了しましょう。
タスクマネージャーを起動し(Ctrl+Shift+Escで起動します)
アプリケーションタブから該当のタスクを選んで「タスクの終了」で終了させます。
これで「数時間分の作業が全部吹っ飛んだ!」なんてことになるのを防ぐため、実行前の保存は必須なのです。

デバッグの準備

「ウォッチ」「イミディエイト」の2つのウインドウを出しておきましょう。
両方ともメニューの「表示」から選択すると表示されます。

ウインドウの配置などはもちろん動かせるので、後々使いやすいように調整していくと良いです。

f:id:honey8823:20150904103937p:plain

ブレークポイントを設置する方法

デバッグをする時、「ここで一旦動きを止めてほしい!」という時があります。
そういう時は止めたい箇所に「ブレークポイント」を設置してから実行すればOKです。

ブレークポイントを置いたり消したりするには、

  • 止めたい箇所にカーソルを置いた状態で「デバッグブレークポイントの設定/解除」
  • 止めたい箇所にカーソルを置いた状態で「F9」を押す
  • 止めたい箇所の左側のグレーのエリアをクリックする

のいずれかでOKです。
空行や変数を定義しているところなど、ブレークポイントを設置できない箇所もあります。
ブレークポイントが設置されると、このように赤い目印が付きます。
複数設置することもできます。

f:id:honey8823:20150904110801p:plain

この状態で実行すると、ブレークポイントの位置で中断状態になります。
中断状態については先に書いたとおりで、続きから実行することもできますし、終了させることもできます。

処理を一つずつ実行する方法(ステップ実行)

では処理を順番に一つずつ実行させて確認して…を繰り返したいとき、すべての行にブレークポイントを設置するのかというと、そういうわけではありません。
そういうときは「ステップ実行」で確認します。

プログラムが実行されていない状態でも中断状態からでも、

のいずれかを押下すると、処理がひとつ実行されます。

確認を始めたい箇所にブレークポイントを張って実行し、そこからステップ実行…という合わせ技で手っ取り早く確認できます。

とりあえずステップ実行についてはこういうやり方を覚えておけば問題ありませんが、
「ステップ オーバー」「ステップ アウト」というものもあります。
参考サイトへのリンクだけ貼っておきますので、興味と余裕のある方はご覧ください。

参考:ステップ実行 - 自宅でプログラミング!
http://www.239-programing.com/excel-vba/basic/basic023.html

データ型変数の中身を簡単に確認する方法

ステップ実行ができると「プログラムがどこを通って動いているか」を確認できます。それだけでも得られる情報は多いのですが、中断中に「今この変数に入ってるのは何?」ということを確認したくなることも多々あります。

そういう時、一番手っ取り早く確認できるのは「変数にマウスカーソルを乗せる」です。
コード中の変数にマウスカーソルを乗せると、静止している間、現在の値が表示されます。

f:id:honey8823:20150907132015p:plain

変数でなくとも、以下のようなものもOK。
ただし、オブジェクト型変数やオブジェクトそのものの中身は表示することができません。
(例えば、以下コードを「Range("A" & i + 1) = i」としているとNG)

f:id:honey8823:20150907132027p:plain

これは実際にA1セルを見てみるのと同じことですね。
黄色い行はまだ実行されていないのでセルの中身はEmpty、つまり空っぽです。
ステップ実行で1つ進めると、同じところにマウスカーソルを当てると値が変わっているのを確認してみてください。

変数の中身を確認する方法(ウォッチウインドウ)

では、オブジェクトの中身を見たい場合は…というと、「ウォッチウインドウ」を使用すればOKです。
もちろん、数値や文字列などのデータ型変数も見ることができます。

使い方としては、まず、見たいものを選択してドラッグ&ドロップでウォッチウインドウに貼り付けます。
(エディタかウォッチウインドウを右クリックで「ウォッチ式の追加」も可能ですが、面倒なのでわざわざ覚える必要はありません)

f:id:honey8823:20150907142014p:plain

この状態でコードを実行して中断状態にすると、その時点での中身を見ることができます。

f:id:honey8823:20150907142324p:plain

単純に数値や文字列が入っているだけのデータ型変数であれば1行だけわかりやすく表示されますが、
オブジェクト型となるとこのようにたくさんの情報がツリー式で入っていますので、目的のデータを探してください。

たとえばここに表示されている内容なら、
「Column」は何行目かという情報、「Count」はRangeに含まれているセル数…など。

デバッグ用コードを埋め込む方法

デバッグ用のコードを埋め込んで、各処理の確認を行う方法もあります。

例えば「この処理、本当に動いてるのかな?」というとき。
処理の前後に「MsgBox "test"」などと埋め込んでおけば、そこは確実に通っていることが分かります。

もしくは「100回繰り返す処理の50回目での変数の値を確認したいけど、50回もステップ実行したくない…」というとき。
一時的に「If i = 50 Then ...」というようなIf文を埋め込むことで、その中の処理にブレークポイントを張ることもできます。

また、変数の中身などを「イミディエイトウインドウ」に出力させるコードを埋め込むこともできます。

Debug.Print a

これで変数aの中身をイミディエイトウインドウに表示できます。
使い方としてはこんな感じ。

f:id:honey8823:20150907145357p:plain

このように繰り返し処理の中に入れておくと、1周ずつステップ実行して変数にカーソル当てて…なんてやらなくても、変数の変化をまとめて確認できます。

また、余談ですが、イミディエイトウインドウは他にも使い道がある(ということに、これを書きながら気付いた)のでご紹介しておきます。
ちょっとした小技ですが役立つかもしれませんので、余裕のある方は見てみてください。

イミディエイトウインドウの使い方と挙動 - アナログCPU:5108843109

まとめ

いかがでしたでしょうか。
あくまでデバッグ用の技なので一気に全部マスターする必要はありませんが、パターンによって使い分けられると快適なデバッグができますので、少しずつ活用して慣れていくとよいと思います。

次回予告

ExcelVBA入門 #8:ググらずマニュアル見ずスピード解決する方法 - アナログCPU:5108843109
次回もちょっとした小技、「どう書けばいいか分からないとき、ググるよりもマニュアル見るよりも早く解決する方法」です。
小枝たべたい。