では 「練習問題 1〜3」の模範解答を“ステップ実行しながら学べる形” で、1行ずつ何が起きているかを詳しく説明します。
- 初心者向けに、F8(ステップイン)でどう見えるか
- ローカルウィンドウで何を確認すべきか
- どこでバグが起きやすいか
も含めて丁寧に解説します。
事前準備:ステップ実行の使い方(超重要)
- Excel → Alt + F11 で VBA エディタを開く
- モジュールを開く
- 上のバーの
[表示] → [ローカルウィンドウ] を ON にする(変数の中身が見える) - Sub(テスト用)を作って、そこで F8 で実行していく
- 黄色い部分が「これから実行する行」
- 値が変わる瞬間をローカルウィンドウで確認する
問題1:成績(A/B/C/D)を返す関数
コード(再掲)
Function Grade(score As Integer) As String
If score >= 90 Then
Grade = "A"
ElseIf score >= 80 Then
Grade = "B"
ElseIf score >= 70 Then
Grade = "C"
Else
Grade = "D"
End If
End Function
Sub TestGrade()
Dim r As String
r = Grade(85)
Debug.Print r
End Sub
VBステップ実行の解説
1行目:Sub TestGrade()
F8 → 黄色がここに来るだけ。処理はまだしていない。
2行目:Dim r As String
F8 → 変数 r がローカルウィンドウに登場。
- 値=
""(空文字) - 型=String
3行目:r = Grade(85)
F8 → 関数の中へ飛びたい場合は「F8」ではなく「F8 もう一度」または「F11」
- 今は Sub 内の「呼び出し」の行に黄色がある状態
- F8 を押すと Grade の中にジャンプ
関数の最初:Function Grade(score As Integer)
ローカルウィンドウに新しい変数が登場:
| 変数 | 値 | 型 |
|---|---|---|
| score | 85 | Integer |
| Grade | “” | String |
関数名「Grade」も変数扱いで表示され、
「これが戻り値になる変数」 として扱われる。
If score >= 90 Then
85 >= 90 → False
- このブロックには入らず
- 自動的に「ElseIf score >= 80」へ飛ぶ
ElseIf score >= 80 Then
85 >= 80 → True
- このブロックの内容が実行される!
Grade = "B"
F8 → ローカルウィンドウで
| 変数 | 値 |
|---|---|
| Grade | “B” |
ここで 戻り値が確定。
End If → End Function
F8 を押すと関数が終わり、呼び出し元の Sub の
r = Grade(85)
VBの行へ戻る。
r = Grade(85) 完了
ローカルウィンドウで r の値が "B" に変わる。
Debug.Print r
F8 → Immediate ウィンドウに
B
と表示。
この問題で初心者がよく間違える点
- 関数の中で
Grade = ...を忘れる Integerが小さすぎて Overflow する
→ 基本はLongで良い- 関数名と変数名を同じにしがち(避ける)
問題2:文字列の先頭を大文字にする関数
コード
Function Capitalize(s As String) As String
If Len(s) = 0 Then
Capitalize = ""
Exit Function
End If
Capitalize = UCase(Left(s, 1)) & Mid(s, 2)
End Function
Sub TestCap()
Dim r As String
r = Capitalize("hello")
Debug.Print r
End Sub
ステップ実行の解説
r = Capitalize("hello") に到達したら F8 → 関数へ移動
ローカルウィンドウ:
| 変数 | 値 |
|---|---|
| s | “hello” |
| Capitalize | “” |
If Len(s) = 0 Then
文字数は 5 → False
→ If ブロックをスキップ
Capitalize = UCase(Left(s, 1)) & Mid(s, 2)
F8 を1回押すとまとめて実行されるが、右辺を分解して理解しよう:
Left(s, 1)→"h"UCase("h")→"H"Mid(s, 2)→"ello"
結合結果 → "H" & "ello" = "Hello"
ローカルウィンドウで:
| 変数 | 値 |
|---|---|
| Capitalize | “Hello” |
End Function → Sub へ戻る
r = ... の行に戻る
→ r が “Hello” になる。
問題3:範囲の平均を返す関数
コード
Function RangeAverage(rng As Range) As Variant
Dim cell As Range
Dim sum As Double
Dim count As Long
sum = 0
count = 0
For Each cell In rng
If IsNumeric(cell.Value) Then
sum = sum + cell.Value
count = count + 1
End If
Next cell
If count = 0 Then
RangeAverage = CVErr(xlErrDiv0)
Else
RangeAverage = sum / count
End If
End Function
Sub TestRangeAve()
Dim r As Variant
r = RangeAverage(Range("A1:A3"))
Debug.Print r
End Sub
VBステップ実行ポイント
RangeAverage(Range("A1:A3")) へ移動
ローカルに登場:
| 変数 | 値 |
|---|---|
| rng | Range(“A1:A3”) |
| sum | 0 |
| count | 0 |
For Each cell In rng
最初は cell = A1
- cell の Value が例えば 10 なら
- sum → 10
- count → 1
ローカルウィンドウで変化を見るのが重要。
2回目
cell = A2
もし A2=20
- sum → 30
- count → 2
3回目
cell = A3
もし A3=30
- sum → 60
- count → 3
ループ終了後
ローカルウィンドウ:
| 変数 | 値 |
|---|---|
| sum | 60 |
| count | 3 |
RangeAverage = sum / count
60 / 3 = 20 → 戻り値が 20 になる。
よくあるミス
- Numeric 以外を入れるとエラーと思い込む →
IsNumericで回避可能 - 空白セルも numeric と判定される場合があるので注意(”” は False)
- Variant を返す理由を理解していない
→ エラー(CVErr)も返せるため
まとめ:ステップ実行で必ず見る場所
初心者がステップ実行で見るべきポイントは以下の5つ:
- ローカルウィンドウ
→ 変数の値が行ごとにどう変わるか - If の分岐
→ 条件が True なのか False なのか - 関数名の値がいつセットされるか
→ = を忘れるとバグ - Range を渡したときの For Each の動き
- Exit Function がどこで起きるか
