Exit文の基礎
プログラミング初心者がつまずきやすいのが「ループをいつ終わらせるか」。Exit文は「条件を満たした瞬間に、その場でループを抜ける」ための合図です。うまく使うと処理が短く、読みやすく、意図が明確になります。
Exit文の種類と考え方
- 基本の種類: Do〜Loopの途中で抜けるときは「Exit Do」、For〜Nextの途中で抜けるときは「Exit For」。SubやFunctionそのものを終わらせる「Exit Sub」「Exit Function」もあります。
- 考え方: 「まだ続ける?」ではなく「もうやめる!」のスイッチ。条件を満たした瞬間にループを止めたいときに使います。
- 内側だけ終了: ループが入れ子(ネスト)になっている場合、Exitは「今いる一番内側のループ」だけを終了します。
Exit Doを使った例(合計が一定を超えたら止める)
例の状況
A列に品名、B列に金額が順に入っているとします。合計が10,000を超えたら計算を止めたい。
Sub StopWhenOverBudget()
Dim rowNo As Long
Dim total As Long
rowNo = 2 ' 見出しが1行目にある想定で2行目から
total = 0
Do While Cells(rowNo, 1).Value <> "" ' A列が空でない間続ける
total = total + Cells(rowNo, 2).Value ' B列の金額を足す
If total > 10000 Then ' ここが「やめる条件」
MsgBox "予算オーバー!合計: " & total & "(" & rowNo & "行目で停止)"
Exit Do ' Do〜Loopを即終了
End If
rowNo = rowNo + 1
Loop
' ここに来たら、ループは終わっている(条件で抜けたか、A列が空で終わったか)
End Sub
VB- ポイント:
- やめる条件: totalが10,000を超えた瞬間にExit Do。後続の足し算は行わないので「超えた直後」の状態を保てます。
- 境界の扱い: 「超えたら止める」なら
>。「超えそうなら止める」なら足す前にチェックするか、>=を使います。 - 安全運転: A列が空になったら自然終了。データの終わりがわからないときはこの書き方が便利。
Exit Forを使った例(条件に当たったら探すのを止める)
例の状況
1〜100の中から、最初に偶数でかつ10の倍数の数を見つけたら探すのを止めたい。
Sub FindFirstMatch()
Dim i As Long
For i = 1 To 100
If (i Mod 2 = 0) And (i Mod 10 = 0) Then
Debug.Print "見つけた値: "; i
Exit For ' 見つけた瞬間にFor〜Nextを終了
End If
Next i
' Exit Forの後はここに来る。見つかった時点のiで止まっている
End Sub
VB- ポイント:
- 最初の一致だけ欲しい: 一致した瞬間にExit For。無駄な繰り返しをしない。
- 範囲が決まっている: For〜Nextは「開始〜終了」が決まっているループに向いています。
- 見つからない場合: 条件に一度も当たらないなら、最後まで回ってから終了します。
ネスト(入れ子)のループでのExitの動き
Sub NestedExitExample()
Dim r As Long, c As Long
For r = 1 To 10 ' 外側:行
For c = 1 To 10 ' 内側:列
If Cells(r, c).Value = "STOP" Then
Debug.Print "止めた位置: (" & r & ", " & c & ")"
Exit For ' これで「列ループ」だけ終わる
End If
Next c
' ここに来た時点で、その行の列走査は終わっているが、行のループは続く
Next r
End Sub
VB- 重要:
- Exit For/Doは「今いる内側ループのみ」終了。 外側まで一気に抜けたいなら、フラグ変数を使うか、
GoToやサブルーチン分割で設計を工夫する。 - フラグの例: 条件成立で
found = Trueにして、内側をExit後、外側のループ先頭でIf found Then Exit Forのように段階的に抜ける。
- Exit For/Doは「今いる内側ループのみ」終了。 外側まで一気に抜けたいなら、フラグ変数を使うか、
Exitを使うべき場面と注意点
- 使うべき場面:
- 早期終了: 目的のデータを見つけたら即終了(検索・探索)。
- 安全停止: 閾値を超えたら止める(合計、時間、回数)。
- エラー回避: 想定外の値や空欄に当たったら処理を中断。
- 注意点:
- 読みやすさ: Exitを多用しすぎると「どこで終わるか」が散らばる。条件は「明確・単純」に。
- 副作用: Exit直前までの処理は実行済み。途中の計算が未完のまま終わる可能性を理解して設計する。
- ログを残す: 終了理由(どの条件で止まったか)をMsgBoxやDebug.Printで記録すると、後で原因追跡が楽。
すぐに試せる練習問題
- 練習1(Exit Do):
- 目標: B列の合計が5,000以上になったら止め、止めた行番号を表示する。
- ヒント:
Do While Cells(rowNo, 2).Value <> ""- 合計を更新した直後に
If total >= 5000 Then Exit Do
- 練習2(Exit For):
- 目標: C列の1〜50行目で、最初に空欄のセルを見つけたら位置を表示して終了する。
- ヒント:
For i = 1 To 50If Cells(i, 3).Value = "" Then Exit For
- 練習3(ネスト+フラグ):
- 目標: 5×5の表から「OK」を初めて見つけたら、行・列ともループを終了する。
- ヒント:
found As Booleanを用意し、内側でfound = True→Exit For。外側の先頭でIf found Then Exit For。
模範解答と解説
練習1(Exit Do)
問題: B列の合計が5,000以上になったら止め、止めた行番号を表示する。
解答例
Sub Practice1()
Dim rowNo As Long
Dim total As Long
rowNo = 1
total = 0
Do While Cells(rowNo, 2).Value <> "" ' B列が空でない間繰り返す
total = total + Cells(rowNo, 2).Value
If total >= 5000 Then ' 合計が5000以上になったら
MsgBox "合計が5000を超えました! 行番号: " & rowNo
Exit Do ' ループを終了
End If
rowNo = rowNo + 1
Loop
End Sub
VB解説
Do Whileは「条件が真の間繰り返す」構文。ここでは「セルが空でない間」。- 合計を更新した直後にチェック → 超えたら
Exit Do。 Exit Doにより、その場でループを抜ける。以降の処理は実行されない。
練習2(Exit For)
問題: C列の1〜50行目で、最初に空欄のセルを見つけたら位置を表示して終了する。
解答例
Sub Practice2()
Dim i As Long
For i = 1 To 50
If Cells(i, 3).Value = "" Then ' C列が空欄なら
MsgBox "最初の空欄は " & i & " 行目です"
Exit For ' ループを終了
End If
Next i
End Sub
VB解説
For i = 1 To 50は「1から50まで順番に繰り返す」。- 空欄を見つけた瞬間に
Exit For→ 以降のチェックは不要。 - 最初の空欄だけを探すときに便利。
練習3(ネスト+フラグ)
問題: 5×5の表から「OK」を初めて見つけたら、行・列ともループを終了する。
解答例
Sub Practice3()
Dim r As Long, c As Long
Dim found As Boolean
found = False
For r = 1 To 5
For c = 1 To 5
If Cells(r, c).Value = "OK" Then
MsgBox "OKを見つけました! 行: " & r & " 列: " & c
found = True
Exit For ' 内側の列ループを終了
End If
Next c
If found Then Exit For ' 外側の行ループも終了
Next r
End Sub
VB解説
- ループが二重になっている場合、
Exit Forは「内側のループ」だけ終了。 - 外側も止めたいときは「フラグ変数」を使う。
found = Trueにしておき、外側のループ先頭でチェック。If found Then Exit Forで外側も終了。
小さな設計のコツ
- 明確な停止条件: 「何が起きたら終わるのか」を短いIf文で言い切る。
- 途中結果の報告: MsgBoxやDebug.Printで「どこで止まったか」を出す。
- テストしやすく: 範囲や閾値を定数にして上部で定義すると、動作確認が楽になる。
