【この記事について】本記事に載せた VBA のコードは、2026年10月29日に Microsoft 365 の Excel(Windows デスクトップ版)ですべて実際に実行し、結果を確かめたものです。構文の説明は Microsoft Learn の公式リファレンス(記事末尾に出典)に沿っています。マクロは元に戻せない変更をすることがあります。会社のファイルで試す前に、必ずコピーを取ってから実行してください。マクロの利用が会社のルールで制限されている場合は、そちらに従ってください。本記事の内容の利用は、ご自身の判断と責任でお願いします。
対象環境:Windows 11 / Microsoft 365 の Excel(デスクトップ版・バージョン 16.0 ビルド 20527)。2026年10月29日に全コードの動作を確認。難易度:VBA 入門(マクロを1回でも貼り付けて動かしたことがある人向け)。
VBA のループ(繰り返し)は、実務で使うのは3種類だけです。回数が決まっているなら For Next、セル範囲やシートを「全部」処理するなら For Each、どこで終わるか分からないなら Do While/Do Until。古い書き方の While…Wend は覚えなくて大丈夫です。止まらなくなったら Esc キー(または Ctrl+Break)で中断できます。この記事では、4種類の使い分けを、実機の Excel で動かして確かめたコードで整理します。

この記事は「どのループを選ぶか」と「抜け方・止め方」に絞ります。For Next の Step(1行おき・逆順)や「1回も回らない」ときの直し方は、こちらで詳しく扱っています。

