「条件を満たすまで処理を繰り返したい……」
VBAで繰り返し処理を書いていると、そんな場面に出くわしますよね。回数が決まっていればFor文で十分です。でも「空白セルが見つかるまで」「値が一定を超えるまで」のように、終了タイミングが条件次第のケースがあります。こうした場合、For文だとうまく書けません。
そんなときに使うのが VBA Do Loop です。この記事では4パターンの構文から実務コードまで解説していきますね。
VBA Do Loopとは?
Do Loopは、指定した条件にもとづいて処理を繰り返すVBAのステートメントです。
たとえば「セルが空白になるまで1行ずつ読み込む」といった処理に使います。「合計金額が予算を超えるまで加算を続ける」といったケースにも対応できます。
For文が「回数指定の繰り返し」なのに対して、Do Loopは「条件指定の繰り返し」と覚えるとわかりやすいですよ。
| 比較項目 | For文 | Do Loop |
|---|---|---|
| 繰り返しの基準 | 回数(開始値〜終了値) | 条件(True / False) |
| 主な用途 | 決まった回数のループ | 終了条件が動的なループ |
| 無限ループのリスク | 低い(自動で終了) | あり(条件設定ミスに注意) |
NOTE
VBE(Visual Basic Editor)は
Alt+F11で起動します。「挿入」→「標準モジュール」でコードを書く場所を作ったら、Do Loopを試してみましょう。起動方法や画面構成がわからない方は、VBE画面の見方の記事を先にチェックしてみてください。
NOTE
Do Loopは条件を満たすまで動き続けます。条件設定を間違えると無限ループになるので、初めのうちは必ずカウンター変数を入れて安全策を取りましょう。強制終了の方法は「マクロを強制終了する方法」で解説しています。
Do Loopの基本構文4パターン
Do Loopには While と Until の2種類のキーワードがあります。さらに条件判定をループの先頭に置くか末尾に置くかで、計4パターンの構文になります。
パターン1: Do While … Loop(前判定・条件を満たす間)
条件を満たしている間、処理を繰り返します。条件判定はループに入る前に行われます。
Do While 条件式
'--- 繰り返す処理 ---
Loop
条件が最初からFalseの場合、処理は1回も実行されません。
パターン2: Do … Loop While(後判定・条件を満たす間)
処理を1回実行したあとに条件を判定します。条件を満たしている間、繰り返します。
Do
'--- 繰り返す処理 ---
Loop While 条件式
条件にかかわらず、必ず1回は処理が実行されるのがポイントです。
パターン3: Do Until … Loop(前判定・条件を満たすまで)
条件を満たすまで処理を繰り返します。条件判定はループに入る前に行われます。
Do Until 条件式
'--- 繰り返す処理 ---
Loop
Whileとは条件の意味が逆になります。「〜になるまで回す」と読むとわかりやすいですよ。
パターン4: Do … Loop Until(後判定・条件を満たすまで)
処理を1回実行したあとに条件を判定します。条件を満たすまで繰り返します。
Do
'--- 繰り返す処理 ---
Loop Until 条件式
こちらも必ず1回は処理が実行されるパターンです。
4パターンの早見表
| パターン | キーワード | 判定タイミング | 意味 | 最低実行回数 |
|---|---|---|---|---|
| Do While … Loop | While | 前判定 | 条件を満たす間 | 0回 |
| Do … Loop While | While | 後判定 | 条件を満たす間 | 1回 |
| Do Until … Loop | Until | 前判定 | 条件を満たすまで | 0回 |
| Do … Loop Until | Until | 後判定 | 条件を満たすまで | 1回 |
TIP
迷ったときは Do While … Loop(前判定・While) を使うのがおすすめです。最もよく使われるパターンで、条件を先にチェックするため安全です。
VBA Do Loopの基本コード
4パターンそれぞれの動きを確認してみましょう。どれも「1から3まで数えてメッセージを表示する」コードです。
Do While … Loop の例
Sub DoWhileLoop_Basic()
Dim i As Long 'カウンター
i = 1
Do While i <= 3
MsgBox i & "回目の処理です"
i = i + 1
Loop
MsgBox "ループが終了しました"
End Sub
i が4になった時点で i <= 3 がFalseになり、ループを抜けます。
Do Until ... Loop の例
Sub DoUntilLoop_Basic()
Dim i As Long 'カウンター
i = 1
Do Until i > 3
MsgBox i & "回目の処理です"
i = i + 1
Loop
MsgBox "ループが終了しました"
End Sub
i が4になった時点で i > 3 がTrueになり、ループを抜けます。While版とは条件式が逆になっている点に注目です。
前判定と後判定の違いを確認する
前判定と後判定の違いがよくわかるコードを見てみましょう。
Sub ComparePrePost()
Dim i As Long 'カウンター
'--- 前判定: 条件を満たさないので1回も実行されない ---
i = 10
Debug.Print "前判定の開始"
Do While i <= 3
Debug.Print "前判定: " & i
i = i + 1
Loop
'--- 後判定: 条件を満たさなくても1回は実行される ---
i = 10
Debug.Print "後判定の開始"
Do
Debug.Print "後判定: " & i
i = i + 1
Loop While i <= 3
End Sub
イミディエイトウィンドウ(Ctrl + G で表示)に結果が出力されます。前判定では何も表示されません。後判定では「後判定: 10」が1回だけ表示されます。
VBA Do Loopの実践コード
ここからは、実務で使えるパターンを紹介していきます。セル操作ではRange・Cellsプロパティを使います。Cellsの行・列を数値で指定できるので、Do Loopとの相性がいいですよ。
パターン1: 空白セルまでデータを読み込む
A列にデータが入力されていて、空白セルが見つかったら読み込みを止めるコードです。
Sub ReadUntilBlank()
Dim ws As Worksheet '対象シート
Dim i As Long '行カウンター
Dim total As Double '合計値
Set ws = ActiveSheet
i = 2 'ヘッダー行をスキップ
total = 0
Do While ws.Cells(i, 1).Value <> ""
total = total + ws.Cells(i, 2).Value
i = i + 1
Loop
MsgBox "合計: " & total & vbCrLf & _
"データ件数: " & (i - 2) & "件"
End Sub
A列が空白になった時点でループを抜けます。データの最終行を事前に調べる必要がなく、行数が変動するデータに便利です。
パターン2: 目標金額に達するまで加算する
売上データを上から順に加算して、目標金額に達した行を特定するコードです。
Sub FindTargetRow()
Dim ws As Worksheet '対象シート
Dim i As Long '行カウンター
Dim cumulative As Double '累積金額
Dim target As Double '目標金額
Set ws = ActiveSheet
i = 2
cumulative = 0
target = 1000000
Do Until cumulative >= target
If ws.Cells(i, 1).Value = "" Then
MsgBox "目標に届きませんでした"
Exit Sub
End If
cumulative = cumulative + ws.Cells(i, 2).Value
i = i + 1
Loop
MsgBox "目標達成!" & vbCrLf & _
(i - 2) & "行目で累計" & Format(cumulative, "#,##0") & "円"
End Sub
Exit Sub で「データが尽きたのにまだ目標未達」のケースも安全に処理しています。ループ内のIf文で条件分岐し、空白セルに到達したら処理を中断する仕組みです。
パターン3: ユーザー入力を繰り返し受け付ける
InputBoxで入力を受け付けて、「終了」と入力されるまで繰り返すコードです。後判定(Loop Until)の出番です。
Sub InputLoop()
Dim userInput As String '入力値
Dim items As String '入力リスト
items = ""
Do
userInput = InputBox("品名を入力してください" & vbCrLf & _
"(「終了」で登録完了)", "品名登録")
If userInput = "" Then Exit Do
If userInput <> "終了" Then
items = items & userInput & vbCrLf
End If
Loop Until userInput = "終了"
If items <> "" Then
MsgBox "登録された品名:" & vbCrLf & items
End If
End Sub
InputBoxは「最低1回は表示したい」ので、後判定がぴったりです。キャンセル(空文字)のときは Exit Do で抜けています。
パターン4: 条件に合うセルを検索する
指定した値がA列のどこにあるか、上から順に探すコードです。Rangeプロパティの End(xlUp) で最終行を取得し、Do Loopで1行ずつ照合します。
Sub SearchValue()
Dim ws As Worksheet '対象シート
Dim i As Long '行カウンター
Dim searchWord As String '検索値
Dim lastRow As Long '最終行
Dim found As Boolean '見つかったか
Set ws = ActiveSheet
searchWord = InputBox("検索する値を入力してください")
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
i = 2
found = False
Do While i <= lastRow And Not found
If ws.Cells(i, 1).Value = searchWord Then
found = True
Else
i = i + 1
End If
Loop
If found Then
MsgBox searchWord & " は " & i & "行目にあります"
ws.Cells(i, 1).Select
Else
MsgBox searchWord & " は見つかりませんでした"
End If
End Sub
And Not found で「見つかったら即終了」にしています。Findメソッドでも検索できますが、Do Loopなら途中に追加処理を挟めるのがメリットです。
無限ループの防止策
Do Loopで最も注意すべきなのが無限ループです。条件が永遠にTrueのままだと、Excelが応答しなくなります。以下の3つの対策を覚えておきましょう。
対策1: カウンター変数で上限を設ける
ループ回数を変数で管理し、上限に達したら強制終了する方法です。
Dim cnt As Long 'ループ回数カウンター
cnt = 0
Do While 条件式
'--- 処理 ---
cnt = cnt + 1
If cnt > 10000 Then
MsgBox "ループ回数が上限を超えました"
Exit Do
End If
Loop
対策2: DoEventsで中断可能にする
Do While 条件式
DoEvents '--- OSにイベント処理を返す ---
'--- 処理 ---
Loop
DoEvents を入れると、ループ中でもEscキーで中断しやすくなります。ただし処理速度はやや落ちます。
対策3: Exit Do で途中脱出する
Do While 条件式
If 異常条件 Then Exit Do
'--- 通常処理 ---
Loop
Exit Do はDo Loopを即座に抜けるステートメントです。想定外のデータに遭遇したときの安全弁になります。
NOTE
万が一無限ループに入ってしまったら、強制停止してください。Windowsは Ctrl + Break(または Esc キー連打)、Macは Command + ピリオド です。詳しくは「マクロを強制終了する方法」をご覧ください。
よくあるエラーと対処法
| エラー | 原因 | 対処法 |
|---|---|---|
| 無限ループ(応答なし) | カウンター変数の更新忘れ、条件式の設定ミス | カウンター上限を設ける。DoEvents を入れる |
| コンパイルエラー: 「Loop がありません」 | Do に対応する Loop が欠落 | インデントを揃えて Do と Loop の対応を確認する |
| コンパイルエラー: 「Do がありません」 | Loop に対応する Do が欠落 | 同上。ネストが深い場合はインデントで整理する |
| 実行時エラー '6': オーバーフロー | カウンター変数が Integer(-32,768〜32,767)で足りない | Dim i As Long に変更する(約21億まで対応) |
| 実行時エラー '91': オブジェクト変数が設定されていません | ループ内で未初期化のオブジェクトを参照 | Set でオブジェクト変数を初期化してからループに入る |
| While と Until の条件が逆 | While(〜の間)とUntil(〜になるまで)を取り違え | 「While = True の間」「Until = True になったら終了」と覚える |
NOTE
Do Loopを含むマクロは、ファイルを マクロ有効ブック(.xlsm) で保存してください。通常の .xlsx では保存時にマクロが消えてしまいます。
繰り返し処理の使い分け
VBAには3種類の繰り返しステートメントがあります。場面に合わせて使い分けましょう。
| 比較項目 | For ... Next | Do Loop | For Each ... Next |
|---|---|---|---|
| 繰り返しの基準 | 回数(開始値〜終了値) | 条件(True / False) | コレクション内の要素数 |
| 主な用途 | 行番号ループ、連番生成 | 空白セルまで、目標値まで | 全セル、全シート、配列 |
| 回数が事前にわかるか | わかる | わからないことが多い | 自動で全要素を処理 |
| ループ途中の脱出 | Exit For | Exit Do | Exit For |
| 無限ループのリスク | 低い | あり | 低い |
使い分けの目安:
TIP
「空白セルまで下に読む」のような処理はDo Loopの定番パターンです。ただし最終行を取得する方法で先に
End(xlUp).Rowで行数を確定させ、Forループで回す方法もあります。好みや可読性で選んで大丈夫ですよ。
まとめ
Do Loopは「条件にもとづいて繰り返す」ためのステートメントです。
- While = 条件を満たしている間繰り返す
- Until = 条件を満たすまで繰り返す
- 前判定(Do While / Do Until)= 条件次第で1回も実行されない
- 後判定(Loop While / Loop Until)= 必ず1回は実行される
- 迷ったら Do While ... Loop(前判定・While)を選ぶ
- カウンター変数 と Exit Do で無限ループを防ぐ
条件付きの繰り返し処理が書けると、VBAの活用幅がぐっと広がります。まずは基本コードをVBEに貼り付けて、動きを確認してみてくださいね。
Do Loopを使いこなせたら、次はVBA学習ロードマップで全体の学習ステップを確認してみましょう。
