ウォッチ式で特定の変数を監視する方法
目的とイメージ
ウォッチ式は「気になる変数の値をずっと見張る」ための仕組みです。登録しておくと、コードを動かしている間に値がどう変わるかがリアルタイムで見えます。さらに「値が変わった瞬間で止める」「特定条件を満たしたら止める」こともできます。
ウォッチウィンドウの開き方と基本操作
- ウィンドウを開く: VBAエディタで「表示 → ウォッチウィンドウ」を選ぶ(Alt+F11でエディタ、Ctrl+Gでイミディエイトも便利)。
- ウォッチの追加: コード上で監視したい変数や式を選択し右クリック → ウォッチ式の追加。ウォッチウィンドウの右クリック → 追加 でもOK。
- 何を登録するか:
- 変数名: 例「i」「s」「result」。
- 式: 例「Square(i)」「x * x」「Range(“A1”).Value」。
- 初心者はまず「変数名」から始め、慣れたら「式」も使うと便利。
- コンテキストの設定:
- 現在のプロシージャ(その時止まっている関数内で評価)。
- 現在のモジュール(モジュール範囲)。
- 迷ったら「現在のプロシージャ」で開始し、見えない時はコンテキストを変更。
例題で理解する(合計と二乗)
Sub Main()
Dim total As Long
total = SumUp(3)
Debug.Print "Total=" & total
End Sub
Function SumUp(n As Long) As Long
Dim i As Long, s As Long
For i = 1 To n
s = s + Square(i) ' ← ここにブレークポイントを置くと観察しやすい
Next i
SumUp = s
End Function
Function Square(x As Long) As Long
Square = x * x
End Function
VB- 登録するウォッチ:
- i: ループの回数が今いくつか。
- s: 合計の累積値が今いくつか。
- Square(i): 呼び出し直前に式の評価結果(1→4→9など)を確認できる。
- 観察の流れ:
- ブレークポイント:
s = s + Square(i)に置く。 - F8で1ステップずつ:
- 1周目停止: i=1, s=0, Square(i)=1 → 実行後 s=1。
- 2周目停止: i=2, s=1, Square(i)=4 → 実行後 s=5。
- 3周目停止: i=3, s=5, Square(i)=9 → 実行後 s=14。
- 最後に
SumUp = sで 14 が返り、MainでTotal=14。
- ブレークポイント:
変化や条件で「自動的に止める」設定
- 値が変わったら止める(変化で中断):
- 使い方: ウォッチ追加ダイアログで「ウォッチの種類」を「式の内容が変化したときに中断」に設定。
- 例: グローバル変数
gCountを登録して、誰かが書き換えた瞬間を特定する。
- 特定の条件で止める(真で中断):
- 使い方: 「式が真のときに中断」を選び、条件式を登録。
- 例: ループで
i = 100のときだけ止めたい。ウォッチ式にi = 100を登録。 - 効果: 毎回止まらず、問題の状況だけピンポイントで停止できる。
よくあるつまずきと対策
- ウォッチに値が出ない:
- 原因: そのスコープ(関数)内に変数が存在しない、コンテキストが合っていない。
- 対策: コンテキストを「現在のプロシージャ」に変更、または「現在のモジュール」にして再確認。
- 止まりすぎて進めない:
- 原因: 「変化で中断」が頻繁にトリガー。
- 対策: 一時的にウォッチを無効化(ウォッチウィンドウで右クリック → 無効化)、または「真で中断」に切り替える。
- 関数の内部に入れない(ビルトインなど):
- 事実:
Left,Range.Valueの内部実装にはステップインできない。 - 対策: その前後の値をウォッチで見て、入力と出力の差を確認する。
- 事実:
練習課題(すぐ試せる)
- 課題A(合計の追跡):
- ウォッチ:
i,s,Square(i)を登録。 - 目的: ループ各回の加算結果と累積の動きを確認。
- ウォッチ:
- 課題B(条件停止):
- ウォッチ:
i = 3を「式が真のときに中断」で登録。 - 目的: 最終加算の直前・直後の
sをピンポイントで観察。
- ウォッチ:
- 課題C(グローバルの変化検知):
- 前準備:
Public gCount As Longを宣言し、どこかでgCount = gCount + 1。 - ウォッチ:
gCountを「変化で中断」。 - 目的: どの行が
gCountを更新したか一撃で特定。
- 前準備:
練習課題の解答解説
課題A 合計の追跡(i, s, Square(i) の監視)
対象コード
Sub Main()
Dim total As Long
total = SumUp(3)
Debug.Print "Total=" & total
End Sub
Function SumUp(n As Long) As Long
Dim i As Long, s As Long
For i = 1 To n
s = s + Square(i) ' ← ここにブレークポイント
Next i
SumUp = s
End Function
Function Square(x As Long) As Long
Square = x * x
End Function
VB- ウォッチ登録:
- i: ループの現在値。
- s: 累積合計。
- Square(i): 呼び出し直前の式評価(1, 4, 9 など)。
- 進め方:
- ブレークポイント:
s = s + Square(i)。 - F8で1周ずつ: 停止のたびにウォッチを確認。
- ブレークポイント:
- 期待される観察結果:
- 1周目停止: i=1, s=0, Square(i)=1 → 実行後 s=1。
- 2周目停止: i=2, s=1, Square(i)=4 → 実行後 s=5。
- 3周目停止: i=3, s=5, Square(i)=9 → 実行後 s=14。
- 戻り値:
SumUp = sで 14 が返り、Mainのtotalが 14。
- チェックのコツ:
- 式ウォッチ:
Square(i)を登録しておくと、引数の不整合が一目で分かる。 - 戻り値直前:
SumUp = sにブレークポイントを追加すると「返す瞬間」の値を確定できる。
- 式ウォッチ:
課題B 条件停止(i=3 のときだけ止める)
- 目的: 毎回止めず「狙った状況」だけ観察する。
- 設定手順:
- ブレークポイント:
s = s + Square(i)。 - 条件付きブレーク: 赤丸を右クリック → 条件 → 「式が真のとき」へ
i = 3を入力。
- ブレークポイント:
- 期待される観察結果:
- 停止タイミング: 3回目の加算の直前でのみ停止。
- 停止時の値: i=3, s=5, Square(i)=9。
- 実行後: s が 14 に更新。
- 最終:
total = 14が表示される。
- ポイント:
- 無駄な停止回避: 長いループでも欲しい瞬間だけ止まる。
- 他条件例:
s > 1000やSquare(i) = 25のような「状態ベース」も有効。
課題C グローバル変数の変化検知(変化で中断)
前準備
Public gCount As Long
Sub Bump()
gCount = gCount + 1
End Sub
Sub DemoGlobal()
gCount = 0
Bump
Bump
Debug.Print gCount
End Sub
VB- ウォッチ登録:
- gCount: 「ウォッチの種類」を 式の内容が変化したときに中断 に設定。
- 進め方:
- 実行:
DemoGlobalを開始。 - 停止ポイント:
gCountが書き換わる行(gCount = ...やBump内の代入)で自動的にブレーク。
- 実行:
- 期待される観察結果:
- 初期化後: gCount=0。
- 1回目の更新: 停止時 gCount は 1 へ。呼び出し元に戻ると 1 が保持。
- 2回目の更新: 再び停止、gCount は 2。
- 出力:
Debug.Print gCountで 2。
- ポイント:
- 原因特定に強い: 「どの行が書き換えたか」を自動で捕まえられる。
- 停止過多の回避: 更新が多いなら、一時的に無効化するか、特定モジュールだけに絞る。
つまずき対策のチェックリスト
- 値が表示されない:
- 原因: コンテキスト不一致(別プロシージャ/モジュール)。
- 対策: ウォッチのコンテキストを「現在のプロシージャ」または「現在のモジュール」に合わせる。
- 止まりすぎる:
- 原因: 「変化で中断」の対象が頻繁に更新。
- 対策: 条件付き(真で中断)に変更、もしくは一時的に無効化。
- 思った行で止まらない:
- 原因: その行を通っていない、または条件が満たされていない。
- 対策: 実際に通過する行に置き直す/条件式を確認。
まとめの指針
- 入口・副作用・戻り値直前にブレークポイント、重要変数・式をウォッチ登録。
- 条件付き・変化で中断を使い分けて、問題が起きる「その瞬間」を的確に捕まえる。