🔎 あわせて確認されている記事
まず結論|VBA のループ4種類の早見表
| ループ | 向いている場面 | 終わり方 |
|---|---|---|
| For Next | 「1行目から100行目まで」のように回数が決まっている | カウンターが終わりの数を超えたら |
| For Each | 選んだセル範囲・全シートなど「全部」を1つずつ | 中身を全部たどったら |
| Do While/Do Until | 「空白のセルが来るまで」など終わりが分からない | 条件を満たさなくなったら(While)/満たしたら(Until) |
| While…Wend | 古い書き方。今から覚える必要はない | 条件が False になったら |
迷ったら、「何回やるか分かっている?」と自分に聞いてください。分かっていれば For Next、分からなければ Do While/Do Until。セルやシートを「全部」触るなら For Each です。
この記事のコードを試すための準備
新しいブックの1枚目のシートに、次の小さな表を作ってから試すと、記事と同じ結果になります。
- A1 に「数量」、A2〜A11 に 10、20、30 … 100(10 刻み)
- B1 に「メモ」、B2〜B11 に「済」。ただし B5・B8・B9 だけ空白にしておく
コードは、Alt+F11 で VBE(マクロの編集画面)を開き、[挿入]→[標準モジュール]に貼り付けます。実行したい Sub の中にカーソルを置いて F5 を押すと動きます。Debug.Print の結果は、Ctrl+G で開く「イミディエイト ウィンドウ」に表示されます。
For Next|回数が決まっているとき
いちばん基本のループです。For i = 1 To 10 は「i を 1 から 10 まで、1 ずつ増やしながら繰り返す」という意味です。
Sub Loop_ForNext()
Dim i As Long
For i = 1 To 10
Cells(i, 4).Value = i
Next i
End Sub
実行結果:D1〜D10 に 1〜10 の連番が入りました。D11 は空のままです(10 回で止まっている)。
カウンター(ここでは i)は Long 型で宣言しておくのが安全です。Integer 型だと 32,767 行を超えたところでエラーになります。理由と、Step で1行おきや逆順に回す書き方は、冒頭で紹介した For Next の記事にまとめています。
For Each|セル範囲やシートを「全部」処理するとき
For Each は、範囲の中のセルを1つずつ取り出して処理します。何行目かを数えなくてよいのが強みです。
例:空白のセルに「未入力」と入れる
Sub Loop_ForEach()
Dim c As Range
For Each c In Range("B2:B11")
If c.Value = "" Then c.Value = "未入力"
Next c
End Sub
実行結果:B2〜B11 のうち、空白だった B5・B8・B9 にだけ「未入力」が入り、「済」のセルはそのままでした。
c には、ループのたびに B2、B3、B4 … のセルが順番に入ります。だから c.Value と書くだけで、いま見ているセルの値を扱えます。
例:ブックの全シートの名前を書き出す
Sub Loop_Sheets()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
Debug.Print ws.Name
Next ws
End Sub
実行結果:シートが「Sheet1」「集計」の2枚のブックで実行すると、イミディエイト ウィンドウに Sheet1、集計 の順で2行表示されました。シートが何枚あっても、書き換えずにそのまま使えます。
Do While/Do Until|どこで終わるか分からないとき
「データが何行あるか分からないけれど、空白のセルが来たら終わり」。事務の表ではこちらのほうが多いかもしれません。そんなときは Do…Loop を使います。
Do While:条件を満たしている「間」繰り返す
Sub Loop_DoWhile()
Dim r As Long
r = 2
Do While Cells(r, 1).Value <> ""
Cells(r, 3).Value = Cells(r, 1).Value * 2
r = r + 1
Loop
End Sub
実行結果:C2〜C11 に、A列の2倍(20、40 … 200)が入りました。A12 が空白なので、そこで止まり、C12 は空のままです。
Do Until:条件を満たす「まで」繰り返す
Sub Loop_DoUntil()
Dim r As Long
r = 2
Do Until Cells(r, 1).Value = ""
Cells(r, 5).Value = Cells(r, 1).Value * 3
r = r + 1
Loop
End Sub
実行結果:E2〜E11 に、A列の3倍(30、60 … 300)が入り、同じく12行目で止まりました。
見比べると分かるとおり、Do While は「〜の間」、Do Until は「〜になるまで」で、条件の向きが逆なだけです。上の2つは同じ動きをします。読んで自然なほうを選べば大丈夫です。「空白が来るまで」と考えるなら Until、「値が入っている間」と考えるなら While が読みやすくなります。
前判定と後判定|「必ず1回は実行したい」とき
Do…Loop には、条件を最初に調べる書き方(前判定)と、最後に調べる書き方(後判定)があります。違いは「最初から条件を満たしていないとき、1回も動かないか、1回は動くか」です。
Sub Loop_PrePost()
Dim cnt As Long, ok As Boolean
ok = False
cnt = 0
Do While ok
cnt = cnt + 1
Loop
Debug.Print "前判定の実行回数:" & cnt
cnt = 0
Do
cnt = cnt + 1
Loop While ok
Debug.Print "後判定の実行回数:" & cnt
End Sub
実行結果:イミディエイト ウィンドウに「前判定の実行回数:0」「後判定の実行回数:1」と表示されました。条件(ok)は最初から False なのに、後判定は1回だけ中身を実行しています。
「入力ボックスで聞いて、正しい値が入るまで聞き直す」のように、最低1回は必ず実行したい処理には後判定が向いています。それ以外は、前判定の Do While/Do Until を使えば十分です。
While…Wend は今は使わなくてよい
古いマクロを開くと、While と Wend で囲まれたループを見かけることがあります。
Sub Loop_WhileWend()
Dim i As Long
i = 1
While i <= 3
Debug.Print i
i = i + 1
Wend
End Sub
実行結果:イミディエイト ウィンドウに 1、2、3 と表示されました。動きは Do While ... Loop と同じです。
Microsoft のリファレンスにも、Do…Loop を使うほうが、より構造化された柔軟な方法でループを実行できるとあります。While…Wend には、途中で抜ける Exit の仕組みがありません。読めれば十分で、新しく書くときは Do While を使いましょう。
途中で抜ける|Exit For/Exit Do
探しているものが見つかったら、残りを回す必要はありません。For のループは Exit For、Do のループは Exit Do で、その場でループを抜けられます。
Sub Loop_ExitFor()
Dim i As Long
For i = 2 To 1000
If Cells(i, 1).Value = "" Then Exit For
If Cells(i, 2).Value = "未入力" Then
Debug.Print "最初の未入力は " & i & " 行目"
Exit For
End If
Next i
End Sub
実行結果:前の節の For Each の例を実行した後に動かすと、「最初の未入力は 5 行目」と1行だけ表示されました。8行目・9行目の「未入力」までは見に行っていません。
この例には、抜け道が2つあります。A列が空白になったら(データの終わり)と、「未入力」が見つかったらです。For i = 2 To 1000 と大きめに書いておき、データの終わりで抜けるようにしておくと、行数が増えても書き換えずに済みます。
入れ子(二重ループ)で表を作る
ループの中にループを書くと、縦と横の両方向に処理できます。九九の表を作ってみます。
Sub Loop_Nested()
Dim r As Long, c As Long
For r = 1 To 9
For c = 1 To 9
Cells(r + 20, c).Value = r * c
Next c
Next r
End Sub
実行結果:A21〜I29 に九九の表ができました。21行目は 1〜9、29行目の I列は 81、23行目の D列は 3×4 の 12 です。
外側の r が1つ進むたびに、内側の c が 1〜9 を一周します。内側の Exit For は内側のループしか抜けない点など、入れ子の注意は For Next の記事で詳しく扱っています。
無限ループを防ぐ・止める
Do…Loop は、条件の書き方を間違えるといつまでも終わらない「無限ループ」になります。よくあるのは、r = r + 1 を書き忘れて、同じ行を見続けてしまうケースです。
止め方:Esc キーまたは Ctrl+Break
Excel が固まったように見えたら、Esc キーを押してください(効かなければ Ctrl+Break)。Microsoft のリファレンスでも、Ctrl+Break または Esc キーで実行中のプロシージャを中断できると説明されています。中断のメッセージが出たら[終了]を押せば止まります。
ただし、マクロの中で Application.EnableCancelKey を変えていると、この中断が効かなくなります。Microsoft も「このプロパティは慎重に使用してください」と注意しています。他人が作ったマクロを動かす前には、この1行が入っていないかを見ておくと安心です。
防ぎ方:回数の上限を決めておく
念のため、「これ以上は回らないはず」という上限を書いておくと、万一のときも自動で止まります。
Sub Loop_Safe()
Dim r As Long
r = 2
Do Until Cells(r, 1).Value = ""
r = r + 1
If r > 100000 Then
Debug.Print "10万行を超えたので止めました"
Exit Do
End If
Loop
Debug.Print "データの次の行は " & r & " 行目"
End Sub
実行結果:データが11行目まであるので、「データの次の行は 12 行目」と表示されました。上限の10万行には届いていないので、止めましたのメッセージは出ていません。
ループが遅いときは「セルを1つずつ触らない」
数千行・数万行をループで1セルずつ読み書きすると、目に見えて遅くなります。速くする定番は、セル範囲をまとめて配列に読み込み、配列の中でループしてから、最後に1回で書き戻す方法です。2万行で実測した速さの違いと書き方は、こちらにまとめています。

