Excel VBAでFor Nextを抜ける方法をお探しですね。
広告
Excel VBAでループを途中で抜ける方法 – Exit ForとExit Doの使い方
Excel VBAで繰り返し処理を書いていると、「探していたデータが見つかったから、もうこれ以上回す必要ないな」とか「空白行まで来たからここで終わりにしよう」といった場面がよくあります。
全部の行を最後まで見なくていい時は、Exit ForやExit Doを使うと処理が速くなるし、コードの意図も伝わりやすくなります。
この記事では、ループを途中で抜ける条件の書き方を、For文とDo Loop文の違いも含めて分かりやすく解説します。
Exit ForとExit Doの基本 – どう使い分ける?
VBAでループを途中で抜けたい時は、使っているループの種類に合わせて命令を選びます。
For…NextやFor Each…Nextなら**Exit For**、Do…Loopなら**Exit Do**です。
どちらも「条件を満たしたら、そのループを終了して次の処理に進む」ための命令です。
ループの終わりを決めるものではなく、途中で抜け出すための命令だと思ってください。
基本的にはIf文と組み合わせて使います。
たとえば、A列を上から順に見ていって、目的の値が見つかった時点で「もう探さなくていいや」と終わらせたい時、Exit Forを使うとスッキリします。
1000行全部見るより、見つかった瞬間に終わる方が速いですし、何をしたいのかも分かりやすいですよね。
特にExcelで大量のデータを扱う時は、無駄なループを減らすことが処理速度アップのコツです。
“`vb
Sub SampleExitFor()
Dim i As Long
Dim target As String
target = “完了”
For i = 1 To 1000
If Cells(i, 1).Value = target Then
MsgBox i & “行目で見つかりました”
Exit For
End If
Next i
MsgBox “検索処理が終わりました”
End Sub
“`
この例では、A列の1行目から1000行目まで「完了」という文字を探します。
見つかったらExit ForでForループを抜けます。
Exit Forが実行されると、Next iの次の行に進むので、最後のMsgBoxはちゃんと表示されます。
ここで大事なのは、**Exit Forはマクロ全体を終わらせる命令じゃない**ということ。
ループだけ抜けたいのか、処理全体を終わらせたいのかで、Exit For、Exit Do、Exit Subを使い分ける必要があります。
For文で途中終了する実務パターン
For文は、繰り返す回数や範囲が最初から決まっている時に便利です。
「1行目から最終行まで確認する」「指定した列を順番に処理する」といった場面でよく使います。
でも、必ずしも最後まで処理しなくていいこともあります。
空白行を見つけたら終わり、特定のIDを見つけたら終わり、おかしな値が出てきたら中断、といった条件を設定できます。
次の例は、A列を上から見ていって、空白セルに当たった時点でループを終了するコードです。
データが連続して入っている表なら、空白行より下を処理する意味がないことが多いので、Exit Forを使うと無駄がありません。
最終行を調べてから処理する方法もありますが、「途中で空白が出たら終わり」という意図を表すには、Exit Forの方が分かりやすい場合もあります。
“`vb
Sub StopAtBlankCell()
Dim i As Long
For i = 1 To 1000
If Cells(i, 1).Value = “” Then
Exit For
End If
Cells(i, 2).Value = “処理済み”
Next i
End Sub
“`
このコードは、A列が空白じゃなければB列に「処理済み」と書き込みます。
A列が空白になった瞬間にExit Forが実行されるので、それ以降の行には何もしません。
条件式はシンプルですが、実務では「金額が0以下なら抜ける」「ステータスが中止なら抜ける」「日付が範囲外なら抜ける」など、業務ルールに合わせて自由に設定できます。
大切なのは、Exit Forの条件を**「このループを続ける意味がなくなる条件」**として考えることです。
For Eachでセル範囲やコレクションを処理している時も、Exit Forが使えます。
たとえば、選択範囲の中にエラー値があったら処理を中止する、といった書き方ができます。
For Eachは要素を順番に取り出す構文なので、行番号や列番号を気にしなくていい一方、途中終了の考え方は普通のFor文と同じです。
“`vb
Sub CheckErrorInRange()
Dim c As Range
For Each c In Range(“A1:A100”)
If IsError(c.Value) Then
MsgBox “エラー値が見つかったので処理を中止します”
Exit For
End If
c.Offset(0, 1).Value = “確認済み”
Next c
End Sub
“`
Exit Forを使う時に注意したいのは、**「次のループに進む」んじゃなくて「ループそのものを抜ける」**という点です。
VBAには他の言語でよく見るContinueみたいな命令が標準ではありません。
条件に合わない行だけスキップして次に進みたい時は、If文の構造を工夫するか、必要ならラベルとGoToを使います。
ただ、GoToは処理の流れが追いにくくなるので、基本的にはIf文をシンプルに保つ設計を優先すると読みやすいコードになります。
Do Loopで途中で抜ける方法と無限ループ対策
Do Loopは、繰り返し回数が事前に決まっていない時に便利な構文です。
「条件が成り立つ間繰り返す」「条件が成り立つまで繰り返す」という形で書けるので、空白セルまで処理する、ユーザーがキャンセルするまで続ける、一定条件を満たすデータが出るまで探す、といった場面で使われます。
Do Whileは条件がTrueの間繰り返し、Do Untilは条件がTrueになるまで繰り返します。
どっちを使っても同じ処理が書けることもありますが、読み手が直感的に分かりやすい方を選ぶのが大事です。
**Exit Do**は、Do…Loopを途中で終了したい時に使います。
たとえば、A列にデータがある間だけ処理しつつ、途中で「中止」という値が見つかったら終わる場合に便利です。
Do Whileの条件だけでも空白行で止められますが、追加の終了条件がある場合は、ループの中にIf文とExit Doを置くと柔軟に制御できます。
“`vb
Sub SampleExitDo()
Dim i As Long
i = 1
Do While Cells(i, 1).Value <> “”
If Cells(i, 1).Value = “中止” Then
MsgBox “中止データが見つかったので終了します”
Exit Do
End If
Cells(i, 2).Value = “処理済み”
i = i + 1
Loop
MsgBox “Do Loopの処理が終わりました”
End Sub
“`
この例では、A列が空白じゃない間は処理を続けます。
でも、セルの値が「中止」だったらExit Doでループを抜けます。
Exit Doが実行されると、Loopの次の行に進むので、最後のMsgBoxは表示されます。
Do Loopではカウンター変数の増減を自分で書く必要があるので、**i = i + 1を忘れると同じ行を見続けて無限ループになる**可能性があります。
For文より自由度が高い分、終了条件とカウンター更新の管理が重要です。
無限ループを防ぐには、ループが必ず終わる条件を複数の視点で確認します。
特にDo WhileやDo Untilでは、条件式がいつFalseまたはTrueになるのかを事前に考える必要があります。
Excelが固まった場合はEscキーやCtrl + Breakで止められることもありますが、業務用マクロではそもそも止まらないコードを書かないことが大切です。
安全策として、最大試行回数を設けてExit Doする書き方も実務では有効です。
“`vb
Sub SafeDoLoop()
Dim i As Long
Dim count As Long
i = 1
Do
If Cells(i, 1).Value = “” Then Exit Do
If count >= 1000 Then
MsgBox “上限回数に達したので終了します”
Exit Do
End If
Cells(i, 2).Value = “処理済み”
i = i + 1
count = count + 1
Loop
End Sub
“`
このように、通常の終了条件に加えて上限回数を設定しておくと、想定外のデータや条件ミスがあっても処理が止まりやすくなります。
特に外部ファイル、ユーザー入力、Webから取得したデータなど、内容が一定じゃないものを処理する場合は、こういう防御的な条件設定が役立ちます。
二重ループ、Exit Subとの違い、読みやすくするコツ
Exit ForやExit Doは、**二重ループ(ネスト)で使うと挙動を勘違いしやすい**命令です。
ネストっていうのは、ループの中にさらにループが入っている構造のことです。
たとえば、行と列を二重ループで処理している場合、内側のFor文でExit Forを実行しても、抜けるのは内側のループだけです。
外側のループまで一緒に終わるわけじゃありません。
この性質を理解していないと、「全部止めたつもりなのに次の行の処理が続いちゃう」という不具合につながります。
“`vb
Sub NestedLoopSample()
Dim r As Long
Dim c As Long
For r = 1 To 10
For c = 1 To 5
If Cells(r, c).Value = “停止” Then
Exit For
End If
Cells(r, c).Interior.Color = vbYellow
Next c
Next r
End Sub
“`
この例で「停止」が見つかると、内側のcのループだけを抜けます。
その後、外側のrのループは次の行に進みます。
もし「停止」が見つかった時点で処理全体を終了したいなら、フラグ変数を使って外側のループも抜けるか、マクロ全体を終了する**Exit Sub**を使う必要があります。
Exit Subは実行中のSubプロシージャを直ちに終了する命令で、ループ後の処理も実行されません。
後続処理が必要な場合に使うと意図しない動作になるので、ループだけを抜けたい場合はExit ForやExit Doを選びます。
“`vb
Sub NestedLoopWithFlag()
Dim r As Long
Dim c As Long
Dim stopFlag As Boolean
For r = 1 To 10
For c = 1 To 5
If Cells(r, c).Value = “停止” Then
stopFlag = True
Exit For
End If
Cells(r, c).Interior.Color = vbYellow
Next c
If stopFlag Then Exit For
Next r
MsgBox “処理が終わりました”
End Sub
“`
このコードでは、内側のループで「停止」を見つけたらstopFlagをTrueにして、まず内側のForを抜けます。
その後、外側のループでもstopFlagをチェックしてExit Forするので、二重ループ全体を終了できます。
Exit Subを使えばもっと短く書ける場合もありますが、終了後にメッセージ表示や後片付け処理をしたい場合は、フラグを使う方が安全です。
特に画面更新の再開、イベント設定の復元、一時ファイルの削除などが必要なマクロでは、途中終了後の処理を残せる設計が重要になります。
読みやすい条件設定にするには、**Exitの条件を複雑にしすぎない**ことも大切です。
If文の中に複数のAndやOrが並ぶと、どの条件で抜けるのか分かりにくくなります。
そんな時は、条件を変数に分けたり、コメントを添えたりすると保守しやすくなります。
また、Exit ForやExit Doは「エラーの時だけ」じゃなく、**「目的を達成した時点で終了する」**ためにも使えます。
検索で見つかった、集計対象が終わった、ユーザーがNoを選んだなど、自然な終了条件として使うと、コードの流れがスッキリします。
最後に、VBAの途中終了を設計する時は、**「ループを抜ける」「次の繰り返しに進む」「マクロ全体を終える」の3つを分けて考える**ことが大事です。
Exit ForとExit Doはループを抜ける命令、Exit Subはマクロ全体を終える命令です。
一方、VBAには標準のContinue文がないので、次の繰り返しに進みたいだけの場面では、If文で処理対象を限定する書き方を検討します。
この違いを押さえておくと、Excel VBAでループを途中で抜ける条件設定を、実務でも迷わず使い分けられるようになります。
広告
