🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

Excel VBA の Exit For — Exit For・Exit Do・Exit Sub とクリーンな早期脱出

|

Excel VBA の Exit For — Exit For・Exit Do・Exit Sub とクリーンな早期脱出

TL;DR — Exit For は For ループを即座に抜け、Exit Do は Do ループを抜け、Exit Sub と Exit Function はプロシージャから戻ります。これらはひとつの考え方です — いまいる構造をすぐに出る — そして、その構造の あと のコードはそのまま動き続けます。落とし穴はこうです。Exit For は 一番内側 の ループしか抜けないので、ネストしたループでは外側のループが回り続けます。VBA には Continue も Exit If もありません。繰り返しを一回だけ飛ばすには If を使います(あるいは、まれに Next の直前 のラベルへ GoTo します)。

Sub FindFirstMatch()
    Dim i As Long, found As Long
    For i = 1 To 100000
        If Cells(i, 1).Value = "TARGET" Then
            found = i
            Exit For              ' 見つかった瞬間に止める - 残りを走査する必要はない
        End If
    Next i
    MsgBox IIf(found > 0, "Found on row " & found, "Not found")
End Sub

Exit は、プログラム全体を抜けることなくブロックから早く出る方法です。Exit For や Exit Do でループを抜け、Exit Sub でプロシージャから戻り、マクロの残りはそのまま動かします。この最後 の部分こそが肝心で、それが Exit を End から分ける一行です。Exit は ドア を閉め、 End は プラグ を抜きます。

この記事で学べること

  • Exit For・Exit Do・Exit Sub・Exit Function をひとつの規則で結ぶ考え方
  • Exit For がループを抜ける仕組み、そしてループのあとのコードがなお動く理由
  • 最大の落とし穴 — ネストした For で Exit For は 一番内側の ループしか抜けない
  • VBA に Continue も Exit If もない理由、そして繰り返しを一回だけきれいに飛ばす方法
  • 深くネストした If ブロックを置き換えるガード節のパターン(If ... Then Exit Sub)
  • Exit Sub が End とどう違うか — プロシージャを出るのか、マクロ全体を止めるのか

考え方の軸:この構造を出て、プログラムは動かし続ける

どの形の Exit も、自分が出る構造を名指しし、その構造だけを出ます。

Exit For        ' 囲んでいる For ループを出る
Exit Do         ' 囲んでいる Do ループを出る
Exit Sub        ' 囲んでいる Sub を出る(呼び出し元へ戻る)
Exit Function   ' 囲んでいる Function を出る(呼び出し元へ戻る)

プロシージャを、入れ子になった部屋の集まりだと考えてください — Sub がループを含み、そのループが If を含 みます。Exit For はループの部屋から出ますが、Sub の中には留まります。Exit Sub はプロシージャ全体から 歩み出ます。どの場合も、実行は出た構造の外側にある 次の ものから再開します — Next の次の行か、あなたの Sub を呼び出した呼び出し元です。そのブロックの中で Exit より後にあるものは何も動きませんが、ブロックよ り後にあるものはすべて動きます。これが Exit を 構造化された ものにしています。制御がどこに着地するかを 常に正確に把握できるのは、名指しした箱のすぐ外側に着地するからです。

Exit For:やり終えた瞬間にループを止める

For ループの既定は、すべての繰り返しを回すことです。ですが、すべての繰り返しが必要ないことはよくあります — 探し物をしているとき、答えが見つかってしまえば、残りの周回はむだな仕事です。

Dim i As Long
For i = 2 To 100000
    If Cells(i, 1).Value = "" Then Exit For   ' 最初の空白行 - ここで止める
Next i
' i にはいま、止まった行が入っている; 実行はこの行から続く

押さえておきたいことが二つあります。第一に、Exit For はループカウンターをリセットもクリアもしません — ループのあと、i は抜けた時点の値をそのまま保ちます。これはたいてい、まさに欲しいもの(止まった行)です。 第二に、あなたが出たのはループ だけ です。Next i より後のコードは普通に動きます。プロシージャ全体を打ち 切るつもりだったのなら、それは Exit For ではなく Exit Sub です。

最大の落とし穴:Exit For は一番内側のループしか抜けない

