Excel VBA | VBAで関数の中にブレークポイントを設定する方法

VBA
スポンサーリンク

目的とイメージ

はじめてのデバッグでは「ブレークポイント」は止まるための“しおり”です。関数の中でも置けます。関数が呼ばれたとき、その行で一時停止し、値を確認したり一歩ずつ進められます。


基本の手順

  1. VBAエディタを開く
    • Alt+F11でVBAを開く。対象のモジュール(標準モジュールやシートモジュール)を表示。
  2. 止めたい行を選ぶ
    • 関数の中で「この行で止めたい」という行にカーソルを置く。
  3. ブレークポイントを付ける
    • F9キーを押す、または左の灰色余白をクリック。
    • 赤い丸(左)と行の赤ハイライトが付けば設定完了。
  4. コードを実行する
    • 関数が呼ばれると、ブレークポイントの行で停止。
    • 変数の値を見たり、F8(ステップイン)で1行ずつ進められる。

まずは動かす例(超基本)

Sub Test()
    Dim result As Long
    result = Square(5)      ' ← 実行するとSquareが呼ばれる
    Debug.Print result
End Sub

Function Square(x As Long) As Long
    Square = x * x          ' ← この行にブレークポイントを置く
End Function
VB
  • やること: Square関数の「Square = x * x」にブレークポイントを付ける。
  • 実行: Testを実行すると、その行で止まる。
  • 確認ポイント:
    • ウォッチ: 変数xの値が「5」になっているか。
    • F8: 次の行へ進めて、戻り値がどう作られるか確認。

“中でさらに関数を呼ぶ”場合の止め方

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
  • コツ: まずSumUpの「s = s + Square(i)」にブレークポイント。値の積み上がり(sの変化)と引数(i)を確認。
  • さらに細かく: Square内にもブレークポイントを置けば、引数xの実際の値と戻り値の作成を1回ずつチェックできる。

ByRefの“呼び出し元が変わる”例

Sub DemoByRef()
    Dim a As Long, b As Long
    a = 10: b = 3
    Adjust a, b                 ' ← ここを実行するとaが書き換わる
    Debug.Print "a=" & a, "b=" & b
End Sub

Sub Adjust(ByRef x As Long, ByVal y As Long)
    x = x + y                   ' ← ここにブレークポイント。x(=a)の変化を確認
End Sub
VB
  • ポイント: ByRefで渡されたxは呼び出し元aと同じ“実体”。この行で止めてx・yの値を見れば、なぜaが変わるか納得できる。

ブレークポイントの便利ワザ

  • 条件付きブレークポイント
    • 使い方: ブレークポイント(赤丸)を右クリック → 条件。
    • 例: ループ中、i = 10のときだけ止めたい(「式が真のとき」へ i = 10)。
    • 効果: 無駄に毎回止まらず、問題の状況でだけ停止。
  • 一時的に無効化
    • 赤丸を右クリック → 無効化。赤丸に斜線。
    • 設定は残したまま実行を邪魔しない。
  • 複数の止め点
    • 関数の入口、ループの中、戻り値代入の直前など複数に置くと、流れが見えやすい。

画面で見られる情報(初心者が最初に見る場所)

  • イミディエイトウィンドウ(Ctrl+G)
    • ? 変数名 と入力すると、その場で値を表示。
    • 例:? x? s で現在値を確認。
  • ウォッチウィンドウ
    • 変数や式を登録して、値の変化を自動表示。
    • 例:siSquare(i) を登録すると、ステップ実行で変化が追える。
  • ローカルウィンドウ
    • 現在のプロシージャで有効な変数を一覧表示。関数に入った瞬間の値が一目で分かる。

よくあるつまずきと対策

  • 止まらない(ブレークしない)
    • ラベル: ブレークポイントの行が実行されていない(条件分岐の外など)。
    • 対策: 実際に通る行に置き直す、または呼び出し元にブレークポイントを追加。
  • ビルトイン関数の中には入れない
    • Left, Range.Value などの内部実装にはステップイン不可。
    • 対策: その前後の行で値を確認する。
  • イベントで予期せず動く
    • Worksheet_Changeなど、入力で勝手に発火。
    • 対策: 必要なイベントの冒頭にブレークポイントを置き、いつ発火したかを確認。

練習課題(自分の手で確かめる)

  1. 課題A:合計関数
    • SumUpのループ内にブレークポイントを置き、isの変化を1回ずつ確認。
    • 条件付きブレークで「i=3のときだけ止まる」を設定してみる。
  2. 課題B:ByRefの確認
    • Adjustの行で止めてxyを確認。再開後、aがどう変わるかイミディエイトで ? a を表示。
  3. 課題C:戻り値の追跡
    • Squareの行で止め、xの値を見てからF8。Main側で result の値がどう出るか確認。

