ステップイン(F8)とステップオーバー(Shift+F8)の違い
概要
VBAのステップ実行は「どこまで踏み込むか」の違いが肝です。ステップイン(F8)は呼び出し先のプロシージャ・関数の中へ入り、行ごとに追跡します。ステップオーバー(Shift+F8)は呼び出し先には入らず、その呼び出しを丸ごと実行して次の行へ進みます。使い分けることで、問題箇所を素早く特定できます。
基本の挙動と使い分け
- ステップイン(F8):
呼び出し先に入り、内部の処理を1行ずつ確認します。ロジックを精査したい、引数の受け渡しや副作用をチェックしたい場合に適しています。 - ステップオーバー(Shift+F8):
呼び出し先には入らず、その行の呼び出しを一括で実行します。呼び出し先が信頼できる・詳細追跡の必要がないときに、現在のプロシージャの流れを素早く確認できます。 - 補足(ステップアウト:Ctrl+Shift+F8):
いま入っているプロシージャを最後まで実行して、呼び出し元に戻ります。深く入りすぎた時の「戻るボタン」。
例題 1:プロシージャ呼び出しの違いを体感
Sub Main()
Dim total As Long
Debug.Print "Start"
total = SumUp(5) ' ←ここでF8ならSumUpに入る、Shift+F8なら入らない
Debug.Print "Total=" & total
Debug.Print "Done"
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) ' ←F8ならSquareへさらに入る、Shift+F8なら入らない
Next i
SumUp = s
End Function
Function Square(x As Long) As Long
Square = x * x
End Function
VB- F8(Mainの行 total = SumUp(5)): SumUpへ入り、さらにSquareへも入って、1行ずつ内部を確認できます。引数の流れや戻り値の作られ方を追跡したいときに最適。
- Shift+F8(同じ行): SumUpを内部まで見ずに一気に実行し、次のDebug.Printへ進みます。SumUpの正しさが前提ならこちらが速いです。
例題 2:ByRefの副作用を追うかスキップするか
Sub DemoByRef()
Dim a As Long, b As Long
a = 10: b = 3
Adjust a, b ' ←F8ならAdjustの中へ入り、a/bの変化を逐次確認できる
Debug.Print "a=" & a, "b=" & b
End Sub
Sub Adjust(ByRef x As Long, ByVal y As Long)
x = x + y ' ByRefなので呼び出し元のaが変わる
End Sub
VB- F8: Adjust内でxがどう変わり、呼び出し元のaが更新される瞬間まで確認できます。
- Shift+F8: 副作用をまとめて受け止め、結果だけを次行で確認します。副作用の「原因を追いたい/追わない」で使い分けます。
例題 3:エラー発生箇所の特定
Sub DemoError()
On Error GoTo Handler
Debug.Print Divide(10, 0) ' ←F8ならDivide内で0割りに到達する瞬間がわかる
Exit Sub
Handler:
Debug.Print "Error: " & Err.Number & " " & Err.Description
End Sub
Function Divide(a As Double, b As Double) As Double
Divide = a / b ' 0割り
End Function
VB- F8: Divideの該当行でエラーが発生する瞬間を確認でき、どの引数が問題かを特定しやすい。
- Shift+F8: 呼び出しをまとめて実行するため、エラーは呼び出し元のHandlerで受けます。原因追跡には不向きですが、ハンドリングの動作確認は効率的です。
例題 4:イベント・組み込み関数・外部呼び出し
Private Sub Worksheet_Change(ByVal Target As Range)
LogChange Target
End Sub
Sub LogChange(ByVal r As Range)
Debug.Print "Changed: " & r.Address
End Sub
VB- イベントへ入るタイミング: イベントが発火した後にブレーク(停止)していれば、F8でイベント内を追えます。
- 組み込み関数(例:Left、Range.Valueなど): その内部実装には基本的にステップインできません。行を実行して結果だけが返ります。
- 外部ライブラリ/COM呼び出し: 型情報やデバッグシンボルがない場合、内部へは入れないことが多く、実行結果のみが戻ります。ここでもステップオーバー相当の挙動になります。
実践のコツ
- 問題の「範囲」を絞る: まずShift+F8で上位の流れを確認し、怪しい呼び出し行が絞れたらF8で中へ入って詳細を確認します。
- ウォッチとイミディエイトの併用:
- ウォッチ: 変数・式の値を監視して、F8で変化点を見つける。
- イミディエイト:
?変数名で即値確認、Debug.Printでログを残す。
- ブレークポイントを活用: 呼び出し先の入口にブレークを置いてからShift+F8で進めると、必要な箇所だけ中に入れます。
- 深追いしすぎたらステップアウト: Ctrl+Shift+F8で呼び出し元へ戻り、全体の流れに復帰。
まとめ
- F8(ステップイン): 呼び出し先の内部を1行ずつ検証。原因究明・ロジック精査に最適。
- Shift+F8(ステップオーバー): 呼び出し先には入らず、現在のプロシージャの流れを素早く確認。局所化・効率化に便利。
- 併用が最強: 上位はオーバーで流れ把握、怪しい箇所はインで掘る。必要に応じてアウトで戻る。