これは、人から午後一つ分を奪う間違いです。ある For を別の For の中にネストすると、Exit For は 自分 がいるループだけ — 内側のループ — を抜けます。外側のループは何事もなかったかのように回り続けます。

Dim r As Long, c As Long
For r = 1 To 100
    For c = 1 To 50
        If Cells(r, c).Value = "STOP" Then Exit For   ' c ループ「だけ」を抜ける
    Next c
    ' <-- 制御はここに着地し、外側の r ループは r = 100 まで続く
Next r

二段いっぺんに抜ける Exit For, For のようなものは存在しません。両方の ループを本当に止めたいときは、正 直な選択肢が三つあります。Boolean のフラグを立てて外側のループの条件で判定する、ネストしたループを専用の Function に移して Exit Function で両方を一度に抜ける、あるいは — 熟練の VBA 書きがいまだに手を伸ばす唯 一の場面ですが — 外側の Next のすぐ先にあるラベルへ GoTo する、です。たいていは Function を使うやり方 が一番きれいです — ジャンプが最後の手段である理由は VBA GoTo を参照してください。

Exit Do:Do ループでも同じ考え方

Do ループには、まったく同じ理由で専用のキーワード Exit Do があります。これがもっとも効くのは、条件のな い Do ... Loop — そのままでは永遠に回り続けるもの — です。

Dim n As Long
Do
    n = n + 1
    If n > 1000 Then Exit Do          ' このループから出る唯一の道
Loop

Exit Do は Do While、Do Until、そして素の Do ... Loop の中で使います。Do ループの中で Exit For を使おうとしたり、その逆をしたりしてはいけません — キーワードはループの種類と一致していなければならず、さも ないと VBA はコンパイルエラーを出します。ループの書き方そのものの違いについては VBA While Loop を参照してください。

Exit Sub と Exit Function:プロシージャから早く戻る

ループの外では、同じ考え方がプロシージャ全体からあなたを戻します。Exit Sub は Sub を即座に終わらせ、そ れを呼び出したものへ制御を返します。Exit Function は Function に対して同じことをし、関数名がその時点で 保持している値を返します。

Function SafeDivide(a As Double, b As Double) As Double
    If b = 0 Then
        SafeDivide = 0
        Exit Function        ' いま 0 を返す; 下の割り算は飛ばす
    End If
    SafeDivide = a / b
End Function

Exit Function では順序に注意してください。抜ける 前 に戻り値を設定します。Exit Function はすぐに出て しまい、その下の行には決して到達しないからです。この「条件を確かめて、早めに切り上げる」形は、Exit がして くれることの中でいちばん役に立つもので、名前まで付いています。

ガード節のパターン:ネストした If の代わりに Exit Sub

プロシージャに前提条件があるとき — シートが存在しなければならない、セルが空白であってはならない、ユーザーが 何かを選んでいなければならない — つい書きたくなるのは、ネストした If ブロックのピラミッドです。より平らで 読みやすい代わりの手が ガード節 です。前提条件を一つずつ先頭で確かめ、満たされなければ Exit Sub する。 そうすれば本題の処理は、ネストなしで左端から始まります。

Sub ProcessSelection()
    If Selection Is Nothing Then Exit Sub
    If Selection.Cells.Count = 0 Then Exit Sub
    If Not TypeName(Selection) = "Range" Then Exit Sub

    ' ここまで来れば、前提条件はすべて満たされている - ネストなしで作業する
    Dim cell As Range
    For Each cell In Selection
        cell.Value = UCase(cell.Value)
    Next cell
End Sub

どのガードも、ふつうの一文のように読めます — 「何も選択されていなければ、それで終わり」。見返りは、大事なコ ードが If 三段の奥深くに埋もれることが決してない点です。プロシージャに早く止まるべき明確な理由が一つある なら、先頭の Exit Sub ガードは、本体全体を If ... End If で包むよりも勝ります。

VBA には Continue も Exit If もない

他の言語から来たプログラマーが手を伸ばして、そして見つからないものが二つあります。VBA には次の繰り返しへ飛 ぶための Continue 文が なく、Exit If も ありません — Exit が出るのはループとプロシー ジャだけで、If ブロックを出ることは決してありません(If は自分の End If で勝手に終わります)。ループの 繰り返しを一回飛ばすには、本体を If で包んで、飛ばすことを単なる「今回は何もしない」にします。