練習課題の解答解説

課題A 合計関数のループでの値の追跡

対象コード

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
  • 目的: ループ中の各周回で、変数の増え方を確認する。
  • 手順:
    • s = s + Square(i) 行にブレークポイントを置く。
    • Mainを実行し、停止したらF8で1周ずつ進める。
    • ローカル/ウォッチで is の値を確認。
  • 観察:
    • 1周目停止時: i = 1Square(1) = 1、実行後 s = 1
    • 2周目停止時: i = 2Square(2) = 4、実行後 s = 5
    • 3周目停止時: i = 3Square(3) = 9、実行後 s = 14
    • ループ終了後: SumUp = 14 が返り、Mainで Total=14 と表示。
  • 条件付きブレークポイント:
    • 設定: 赤丸を右クリック → 条件 → 「式が真のとき」に i = 3
    • 効果: 3周目のときだけ停止。最終加算の直前の s5 であること、加算後 14 になることを一発確認。
  • ポイント:
    • 引数の確認: Square(i) をウォッチ登録すると「呼び出し前の式評価結果」を常時見られる。
    • 戻り値タイミング: SumUp = s 行の直前に追加でブレークポイントを置くと、最終値が返る瞬間を確実に捉えられる。

課題B ByRefの副作用の確認

対象コード

Sub DemoByRef()
    Dim a As Long, b As Long
    a = 10: b = 3
    Adjust a, b
    Debug.Print "a=" & a, "b=" & b
End Sub

Sub Adjust(ByRef x As Long, ByVal y As Long)
    x = x + y     ' ← ここにブレークポイント
End Sub
VB
  • 目的: ByRefで渡された変数が呼び出し元で書き換わる仕組みを体感する。
  • 手順:
    • x = x + y にブレークポイント。
    • DemoByRef を実行し停止したら、ローカルで xy を確認。
    • F8で実行してから、イミディエイトで ? a をチェック。
  • 観察:
    • 停止直後: x = 10(aの参照)、y = 3(値渡し)。
    • 実行後: x = 13 に更新。呼び出し元へ戻ると a = 13b = 3 が維持。
    • 出力: a=13 b=3
  • ポイント:
    • ByRefの本質: xa の別名。x を変えれば a が変わる。
    • 誤解防止: ByValy は別物。DemoByRef 側の b は変更されない。
    • デバッグのコツ: Adjustの前後で ? a, b を出して差分を明示する。

課題C 戻り値の生成と受け取りの追跡

対象コード

Sub Test()
    Dim result As Long
    result = Square(5)   ' ← 呼び出し行にブレークポイントを追加してもOK
    Debug.Print result
End Sub

Function Square(x As Long) As Long
    Square = x * x       ' ← ここにブレークポイント
End Function
VB
  • 目的: 関数内で戻り値が作られ、呼び出し元の変数に格納される流れを確認する。
  • 手順:
    • Square = x * x にブレークポイント。
    • Test を実行、停止したら x の値を確認(5)。
    • F8で代入を実行してから、呼び出し元へ戻る。
    • result の値をローカル/イミディエイトで確認。
  • 観察:
    • 関数内: x = 5、代入後の戻り値は 25
    • 呼び出し元へ復帰: result = 25
    • 出力: 25
  • ポイント:
    • 戻り値の代入タイミング: Square = ... の行が実質的な「return」の役割。
    • 呼び出し側の確認: 呼び出し行にもブレークポイントを置くと、「呼ぶ前の result は未定義」「戻り後に確定」の差分が見やすい。
    • 式のウォッチ: x * x をウォッチ登録すると、評価結果(25)を事前に確認できる。

総合的なチェックリスト

  • ブレークポイント位置:
    • 入口、副作用が起きる行、戻り値代入直前に置くと全体が掴みやすい。
  • ウォッチ/ローカル/イミディエイト:
    • ウォッチ: 重要な変数・式を登録して変化を継続監視。
    • ローカル: 現在スコープの全変数の現在値を一覧で把握。
    • イミディエイト: ? 変数 で即時確認、Debug.Print を併用してログ化。
  • 条件付きブレーク:
    • ループや多回呼び出しでは「問題の状況」でだけ止める設定が効率的。

まとめ

  • ブレークポイントは「その行で止める」目印。関数の中でも普通に置ける。
  • F9で設定、Alt+F11でエディタ、イミディエイト/ウォッチで値を確認。
  • 条件付きや複数設置を使うと、無駄なく“問題の瞬間”を捕まえられる。
VBA
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました