Excel VBAでマクロを作成していると、
For-Next ループが思った通りに動かない という問題に必ず直面します。
- 途中でループが止まる
- 1回も回らない
- 回数が合わない
- 無限ループになる
- エラーは出ないのに結果がおかしい
For-NextはVBAの中でも最も基本的な構文ですが、
実務では 「一番トラブルを生みやすい構文」 でもあります。
特に、
- 条件分岐(If)
- 配列
- 行・列の最終行取得
- データ削除
- RPA(UiPath)連携
などと組み合わさると、
一見正しそうなのに動かないコード が簡単に出来上がってしまいます。
この記事では、
Excel VBAの For-Nextループが上手く動作しない原因 を体系的に整理し、
- なぜその問題が起きるのか
- どう直せばよいのか
- どう設計すれば再発しないのか
を、実務視点・コード例付きで徹底解説します。
目次
- ✅ For-Nextループが「上手く動かない」とはどういう状態か
- ・よくある不具合パターン
- ✅ For-Nextループの基本仕様を再確認する
- ・For-Nextの基本構文
- ・For文は「開始時点で回数が確定」する
- ✅ 原因①:For文の開始条件が成立していない
- ・開始値 > 終了値になっている
- ・対処法:Step を指定する
- ✅ 原因②:最終行・最終列の取得ミス
- ・lastRow が 0 や 1 になっている
- ・対処法:ループ前に値を確認する
- ✅ 原因③:ループ中に行・列を削除している
- ・上から下へ削除している例
- ・対処法①:下から上へループする
- ✅ 原因④:Exit For / Exit Sub の使い方ミス
- ・Exit For による意図しない終了
- ・対処法:Continue的な構造を作る
- ✅ 原因⑤:変数の型が不適切
- ・Integerを使っている
- ・対処法:Longを使う
- ✅ 原因⑥:配列とForループの理解不足
- ・配列の範囲を誤っている
- ・対処法:LBound と UBound を使う
- ✅ 原因⑦:For Each と For を混同している
- ・For Each の方が安全なケース
- ✅ 原因⑧:DoEvents / Wait / Sleep との組み合わせ
- ・ループが止まったように見える
- ・対処法:待機の意味を明確にする
- ✅ デバッグ時の効果的な確認方法
- ・ループ変数を出力する
- ・条件を1つずつ外す
- ✅ 実務で再発させないための設計ポイント
- ・Forの責務を小さくする
- ・ループ前に前提条件をチェックする
- ✅ RPA(UiPath)連携時の注意点
- ✅ よくある勘違い
- ・「For文が壊れている」
- ・「Excelの不具合」
- ✅ まとめ:For-Nextループが上手く動かない本質的な原因
✅ For-Nextループが「上手く動かない」とはどういう状態か
※最初に「問題の種類」を整理します。
・よくある不具合パターン
For-Nextが上手く動かないと言われるケースは、主に次の5つです。
- ループが 1回も実行されない
- ループ回数が 想定より少ない/多い
- 途中で 止まる/抜ける
- 無限ループになる
- エラーは出ないが 結果がズレる
これらはすべて、
For-Nextの仕様を正しく理解していないこと が原因です。
✅ For-Nextループの基本仕様を再確認する
※原因分析の前に、土台を固めます。
・For-Nextの基本構文
Dim i As Long
For i = 1 To 5
Debug.Print i
Next i
このループは、
- i = 1 から開始
- i = 5 まで
- 1ずつ増加
という条件で動作します。
・For文は「開始時点で回数が確定」する
重要なポイントは、
Forループは開始時に回数が確定する という点です。
For i = 1 To lastRow
' 処理
Next i
この lastRow は、
ループ開始時の値で固定 されます。
ループ途中で lastRow が変わっても、
ループ回数は変わりません。
✅ 原因①:For文の開始条件が成立していない
※「1回も回らない」原因の代表例です。
・開始値 > 終了値になっている
For i = 10 To 1
Debug.Print i
Next i
このコードは、
1回も実行されません。
なぜなら、
- 開始値:10
- 終了値:1
であり、
増加方向(+1)では条件を満たさないからです。
・対処法:Step を指定する
For i = 10 To 1 Step -1
Debug.Print i
Next i
減らしたいときは必ず Step -1
これを忘れると、ループは動きません。
✅ 原因②:最終行・最終列の取得ミス
※実務で最も多い原因です。
・lastRow が 0 や 1 になっている
lastRow = Cells(Rows.Count, 1).End(xlUp).Row
For i = 2 To lastRow
' 処理
Next i
一見正しく見えますが、
- データが1行もない
- ヘッダーしかない
場合、
lastRow = 1 となり、
ループが1回も回りません。
・対処法:ループ前に値を確認する
If lastRow < 2 Then Exit Sub
Forが動かないのではなく、条件が成立していない
この視点が重要です。
✅ 原因③:ループ中に行・列を削除している
※結果がズレる・一部処理されない原因です。
・上から下へ削除している例
For i = 2 To lastRow
If Cells(i, 1).Value = "" Then
Rows(i).Delete
End If
Next i
このコードは、
- 行を削除すると
- 下の行が繰り上がる
ため、
次の行をスキップしてしまう という問題が起きます。
・対処法①:下から上へループする
For i = lastRow To 2 Step -1
If Cells(i, 1).Value = "" Then
Rows(i).Delete
End If
Next i
削除を伴う処理は必ず逆順
これは鉄則です。
✅ 原因④:Exit For / Exit Sub の使い方ミス
※「途中で止まる」原因です。
・Exit For による意図しない終了
For i = 1 To 10
If Cells(i, 1).Value = "" Then Exit For
Next i
この場合、
- 空白セルが見つかった時点で
- ループは完全終了
します。
処理をスキップしたいだけ なのに、
ループ全体が止まる というミスは非常に多いです。
・対処法:Continue的な構造を作る
VBAには Continue For がないため、
Ifで処理を分岐します。
For i = 1 To 10
If Cells(i, 1).Value <> "" Then
' 処理
End If
Next i
✅ 原因⑤:変数の型が不適切
※回数がおかしくなる原因です。
・Integerを使っている
Dim i As Integer
For i = 1 To 50000
' 処理
Next i
Integerの上限は 32,767 のため、
値がオーバーフローし、
ループが正しく動作しません。
・対処法:Longを使う
Dim i As Long
ループ変数は原則 Long
これは実務の基本ルールです。
✅ 原因⑥:配列とForループの理解不足
※処理されない・エラーにならない原因です。
・配列の範囲を誤っている
For i = 1 To UBound(arr)
Debug.Print arr(i)
Next i
配列が
arr(0 To 9)
の場合、
arr(0) が処理されません。
・対処法:LBound と UBound を使う
For i = LBound(arr) To UBound(arr)
Debug.Print arr(i)
Next i
配列は必ず LBound / UBound
これで範囲ミスを防げます。
参考:【VBA】文字列を一括置換する方法|大量データを安全に処理する実務手順
✅ 原因⑦:For Each と For を混同している
※オブジェクト操作で多いミスです。
・For Each の方が安全なケース
Dim c As Range
For Each c In Range("A1:A10")
Debug.Print c.Value
Next c
RangeやWorksheetなど、
コレクションを扱う場合は For Each が安全 です。
無理に For i を使うと、
存在しない要素を参照して問題になります。
参考:【VBA】条件に一致するセルを複数取得する方法|Find・For Each・SpecialCells
✅ 原因⑧:DoEvents / Wait / Sleep との組み合わせ
※RPA連携でよく起きます。
・ループが止まったように見える
For i = 1 To 1000
Sleep 1000
Next i
この場合、
- 1回ごとに1秒停止
- 合計約1000秒
となり、
「止まった」と誤解される 状態になります。
・対処法:待機の意味を明確にする
- 本当に必要な箇所だけ待つ
- ループ全体で待たせない
参考:【VBA】処理が終わってから次の処理を実行する方法|DoEvents・待機・同期制御の基本と実例
✅ デバッグ時の効果的な確認方法
※原因特定を早めます。
・ループ変数を出力する
Debug.Print i
これだけで、
- 何回回っているか
- どこで止まったか
が一目で分かります。
・条件を1つずつ外す
- Ifを一時的に外す
- Exit文を外す
動く状態を作ってから条件を戻す
これが最短ルートです。
参考:【Excel】「セルに特定の文字が入っていたら」複数条件を判定する方法|IF・OR・SEARCH関数
✅ 実務で再発させないための設計ポイント
※ここが一番重要です。
・Forの責務を小さくする
- 1つのForでやる処理は最小限
- 複雑ならSubに分ける
・ループ前に前提条件をチェックする
If lastRow < 2 Then Exit Sub
Forが悪いのではなく、前提が崩れている
この視点が重要です。
✅ RPA(UiPath)連携時の注意点
※Forループの不具合が顕在化しやすいです。
- データ量が日によって違う
- 空白・欠損が混ざる
- 処理時間が延びる
そのため、
- ループ条件を厳密に
- Exit条件を明確に
- ログを残す
設計が求められます。
✅ よくある勘違い
※遠回りの原因です。
・「For文が壊れている」
→ 多くの場合、条件や前提が壊れています。
・「Excelの不具合」
→ ほぼ100%コード設計の問題です。
✅ まとめ:For-Nextループが上手く動かない本質的な原因
- Forは開始時点で条件が確定する
- 開始値・終了値・Step を必ず確認
- 削除処理は逆順が鉄則
- Long型を使う
- 配列は LBound / UBound
- 前提条件チェックが最重要
For-Nextループは、
「書ける」より「壊れない」ことが重要 です。
正しく理解し、
条件・構造・責務を意識したForループ設計 を行うことで、
VBAは一気に安定します。
ぜひ、
「とりあえず回すFor」から卒業し、
意図が明確なFor-Nextループ を書けるようになってください。