Excel VBA | Exit文

VBA
スポンサーリンク

繰り返し処理を途中で止める

ループ(繰り返し)を使っていると、「途中で条件が満たされたからそこでやめたい」場面がよく出てきます。VBA ではそれを簡単にするための Exit 文が用意されています。ここでは Exit Do / Exit For を中心に、初心者でも分かるようになぜ使うか → どう書くか → 例題で動きを追う流れで説明します。


1. Exit 文のイメージ

  • ループは列車に例えると「線路をぐるぐる回る」もの。
  • Exit は「次の駅に行かずにホームから降りるボタン」を押すイメージ。
  • 押すとそのループだけを即終了して、ループ後の処理に進みます。

2. どの Exit を使うか

  • Do ... Loop の途中で抜けたい → Exit Do
  • For ... Next の途中で抜けたい → Exit For
  • サブルーチン全体を途中でやめたい → Exit Sub
  • 関数を途中でやめたい → Exit Function

今回は主に Exit DoExit For を扱います。


3. 基本の書き方(見本)

Do の場合:

Do While 条件
    ' 繰り返し処理
    If (抜ける条件) Then
        Exit Do
    End If
Loop
' ここにループ終了後の処理
VB

For の場合:

For i = 1 To 10
    ' 繰り返し処理
    If (抜ける条件) Then
        Exit For
    End If
Next i
' ここにループ終了後の処理
VB

4. 例題 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

動きの追い方(ステップ)

  1. rowno=2, total=0
  2. A2 が空でなければ B2 を合計に足す
  3. total が 200 を超えていたら Exit Do → ループを終える
  4. 超えていなければ rowno を増やして次へ
  5. ループ終了後に合計と行番号を表示

ポイント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 を使う
VBA
スポンサーリンク
シェアする
@lifehackerをフォローする
スポンサーリンク
タイトルとURLをコピーしました