よくある質問
Q. 結局、どのループを覚えればいいですか?
まずは For Next と Do While(または Do Until)の2つです。この2つで、事務のマクロのほとんどは書けます。慣れてきたら、セル範囲やシートを「全部」処理するときに For Each を使ってみてください。
Q. Do While と Do Until は、どちらを使うのが正解ですか?
正解はありません。条件の向きが逆なだけで、同じ処理はどちらでも書けます(本記事の例では、同じ表に対して同じ行で止まりました)。チームで書くなら、どちらかに揃えておくと、後から読む人が迷いません。
Q. For Each で行を削除したら、うまく消えない行がありました。
行を削除すると、下の行が1つずつ繰り上がるため、上から順に処理するループでは1行飛ばしてしまいます。行の削除は、For Next の Step -1 で下から上へ回すのが定番です。書き方は For Next の記事で扱っています。
Q. Next の後ろの変数名は省略してもいいですか?
文法上は省略できます(Microsoft のリファレンスでも省略可能とされています)。ただ、入れ子にしたときにどのループの Next かが分かりにくくなるので、本記事のコードではすべて Next i のように書いています。
Q. ループの中で MsgBox を使ったら、何度もクリックする羽目になりました。
ループの中に MsgBox を置くと、回数分だけ表示されます。途中経過を見たいときは、本記事のように Debug.Print でイミディエイト ウィンドウに出すと、クリックせずに確認できます。
まとめ:「何回やるか分かっている?」で選ぶ
- 回数が決まっている → For Next
- セル範囲・シートを全部 → For Each
- どこで終わるか分からない → Do While(〜の間)/Do Until(〜になるまで)
- 最低1回は必ず実行したい → 後判定(Do … Loop While)
- 途中で抜ける → Exit For/Exit Do。While…Wend は読めれば十分
- 止まらなくなったら → Esc キー(または Ctrl+Break)。念のため上限を書いておく
ループが書けるようになると、「100行を手で直す」仕事が「F5 を1回押す」仕事に変わります。最初は、今日の表で例を1つずつ動かして、セルに値が入っていく様子を見てみてください。1つ動けば、次は自分の表に合わせて列や条件を書き換えるだけです。
次に読む


参考にした一次情報(2026年10月29日 確認)
For…Next ステートメント|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/fornext-statement
For Each…Next ステートメント|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/for-eachnext-statement
Do…Loop ステートメント|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/doloop-statement
While…Wend ステートメント|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/whilewend-statement
Exit ステートメント|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/exit-statement
Application.EnableCancelKey プロパティ (Excel)|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/api/excel.application.enablecancelkey


コメント