和風スパゲティのレシピ

日本語でコーディングするExcelVBA

値・状態の変更を検知する - ウォッチウィンドウ

マクロの不具合検証やバグ取り(デバッグ)を行っているとき、
その不具合がいつ起きたか」を知りたいことがよくあります。


どこがおかしいかは分かるがいつおかしくなったかが分からない」ときですね。

そんなとき、値や状態の変更を検知できる「ウォッチウィンドウ」が活躍します。

ウォッチウィンドウ(ウォッチ式)の設定

「ウォッチ式の内容が変化したときに中断」機能

今回は「ActiveSheetがいつの間にか変わってしまった」問題を題材にしてみます。

いつ変わったのかを調べるために、コード各所に

Debug.Print ActiveSheet.Name

を散りばめるのは大変ですからね。


こんなときこそウォッチウィンドウを使ってみましょう。

  • コード上で右クリック→ウォッチ式の追加
  • デバッグタブ→ウォッチ式の追加

いずれかの方法でウォッチ式の追加ダイアログを表示し、
今回は「ActiveSheet.Name」をウォッチ式に追加してみます。

ウォッチ式の追加(式の内容が変化したときに中断)

ウォッチ式の追加は上記のウィンドウで行うのですが、
左下にある「ウォッチの種類」を設定できるのがポイントです。


ウォッチの種類を「式の内容が変化したときに中断」にしておくと、
設定した式の値が変わったタイミングでコードを一時停止させることができます。


試しに適当なコードで実行してみると、
こんな風にActiveSheetが変わった直後のコードでマクロが停止してくれます。
一時停止されたコード

※ このとき「i」は24637になっています。


便利ですね!


この設定を使用することで、値や状態が変わった瞬間を捉え、
不具合を起こす原因のコードがどこにあったかをすぐ調べることができます。


「どこがおかしいかは分かるがいつおかしくなったかが分からない」ときは
ウォッチウィンドウを活用して素早く原因を特定しましょう。

「ウォッチ式が特定の条件を満たしたときに中断」機能

さて先ほどの「ウォッチの種類」にはもう一つ、
式がTrueのとき中断」という設定があります。


例えば「計算結果が0になってしまった瞬間を捉えたい」としましょう。


このときはウォッチ式に「計算結果=0」などTrue/Falseが返る条件式を入力し、
ウォッチの種類を「式が True の時に中断」に設定します。

ウォッチ式の追加(式が True の時に中断)

こうすることで、値がただ変更されたタイミングではなく、
特定の値になった瞬間をとらえることができます。


この設定も便利ですので状況に応じて使い分けてください。

実行速度低下やアクセスによる状態変化に注意

さて便利なウォッチウィンドウですが、こんな風に変更を検知できるわけですから、
当然ながら追加したウォッチ式はマクロ全行で常に計算される仕様です。


今回の例でも、10万回以上ActiveSheetのNameが調べられるため、
かなりの速度低下が発生してしまいます。


また、ウォッチ式は常に実行されてしまう性質上、
「アクセスすることで状態が変わる式」を書くと本体マクロに影響してしまいます。


例えば「次のファイルを検索するDir関数」をウォッチ式に使ってしまうと、
すべての行で次のファイルを検索してしまいあっという間にDir()が""になります。


他には少しマニアックですが、

  • Dim ○○ As New △△ で宣言と同時にNewしたオブジェクト
  • Dictionaryの未登録KeyによるItem取得

など、「はじめてアクセスされたときに何らかの実行がなされるコード」は、
ウォッチ式に書いてしまうとウォッチ式で初実行が起こってしまいます。


どこでエラーが起きているかわかっている場合は、Stopステートメントを活用した

If ActiveSheet.Name <> "○○" Then Stop

If 計算結果 = 0 Then Stop

などで十分対応できますので、こちらと使い分けていきましょう。


繰り返しになりますが、ウォッチ式の使いどころは
どこがおかしいかは分かるが、いつおかしくなったかが分からない
ときと覚えておいてください。

適材適所で使っていきましょう。