繰り返し処理を途中で止める
ループ(繰り返し)を使っていると、「途中で条件が満たされたからそこでやめたい」場面がよく出てきます。VBA ではそれを簡単にするための Exit 文が用意されています。ここでは Exit Do / Exit For を中心に、初心者でも分かるようになぜ使うか → どう書くか → 例題で動きを追う流れで説明します。
1. Exit 文のイメージ
- ループは列車に例えると「線路をぐるぐる回る」もの。
Exitは「次の駅に行かずにホームから降りるボタン」を押すイメージ。- 押すとそのループだけを即終了して、ループ後の処理に進みます。
2. どの Exit を使うか
Do ... Loopの途中で抜けたい →Exit DoFor ... Nextの途中で抜けたい →Exit For- サブルーチン全体を途中でやめたい →
Exit Sub - 関数を途中でやめたい →
Exit Function
今回は主に Exit Do と Exit For を扱います。
3. 基本の書き方(見本)
Do の場合:
Do While 条件
' 繰り返し処理
If (抜ける条件) Then
Exit Do
End If
Loop
' ここにループ終了後の処理
VBFor の場合:
For i = 1 To 10
' 繰り返し処理
If (抜ける条件) Then
Exit For
End If
Next i
' ここにループ終了後の処理
VB4. 例題 1 — 「合計が200を超えたら途中でやめる」 (Do While + Exit Do)
課題:シートの A 列に文字がある行を上から読んで、B 列の数を足していく。合計が 200 を超えたらそこで終わる。終わったときの合計と何行目で止まったかを表示する。
Sub SumUntil200()
Dim rowno As Long
Dim total As Double
rowno = 2 ' データは 2 行目から始まる想定
total = 0
Do While Cells(rowno, 1).Value <> "" ' A列が空でない間ループ
total = total + Cells(rowno, 2).Value ' B列の数を足す
If total > 200 Then
Exit Do ' 合計が200を超えたらここでループを抜ける
End If
rowno = rowno + 1
Loop
Debug.Print "合計 = " & total
Debug.Print "停止した行 = " & rowno
End Sub
VB動きの追い方(ステップ)
- rowno=2, total=0
- A2 が空でなければ B2 を合計に足す
- total が 200 を超えていたら
Exit Do→ ループを終える - 超えていなければ rowno を増やして次へ
- ループ終了後に合計と行番号を表示
ポイント:Exit Do は「その瞬間にループを終了」する。条件を後でチェックするより見やすいケースが多い。
5. 例題 2 — 「当たりが出たら止める」 (For + Exit For)
課題:1〜8 回乱数を作る。もし乱数が 7 になったら当選としてループを終える。
Sub Lottery()
Dim i As Integer
Dim num As Integer
Randomize ' 乱数の初期化(必ず入れる習慣を)
For i = 1 To 8
num = Int(10 * Rnd + 1) ' 1〜10 の乱数
Debug.Print i & "回目: " & num
If num = 7 Then
Debug.Print "当選! " & i & " 回目で終了"
Exit For
End If
Next i
Debug.Print "ループ終了(i = " & i & ")"
End Sub
VB注目点:Exit For を実行すると Next i に戻らず、次の文(ループ後)へ進みます。
6. 例題 3 — ネスト(入れ子)したループの途中終了
課題:2 次元表を走査して、値が見つかったら「内側のループだけ」抜けたい場合と、見つかったら「外側も含めて完全に抜けたい」場合の書き方。
Sub NestedExample()
Dim r As Long, c As Long
Dim found As Boolean
found = False
For r = 1 To 10
For c = 1 To 5
If Cells(r, c).Value = "ターゲット" Then
found = True
Exit For ' 内側の For を抜ける(外側は続く)
End If
Next c
If found Then
Exit For ' 外側の For も抜ける(完全にループ終了)
End If
Next r
If found Then
Debug.Print "見つかった位置: 行" & r & " 列" & c
Else
Debug.Print "見つからなかった"
End If
End Sub
VBポイント:
Exit Forは その実行されたループだけ を抜ける。ネストの場合は外側も終了させたいとき、フラグ(found)を使って外側でもExit Forを呼ぶ必要があります。Exit Doでも同じ考え方です。
7. Exit を使うときの良い習慣と注意点
- 読みやすさ第一:短いサブルーチン内で条件がはっきりしているなら
Exitは読みやすくなる。逆にあちこちにExitがあると流れが追いにくくなるので注意。 - ネストに注意:深くネストしたループで内側だけ抜けるのか外側も抜けるのか、意図を明確にする(コメントや変数名で示す)。
- 無限ループに注意:
Do While Trueのような無条件ループはExitがないと終わらない場合がある。必ず抜ける条件を作る。 - 代替手段:条件をループ条件側に書いて抜ける(
Do Whileの条件を工夫)ことでも実現可能。どちらが読みやすいか判断する。 - 例外的終了:サブルーチン全体を「エラー発生で即終了」させたいときは
Exit Sub/Exit Functionを使います。
8. 練習問題(手を動かして覚えよう)
下に 6 問出します。解答付きなのでまず自力で解いてから答えを確認して下さい。
問1
A 列に名前、B 列に得点がある。上から読み、得点が 60 未満の行が見つかったらその行の名前を表示してループをやめよ(For を使う)。
答1(模範)
Sub Q1()
Dim i As Long
For i = 2 To 100 ' 仮に2行目〜100行目を調べる
If Cells(i, 1).Value = "" Then Exit For ' データ終端チェック
If Cells(i, 2).Value < 60 Then
Debug.Print "不合格: " & Cells(i, 1).Value & "(行 " & i & ")"
Exit For
End If
Next i
End Sub
VB問2
1 から 100 までの乱数を作り、50 より大きい値が出たらそこでループを終える(Do を使用)。
答2
Sub Q2()
Dim n As Integer
Randomize
Do
n = Int(100 * Rnd + 1)
Debug.Print n
If n > 50 Then Exit Do
Loop
Debug.Print "止めた値 = " & n
End Sub
VB問3
2 次元配列(行 1〜5、列 1〜5)を走査して、値が -1 のセルが見つかったら外側のループも含めて完全に終了するコードを示せ(フラグ使用)。
答3
Sub Q3()
Dim r As Long, c As Long
Dim done As Boolean
done = False
For r = 1 To 5
For c = 1 To 5
If Cells(r, c).Value = -1 Then
done = True
Exit For
End If
Next c
If done Then Exit For
Next r
If done Then Debug.Print "見つかった: " & r & "," & c
End Sub
VB問4
For i = 1 To 10 のループ内で、ある条件に合えば(i=4 とする)Exit Sub を使ってサブルーチン全体を終了する例。
答4
Sub Q4()
Dim i As Integer
For i = 1 To 10
If i = 4 Then
Debug.Print "i=4 でサブルーチン終了"
Exit Sub
End If
Next i
Debug.Print "ここは実行されない(Exit Sub のため)"
End Sub
VB問5
無限ループ Do While True の中で、セル A1 が “STOP” になったら抜けるコード。
答5
Sub Q5()
Do While True
DoEvents ' Excel の反応を保つ(必須ではないが推奨)
If Range("A1").Value = "STOP" Then
Exit Do
End If
' 他の処理...
Loop
Debug.Print "STOP を検出して終了"
End Sub
VB問6(やや応用)
ネストした For ループがあり、内側のループで条件が成立したら 外側のループの次の反復へすぐに移りたい。どう書く?
ヒント:フラグではなく GoTo を使う方法もありますが、可読性を保つ目的で Continue 相当の処理は VBA にないのでフラグを使うのが無難。
答6(推奨フラグ)
Sub Q6()
Dim i As Long, j As Long
Dim skipOuter As Boolean
For i = 1 To 10
skipOuter = False
For j = 1 To 5
If Cells(i, j).Value = "X" Then
skipOuter = True
Exit For
End If
Next j
If skipOuter Then
' 外側の次の i へ(実際には何もしないで次の i へ進む)
Continue For ' ※VBA に Continue For はない(説明のための擬似)
End If
' 外側で続けたい処理...
Next i
End Sub
VB注:VBA に
Continue Forは無いので、実際はIf skipOuter Then GoTo NextIやフラグ判定後に処理をスキップする構造を使います。GoToは可読性が落ちることがあるので注意。
総まとめ(短く覚え方)
Exit Do→ Do Loop を即終了Exit For→ For Next を即終了- ネストなら「内側だけ」しか抜けない → 外側も止めたいなら別途処理(フラグや外側の
Exit)が必要 - サブルーチン全体は
Exit Sub/Exit Functionを使う