For i = 1 To n
    If Cells(i, 1).Value = "" Then
        ' 空白行を飛ばす - ただ何もせず Next へ抜け落ちる
    Else
        ' 空白でない行はここで処理する
    End If
Next i

この裏返しの If が、VBA らしい「continue」です。古いコードで見かける代わりの手 — Next の直前に置いたラ ベルへ GoTo する — も動きますが、それはジャンプであり、ジャンプは If よりも追いにくいものです。飛ばす処 理が If には本当に込み入りすぎているときにだけ手を伸ばし、まず VBA GoTo に目を通して ください。

Exit は End ではない:プラグではなくドア

このページでいちばん大事な境界線です。Exit Sub は 現在のプロシージャから戻り、プログラムを続けさせま す — 呼び出し元は次の行を実行し、あなたの後片付けが動き、Excel は正気の状態のまま残ります。 End は マクロ全体を即座に止めます。すべての変数を捨て、UserForm を閉じ、そして — 本当の痛手ですが — 準備しておいた後片付けをすべて飛ばすので、Application.ScreenUpdating は False のまま、 イベントは無効のままになりかねません。このプロシージャ を出たいときの答えは、ほとんどいつも Exit Sub であって、End ではありません。

ExcelMaster の活用

早期脱出は、「正しい」と「速い」が出会う場所です。100,000 行を走査する代わりに最初の一致で止まる検索、入力 が間違っているときにきれいに切り上げるプロシージャ。典型的な失敗は二つ、Exit For がネストしたループを抜け てくれると思い込むことと、Exit Sub(プロシージャを出る)と End(すべてを止めて後片付けを飛ばす)を取り 違えることです。

ExcelMaster には、目的をそのまま伝えら れます — 「A 列が空白になる最初の行を見つけて止めて」 — すると、正しい Exit でループを書き、前提条件には ガード節を添え、何も中途半端に残らないよう後片付けを組み立てます。ブックとコードはあなたの手元に残ります。

よくある質問

VBA で For ループを抜けるには?

Exit For を使います。囲んでいる For ループを即座に抜け、Next の次の最初の行から続きます。ふつうは If の中に置いて、条件が満たされたときだけループが止まるようにします。たとえば If Cells(i, 1).Value = "TARGET" Then Exit For です。ループカウンターは抜けたあとも現在の値を保ち、それはたいてい探していた行や添字です。

Exit For はネストしたループを抜けますか?

いいえ — Exit For は自分がいる一番内側のループしか抜けません。外側のループは回り続けます。VBA には、一つの 文で二段のループを抜ける方法はありません。両方を止めるには、Boolean のフラグを立てて外側のループで判定す るか、ネストしたループを Function に移して Exit Function を使うか、外側の Next の後に置いたラベルへ GoTo します。

Exit Sub と End の違いは何ですか?

Exit Sub は現在のプロシージャから戻り、プログラムを続けさせます — 呼び出し元が再開し、用意した後片付けが 動きます。End はマクロ全体を一度に止めます。すべての変数を消し、フォームを閉じ、後片付けを飛ばすので、 ScreenUpdating が無効のまま、イベントが無効のままになることがあります。プロシージャを出るには Exit Sub を使い、End は本物の緊急事態のために取っておきましょう。

VBA のループで繰り返しを一回飛ばすには?

VBA には Continue 文がありません。定石は、ループの本体を If で包み、飛ばしたい繰り返しはただ何もせず Next へ抜け落ちるようにすることです。古いコードでは Continue をまねるために Next の直前のラベルへ GoTo することもありますが、裏返しの If のほうが分かりやすく、ジャンプを持ち込みません。

Exit Do や Exit While はありますか?

Exit Do はあります。どんな Do ループ(Do While、Do Until、素の Do ... Loop)でも抜けられます。 Exit While はありません — 古い While ... Wend ループには抜ける文がそもそもなく、これも Do ループを好む べきもう一つの理由です。Exit キーワードはループの種類と一致していなければなりません。For ループでは Exit For を、Do ループでは Exit Do を使います。

検証環境

検証環境: Excel 365 (Windows 11)、VBA 7.1 — 最終確認 2026-09-24。

関連ガイド: VBA GoTo · VBA End · VBA For Loop · VBA While Loop · VBA On Error