- 技術 💻
VBAループの書き方一覧|For・For Each・Do Whileの違い
VBAのループは、回数が決まるなら For Next、集合の全要素なら For Each、終わりが条件で決まるなら Do Loop を使います。 この3つの型を選び分けられれば、最終行までの繰り返しも、シート全部の処理も、同じ考え方で書けます。
この記事では、型の選び方を冒頭の表で示したうえで、よく使う20パターンをコピーして使えるコードで並べます。前判定と後判定で実行回数がどう変わるか、Exit For と Exit Do がどこまで抜けるかは、同じ題材のコードを動かした出力で確かめます。
確認環境:LibreOffice 24.2.7.2 の Basic(VBA 互換モード、Option VBASupport 1)で各コードをヘッドレス実行(確認日 2026-10-05)。記事中の「出力」はこの環境でイミディエイトウィンドウ相当の出力を取ったものです。構文と Excel での決まりは Microsoft Learn の VBA リファレンスを開いて確認し、出典を示しています。Dictionary(No.15)は Microsoft Learn の記載に沿ったコードのみを載せています。
この記事の結論
- 回数が決まる → For Next。最終行までの繰り返しも「2 から最終行まで」と回数が決まるので For Next です。
- 集合の全要素 → For Each。セル範囲、シート、ブック、Collection、配列を先頭から順に取り出します。
- 終わりが条件で決まる → Do Loop。条件を先頭に書くと0回のことがあり、末尾に書くと最低1回は実行されます。
- Exit For/Exit Do が抜けるのは内側の1段だけ。多重ループを一度に抜けるには、フラグを使うか、ループを Function に切り出して Exit Function で抜けます。
- 行を削除するループは下から上へ(Step -1)進めます。
VBAループ5構文の早見表
| 構文 | 判定の位置 | 最低実行回数 | 途中で抜ける文 | 向く用途 |
|---|---|---|---|---|
For i = 1 To n … Next |
先頭(前判定) | 0回 | Exit For |
回数・行番号・列番号が決まっている繰り返し |
For Each x In 集合 … Next |
先頭(要素があれば入る) | 0回 | Exit For |
セル範囲・シート・ブック・Collection・配列の全要素 |
Do While 条件 … Loop / Do Until 条件 … Loop |
先頭(前判定) | 0回 | Exit Do |
空白セルまで、条件を満たす間だけ |
Do … Loop While 条件 / Do … Loop Until 条件 |
末尾(後判定) | 1回 | Exit Do |
まず1回実行してから続けるか決める処理 |
While 条件 … Wend |
先頭(前判定) | 0回 | (専用の Exit 文なし) | 既存コードの読み解き |
選び方フロー
- 繰り返す回数(開始と終了の番号)が、ループに入る前に分かりますか。 → はい:For Next
- セル範囲・シート・配列など「集合の中身を全部」処理しますか。 → はい:For Each
- 終わりが「空白になるまで」「値が○○になるまで」のような条件ですか。 → はい:Do Loop
- Do Loop で、1回目は必ず実行したいですか。 → はい:
Do … Loop While/Until(末尾判定)、いいえ:Do While/Until … Loop(先頭判定)
| 条件 | 選ぶ型 |
|---|---|
| 行番号・列番号を使ってセルを読み書きする | For Next |
| 行を削除・挿入しながら進む | For Next(Step -1) |
| 番号を使わず、要素そのものを順に取り出す | For Each |
| 何行あるか数えずに、空白セルで止めたい | Do While/Do Until |
| 入力や再試行のように、最低1回は処理する | Do … Loop While/Until |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「VBAループの書き方一覧|For・For Each・Do Whileの違い」
サンプルデータを用意する
以降のコードは、Sheet1 に次の表がある前提です。標準モジュールに貼って MakeSample を実行すると、同じ表が作られます。
| A | B | C | |
|---|---|---|---|
| 1 | 品名 | 数量 | 状態 |
| 2 | ノート | 3 | 済 |
| 3 | ペン | 12 | |
| 4 | 付箋 | 0 | 済 |
| 5 | ファイル | 7 | |
| 6 | 電池 | 0 |
Sub MakeSample()
Dim ws As Worksheet
Set ws = Worksheets("Sheet1")
ws.Cells.Clear
ws.Range("A1:C1").Value = Array("品名", "数量", "状態")
ws.Range("A2:C2").Value = Array("ノート", 3, "済")
ws.Range("A3:C3").Value = Array("ペン", 12, "")
ws.Range("A4:C4").Value = Array("付箋", 0, "済")
ws.Range("A5:C5").Value = Array("ファイル", 7, "")
ws.Range("A6:C6").Value = Array("電池", 0, "")
End Sub
各コードの Debug.Print は、VBE のイミディエイトウィンドウ(Ctrl+G)に出力します。モジュールの先頭には Option Explicit を書いておくと、変数名の打ち間違いをコンパイル時に見つけられます。
For Nextの書き方(No.1〜4)
1. 決まった回数だけ繰り返す
Sub P01_FixedCount()
Dim i As Long
For i = 1 To 3
Debug.Print i & "回目"
Next i
End Sub
出力:
1回目
2回目
3回目
2. Stepで1つおき・逆順に進める
Microsoft Learn の For...Next ステートメントのページでは、Step を省略すると増分は 1 になり、Step が正または 0 のときは「カウンター <= 終了値」、負のときは「カウンター >= 終了値」の間だけ実行されると説明されています。
Sub P02_Step()
Dim i As Long, s As String
For i = 1 To 9 Step 2
s = s & i & " "
Next i
Debug.Print s
s = ""
For i = 5 To 1 Step -1
s = s & i & " "
Next i
Debug.Print s
End Sub
出力:
1 3 5 7 9
5 4 3 2 1
3. 最終行まで繰り返す
A列のいちばん下のセルから上へ向かって、データのあるセルを探します。End(xlUp) はキーボードの End+↑ と同じ動きです。
Sub P03_LastRow()
Dim ws As Worksheet, lastRow As Long, r As Long
Set ws = Worksheets("Sheet1")
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
For r = 2 To lastRow
Debug.Print r & "行目: " & ws.Cells(r, 1).Value
Next r
End Sub
出力:
2行目: ノート
3行目: ペン
4行目: 付箋
5行目: ファイル
6行目: 電池
4. 最終列まで繰り返す
1行目の右端のセルから左へ向かって探します。
Sub P04_LastColumn()
Dim ws As Worksheet, lastCol As Long, c As Long
Set ws = Worksheets("Sheet1")
lastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
For c = 1 To lastCol
Debug.Print c & "列目: " & ws.Cells(1, c).Value
Next c
End Sub
出力:
1列目: 品名
2列目: 数量
3列目: 状態
Do Loopの書き方(No.5〜7)
5. 空白セルまで繰り返す(Do While)
「A列が空白でない間」繰り返します。行番号を自分で 1 ずつ進める点が For Next との違いです。r = r + 1 を書き忘れるとループが終わらなくなるので、ループの最後の行に置く習慣にすると安心です。
Sub P05_DoWhileBlank()
Dim ws As Worksheet, r As Long
Set ws = Worksheets("Sheet1")
r = 2
Do While ws.Cells(r, 1).Value <> ""
Debug.Print ws.Cells(r, 1).Value
r = r + 1
Loop
Debug.Print "止まった行: " & r
End Sub
出力:
ノート
ペン
付箋
ファイル
電池
止まった行: 7
6. 空白セルまで繰り返す(Do Until)
同じ処理を「A列が空白になるまで」と書いた形です。While と Until は条件の向きが逆なだけで、読みやすい方を選べます。
Sub P06_DoUntilBlank()
Dim ws As Worksheet, r As Long, total As Long
Set ws = Worksheets("Sheet1")
r = 2
Do Until IsEmpty(ws.Cells(r, 1).Value)
total = total + ws.Cells(r, 2).Value
r = r + 1
Loop
Debug.Print "数量の合計: " & total
End Sub
出力:
数量の合計: 22
7. 最低1回は実行する(Do … Loop While)
条件を末尾に書くと、1回目は条件に関係なく実行されます。
Sub P07_AtLeastOnce()
Dim n As Long, tryCount As Long
n = 100
Do
tryCount = tryCount + 1
n = n \ 2
Loop While n > 10
Debug.Print "回数: " & tryCount & " / 値: " & n
End Sub
出力:
回数: 4 / 値: 6
行を削除するループ(No.8)
8. 逆順で行を削除する
数量が 0 の行を削除します。下から上へ(Step -1)進めるのがポイントです。
Sub P08_DeleteRowsBackward()
Dim ws As Worksheet, lastRow As Long, r As Long
Set ws = Worksheets("Sheet1")
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
For r = lastRow To 2 Step -1
If ws.Cells(r, 2).Value = 0 Then
ws.Rows(r).Delete
End If
Next r
Debug.Print "残った最終行: " & ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
End Sub
出力:
残った最終行: 4
実行後の表は、ノート・ペン・ファイルの3行になります。
上から下へ進めた場合の動きも確かめました。数量 0 の行が2つ続く表(4行目が付箋、5行目が電池、6行目がファイル)で For r = 2 To lastRow と書いて削除すると、結果は次のとおりです。
2: ノート / 3
3: ペン / 12
4: 電池 / 0
5: ファイル / 7
4行目の付箋を削除した時点で電池が4行目に上がり、ループは次の5行目へ進むため、電池の行が判定されずに残ります。下から進めれば、削除で動くのは処理済みの行だけなので、この行ずれが起きません。
For Eachの書き方(No.9〜17)
9. セル範囲の全セルを処理する
Sub P09_ForEachCell()
Dim c As Range
For Each c In Worksheets("Sheet1").Range("B2:B6").Cells
If c.Value >= 5 Then
Debug.Print c.Address & " = " & c.Value
End If
Next c
End Sub
出力:
$B$3 = 12
$B$5 = 7
10. 表全体を1行ずつ処理する
CurrentRegion は、指定したセルを含む、空白行と空白列で囲まれた範囲です。.Rows を付けると行単位で取り出せます。
Sub P10_EachRowOfTable()
Dim rw As Range
For Each rw In Worksheets("Sheet1").Range("A1").CurrentRegion.Rows
Debug.Print rw.Row & ": " & rw.Cells(1, 1).Value & " / " & rw.Cells(1, 2).Value
Next rw
End Sub
出力:
1: 品名 / 数量
2: ノート / 3
3: ペン / 12
4: 付箋 / 0
5: ファイル / 7
6: 電池 / 0
11. 配列を添字で回す
配列の下限と上限は LBound と UBound で取ります。Array 関数で作った配列は、既定では添字が 0 から始まります。
Sub P11_ArrayIndex()
Dim areas As Variant, i As Long
areas = Array("東", "西", "南", "北")
For i = LBound(areas) To UBound(areas)
Debug.Print i & ": " & areas(i)
Next i
End Sub
出力:
0: 東
1: 西
2: 南
3: 北
12. 配列をFor Eachで回す
Microsoft Learn の For Each...Next ステートメントのページには、配列を回すときの要素の変数は Variant 型に限ると書かれています。
Sub P12_ArrayForEach()
Dim areas As Variant, v As Variant
areas = Array("東", "西", "南", "北")
For Each v In areas
Debug.Print v
Next v
End Sub
出力:
東
西
南
北
13. セル範囲を2次元配列に読み込んで回す
セル範囲の Value を Variant 型の変数に入れると、行×列の2次元配列になります。添字は行・列とも 1 から始まります。
Sub P13_TwoDimArray()
Dim data As Variant, r As Long, c As Long, rowText As String
data = Worksheets("Sheet1").Range("A1:C3").Value
For r = LBound(data, 1) To UBound(data, 1)
rowText = ""
For c = LBound(data, 2) To UBound(data, 2)
rowText = rowText & "[" & data(r, c) & "]"
Next c
Debug.Print rowText
Next r
End Sub
出力:
[品名][数量][状態]
[ノート][3][済]
[ペン][12][]
14. Collectionを回す
Sub P14_Collection()
Dim col As New Collection, v As Variant
col.Add "A-001"
col.Add "A-002"
col.Add "A-003"
For Each v In col
Debug.Print v
Next v
Debug.Print "件数: " & col.Count
End Sub
出力:
A-001
A-002
A-003
件数: 3
15. Dictionaryのキーを回す
Microsoft Learn の Dictionary オブジェクトのページでは、CreateObject("Scripting.Dictionary") で作成し、Keys メソッドがすべてのキーの配列を返すと説明されています。配列なので、要素の変数は Variant 型にします。
Sub P15_DictionaryKeys()
Dim d As Object, k As Variant
Set d = CreateObject("Scripting.Dictionary")
d.Add "ノート", 3
d.Add "ペン", 12
d.Add "ファイル", 7
For Each k In d.Keys
Debug.Print k & " = " & d.Item(k)
Next k
Debug.Print "件数: " & d.Count
End Sub
16. ブック内のシートを全部回す
Sub P16_AllSheets()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
Debug.Print ws.Index & ": " & ws.Name
Next ws
End Sub
出力(シートが1枚のブックで実行):
1: Sheet1
17. 開いているブックを全部回す
開いているブックの名前が1行ずつ出力されます。
Sub P17_AllBooks()
Dim wb As Workbook
For Each wb In Workbooks
Debug.Print wb.Name
Next wb
End Sub
ループを途中で抜ける・飛ばす(No.18〜20)
18. 見つかったら抜ける(Exit For)
Microsoft Learn の Exit ステートメントのページでは、Exit For は Next の次のステートメントへ制御を移すと説明されています。見つからなかった場合に備えて、結果の変数(ここでは foundRow)が初期値のままかどうかをループの後で調べます。
Sub P18_ExitFor()
Dim ws As Worksheet, lastRow As Long, r As Long, foundRow As Long
Set ws = Worksheets("Sheet1")
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
For r = 2 To lastRow
If ws.Cells(r, 1).Value = "付箋" Then
foundRow = r
Exit For
End If
Next r
If foundRow = 0 Then
Debug.Print "見つかりませんでした"
Else
Debug.Print "見つかった行: " & foundRow
End If
End Sub
出力:
見つかった行: 4
19. 条件に合う行だけ処理して次の周回へ進む
VBA には、他の言語の continue に当たる専用の文がありません。処理したい条件を If で囲む形にすると、条件に合わない行は何もせず次の周回へ進みます。
Sub P19_SkipToNext()
Dim ws As Worksheet, lastRow As Long, r As Long
Set ws = Worksheets("Sheet1")
lastRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row
For r = 2 To lastRow
If ws.Cells(r, 3).Value <> "済" Then
Debug.Print "処理する: " & ws.Cells(r, 1).Value
End If
Next r
End Sub
出力:
処理する: ペン
処理する: ファイル
処理する: 電池
Next の直前にラベルを置いて GoTo で飛ぶ書き方もあります。次のコードは奇数だけを出力します。
Sub GotoContinue()
Dim i As Long
For i = 1 To 5
If i Mod 2 = 0 Then GoTo ContinueLoop
Debug.Print i
ContinueLoop:
Next i
End Sub
出力:
1
3
5
Microsoft Learn の GoTo ステートメントのページでは、GoTo が多いとコードが読みにくくデバッグしにくくなるため、できるだけ構造化された制御ステートメント(Do...Loop、For...Next、If...Then...Else、Select Case)を使うよう案内されています。飛ばす条件が1つなら If で囲む形、条件がいくつも重なって入れ子が深くなるときに GoTo、と使い分けると読みやすさを保てます。
20. 多重ループを一度に抜ける
次の章で、2通りの書き方をコードつきで説明します。
Exit For・Exit Doは内側の1段だけを抜ける
Microsoft Learn の Exit ステートメントのページには、入れ子になった For ループの中で Exit For を使うと、Exit For のあるループの1つ上の階層のループへ制御が移ると書かれています。Exit Do も同じ説明です。次のコードで確かめられます。
Sub ExitOneLevel()
Dim i As Long, j As Long
For i = 1 To 3
For j = 1 To 3
If j = 2 Then Exit For
Debug.Print "i=" & i & " j=" & j
Next j
Next i
Debug.Print "終了時 i=" & i & " j=" & j
End Sub
出力:
i=1 j=1
i=2 j=1
i=3 j=1
終了時 i=4 j=2
内側のループは j=2 で抜けていますが、外側の i は 1 から 3 まで最後まで進んでいます。
書き方1:フラグで外側も抜ける
内側を抜けた直後に、外側でフラグを調べてもう一度 Exit For します。
Sub P20_ExitNestedByFlag()
Dim ws As Worksheet, r As Long, c As Long, found As Boolean
Set ws = Worksheets("Sheet1")
For r = 1 To 6
For c = 1 To 3
If ws.Cells(r, c).Value = 12 Then
found = True
Exit For
End If
Next c
If found Then Exit For
Next r
If found Then Debug.Print "見つかった位置: " & r & "行 " & c & "列"
End Sub
出力:
見つかった位置: 3行 2列
書き方2:Functionに切り出してExit Functionで抜ける
多重ループを1つの Function にまとめると、Exit Function でプロシージャごと抜けられます。Exit ステートメントのページでは、Exit Function はその Function プロシージャをただちに終了し、呼び出し元の次のステートメントから実行が続くと説明されています。
Function FindCellAddress(ByVal target As Variant) As String
Dim ws As Worksheet, r As Long, c As Long
Set ws = Worksheets("Sheet1")
For r = 1 To 6
For c = 1 To 3
If ws.Cells(r, c).Value = target Then
FindCellAddress = ws.Cells(r, c).Address
Exit Function
End If
Next c
Next r
End Function
Sub ExitNestedByFunction()
Debug.Print "12 の位置: " & FindCellAddress(12)
Debug.Print "99 の位置: [" & FindCellAddress(99) & "]"
End Sub
出力:
12 の位置: $B$3
99 の位置: []
| 書き方 | 向く場面 | 気を付ける点 |
|---|---|---|
| フラグ+Exit For を各段に書く | 抜けた後も同じプロシージャで処理を続ける | 段数ぶんの判定が必要 |
| Function に切り出して Exit Function | 「探して結果を返す」処理 | 見つからないときの戻り値(空文字など)を決めておく |
Do Loop の入れ子でも考え方は同じです。外側の条件にフラグを加えると、内側で Exit Do した後に外側も終わります。
Sub ExitNestedDo()
Dim r As Long, c As Long, done As Boolean
r = 1
Do While r <= 3 And Not done
c = 1
Do While c <= 3
If r * c = 4 Then
done = True
Exit Do
End If
c = c + 1
Loop
If Not done Then r = r + 1
Loop
Debug.Print "r=" & r & " c=" & c
End Sub
出力:
r=2 c=2
Do While・Do Until・While Wendを同じ題材で書き分ける
「開始行から A列が空白になるまでの行数を数える」という同じ題材を、5通りで書きます。
Sub CompareForms()
Dim ws As Worksheet
Set ws = Worksheets("Sheet1")
Debug.Print "開始行=2(データあり)"
CompareFrom ws, 2
Debug.Print "開始行=10(最初から空白)"
CompareFrom ws, 10
End Sub
Sub CompareFrom(ByVal ws As Worksheet, ByVal startRow As Long)
Dim r As Long, n As Long
r = startRow: n = 0
Do While ws.Cells(r, 1).Value <> ""
n = n + 1: r = r + 1
Loop
Debug.Print " Do While … Loop : " & n & "回"
r = startRow: n = 0
Do Until ws.Cells(r, 1).Value = ""
n = n + 1: r = r + 1
Loop
Debug.Print " Do Until … Loop : " & n & "回"
r = startRow: n = 0
Do
n = n + 1: r = r + 1
Loop While ws.Cells(r, 1).Value <> ""
Debug.Print " Do … Loop While : " & n & "回"
r = startRow: n = 0
Do
n = n + 1: r = r + 1
Loop Until ws.Cells(r, 1).Value = ""
Debug.Print " Do … Loop Until : " & n & "回"
r = startRow: n = 0
While ws.Cells(r, 1).Value <> ""
n = n + 1: r = r + 1
Wend
Debug.Print " While … Wend : " & n & "回"
End Sub
データのある2行目から始めた場合と、最初から空白の10行目から始めた場合の出力です。
開始行=2(データあり)
Do While … Loop : 5回
Do Until … Loop : 5回
Do … Loop While : 5回
Do … Loop Until : 5回
While … Wend : 5回
開始行=10(最初から空白)
Do While … Loop : 0回
Do Until … Loop : 0回
Do … Loop While : 1回
Do … Loop Until : 1回
While … Wend : 0回
| 書き方 | 続ける条件 | 判定の位置 | 最初から条件を満たさないとき |
|---|---|---|---|
Do While 条件 … Loop |
条件が True の間 | 先頭 | 0回 |
Do Until 条件 … Loop |
条件が True になるまで | 先頭 | 0回 |
Do … Loop While 条件 |
条件が True の間 | 末尾 | 1回 |
Do … Loop Until 条件 |
条件が True になるまで | 末尾 | 1回 |
While 条件 … Wend |
条件が True の間 | 先頭 | 0回 |
データがあるときは5通りとも同じ回数になり、差が出るのは「最初から条件を満たさないとき」だけです。末尾判定は空白セルに対しても1回処理してしまうので、空の表が渡される可能性があるなら先頭判定を選びます。
While … Wend は Do While … Loop と同じ動きです。Microsoft Learn の While...Wend ステートメントのページには、Do...Loop ステートメントのほうが、より構造化された柔軟な方法でループを実行できると書かれています。Exit ステートメントの一覧(Exit Do・Exit For・Exit Function・Exit Property・Exit Sub)にも While … Wend 用のものは無いため、新しく書くコードでは Do While … Loop を選ぶと、途中で抜ける処理を後から足せます。
ループの中でエラーが起きても次の要素へ進む
1件でエラーになっても残りを処理したいときは、エラー処理ルーチンで記録してから Resume ラベル で Next の直前へ戻します。次のコードは、100 を各要素で割った商を合計し、0 で割る要素を読み飛ばします。
Sub LoopWithErrorHandling()
Dim items As Variant, i As Long, total As Long, skipped As Long
items = Array(4, 0, 5, 10)
For i = LBound(items) To UBound(items)
On Error GoTo RowError
total = total + 100 \ items(i)
On Error GoTo 0
NextItem:
Next i
Debug.Print "合計: " & total & " / 読み飛ばし: " & skipped & "件"
Exit Sub
RowError:
skipped = skipped + 1
Debug.Print " " & i & "番目を読み飛ばし: エラー " & Err.Number
Resume NextItem
End Sub
出力:
1番目を読み飛ばし: エラー 11
合計: 55 / 読み飛ばし: 1件
On Error GoTo 0 をループの中に書いて、エラーを拾う範囲を「エラーになり得る1行」に絞っています。読み飛ばした件数を最後に出しておくと、処理漏れに気付けます。
確かめて分かったこと
- For Next を最後まで回した後のカウンターは、終了値より1つ進んでいます。
For i = 1 To 3の後のiは 4 でした。「最後に処理した番号」として使うときは 1 を引くか、別の変数に控えておきます。 - 開始値が終了値より大きく、Step を書かない For は1回も実行されません。
For i = 5 To 1の実行回数は 0 でした。逆順にはStep -1が必要です。 - 内側を Exit For で抜けたとき、外側のカウンターは最後まで進みます。上の出力では、終了時に i=4、j=2 でした。
- 上から下へ行を削除すると、条件に合う行が連続したところで1行残りました。下から上へ進めると残りません。
- 末尾判定の Do … Loop は、最初から空白の行でも1回実行されました。先頭判定の3通りは0回です。
- セル範囲を読み込んだ2次元配列の添字は 1 始まり、Array 関数の配列は 0 始まりでした。どちらも LBound・UBound で回せば、始まりの番号を意識せずに済みます。
よくある質問
Q. For Next と For Each の違いは? A. For Next は番号で回し、For Each は要素そのものを順に取り出します。行番号や列番号が必要な処理(行の削除、隣のセルへの書き込み)は For Next、範囲やシートを全部処理するだけなら For Each が短く書けます。
Q. Do While と Do Until の違いは?
A. 条件の向きが逆です。Do While は条件が True の間、Do Until は条件が True になるまで繰り返します。Do While x <> "" と Do Until x = "" は同じ動きです。
Q. ループが終わらないときは? A. Esc キーか Ctrl+Break で止められます(Microsoft Learn「Do...Loop ステートメントを使用する」の記載)。止めた後、Do Loop の中で行番号やカウンターを進める行があるかを確かめます。
Q. 多重ループを一度に抜けるには? A. Exit For・Exit Do は内側の1段しか抜けないので、フラグを立てて外側でも Exit するか、ループを Function に切り出して Exit Function で抜けます。
Q. 最終行まで繰り返すには For と Do のどちらを使う?
A. 途中に空白行がある表なら、Cells(Rows.Count, 1).End(xlUp).Row で最終行を取って For Next で回します。Do While で空白まで進める書き方は、途中の空白行で止まります。
まとめ
- 回数が決まるなら For Next、集合の全要素なら For Each、終わりが条件で決まるなら Do Loop。
- 先頭判定は0回のことがあり、末尾判定は最低1回。空の表があり得るなら先頭判定にします。
- Do While と Do Until は条件の向きが逆なだけで、While … Wend は Do While … Loop と同じ動きです。
- Exit For/Exit Do は内側の1段だけ。多重ループはフラグか、Function + Exit Function で抜けます。
- 行の削除は Step -1 で下から上へ。
- 配列を For Each で回す変数は Variant 型、番号が必要なら LBound から UBound まで For Next で回します。
- ループ中のエラーは、範囲を絞った On Error と Resume ラベルで次の要素へ進めます。
参考・出典
- Microsoft Learn「For...Next statement」「For Each...Next statement」「Do...Loop statement」「While...Wend statement」「Exit statement」「GoTo statement」(VBA 言語リファレンス、2026-10-05 確認)
- Microsoft Learn「Using Do...Loop statements」「Looping through a range of cells」(2026-10-05 確認)
- Microsoft Learn「Range.End property (Excel)」「Dictionary object」(2026-10-05 確認)
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「VBAループの書き方一覧|For・For Each・Do Whileの違い」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。