VBA Do Loopの使い方|Do While・Do Untilを4パターンで解説

スポンサーリンク

「条件を満たすまで処理を繰り返したい……」

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には WhileUntil の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 … LoopWhile前判定条件を満たす0回
Do … Loop WhileWhile後判定条件を満たす1回
Do Until … LoopUntil前判定条件を満たすまで0回
Do … Loop UntilUntil後判定条件を満たすまで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 が欠落インデントを揃えて DoLoop の対応を確認する
コンパイルエラー: 「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 ... NextDo LoopFor Each ... Next
繰り返しの基準回数(開始値〜終了値)条件(True / False)コレクション内の要素数
主な用途行番号ループ、連番生成空白セルまで、目標値まで全セル、全シート、配列
回数が事前にわかるかわかるわからないことが多い自動で全要素を処理
ループ途中の脱出Exit ForExit DoExit For
無限ループのリスク低いあり低い

使い分けの目安:

  • 回数が決まっているFor文
  • 条件で終了タイミングが変わる → Do Loop
  • コレクション(セル範囲・全シート・配列)を順に処理For Each

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学習ロードマップで全体の学習ステップを確認してみましょう。

関連記事

タイトルとURLをコピーしました