PR
アフィリエイト広告を利用しています
アフィリエイト広告を利用しています

【コピペOK】VBAのFor Nextの使い方|基本形・Step -1・入れ子・Exit Forと「1回も回らない」の直し方

VBAのFor Nextの使い方。基本形・Step・入れ子・Exit Forと「1回も回らない」の原因 EXCEL VBA講座
スポンサーリンク

【この記事について】この記事のコードは、Windows 11 の Excel(Microsoft 365・バージョン 16.0.20430.20092/64ビット・Current Channel)で2026年10月3日に実際に実行し、表示される結果とエラー番号を確かめたものです。処理時間はパソコンの性能や Excel の設定で変わるため、目安として読んでください。

VBAの For~Next は、「数を1つずつ増やしながら、同じ処理を繰り返す」仕組みです。For i = 1 To 5 と書けば、i が 1・2・3・4・5 と変わりながら、間にはさんだ処理が5回動きます。覚えることは「開始の数」「終わりの数」「増やす幅(Step)」の3つだけ。つまずくのもこの3つで、よくあるのは「For i = 5 To 1 と書いて1回も動かない」「Dim i As Integer のまま3万行を回してエラーで止まる」の2つです。この記事では、基本形から入れ子・Exit For・速くする書き方まで、実際に動かして確かめたコードで順に説明します。

For Nextは開始の数・終わりの数・Stepの3つで決まる。For i = 1 To 10 Step 2 では iが1・3・5・7・9と進み、11が10を超えるのでループから出る
スポンサーリンク

For Next は「3つの数字」で決まる

まず全体の形です。For と Next で処理をはさみます。

For カウンター = 開始の数 To 終わりの数 Step 増やす幅
    繰り返したい処理
Next カウンター

「カウンター」は、いま何回目かを覚えておく変数です。i という名前がよく使われます(index の頭文字です)。

場所 意味 書かないとどうなるか
開始の数 カウンターに最初に入る値 省略できません
終わりの数 この値を超えたらループから出る 省略できません
Step 増やす幅 1回まわるごとに足す数 省略すると 1 になります

大事なのは「終わりの数を超えたら出る」という点です。For i = 1 To 10 Step 2 なら、i は 1・3・5・7・9 と進み、次の 11 が 10 を超えるのでそこで終わります。10 ちょうどで止まるわけではありません。


スポンサーリンク

基本形:セルを1行ずつ処理する

いちばんよく使うのが、セルを上から順に処理する形です。次のコードは、A1からA5に 100・200・300・400・500 を入れます。

Sub Sample1_ForNextKihon()
    Dim i As Long

    For i = 1 To 5
        Cells(i, 1).Value = i * 100
    Next i
End Sub

Cells(i, 1) は「i 行目・1列目のセル」という意味です。i が 1 から 5 まで変わるので、A1からA5までが順に埋まります。実行すると、A1からA5が 100・200・300・400・500 になり、A6は空のままでした。

貼り付け方が分からないときは、先にエクセルのマクロが実行できない原因7つと直し方で、[開発]タブの出し方と .xlsm での保存を済ませておいてください。


スポンサーリンク

Step で「1つ飛ばし」「逆から」にする

Step 2 で1行おきに処理する

Step に 2 を指定すると、2つずつ進みます。

Sub Sample2_Step2()
    Dim i As Long

    For i = 1 To 9 Step 2
        Cells(i, 2).Value = "対象"
    Next i
End Sub

実行すると、B列の1・3・5・7・9行目だけに「対象」が入りました。2・4・6・8行目は空のままです。

行を削除するときは Step -1 が必須

Step にマイナスを書くと、カウンターが減っていきます。これがどうしても必要になるのが「行の削除」です。

A1からA10に、2・3・4・7・8行目が「削除」、ほかが「残す1」「残す5」…と入った表で試しました。まず、つい書いてしまう「上から」の形です。

Sub Sample3_NG_UeKara()
    Dim i As Long

    For i = 1 To 10
        If Cells(i, 1).Value = "削除" Then Rows(i).Delete
    Next i
End Sub

実行後のA列はこうなりました。

残す1 / 削除 / 残す5 / 残す6 / 削除 / 残す9 / 残す10

5つあった「削除」のうち、2つが消えずに残っています。行を1つ消すと、下の行がすべて1つ上にずれるためです。2行目を消した瞬間、元の3行目が2行目に上がってきます。ところがカウンターは次の 3 へ進むので、上がってきた行を飛び越してしまいます。

下から処理すれば、この問題は起きません。消した行より下はもう処理済みだからです。

Sub Sample3_OK_ShitaKara()
    Dim i As Long

    For i = 10 To 1 Step -1
        If Cells(i, 1).Value = "削除" Then Rows(i).Delete
    Next i
End Sub

実行後は「残す1 / 残す5 / 残す6 / 残す9 / 残す10」となり、「削除」は1つも残りませんでした。行や列を消すループは、必ず下からと覚えてください。


スポンサーリンク

データがある行だけ回す

実務では「10行」と決め打ちできません。データが何行あるかを先に調べて、そこまで回します。

Sub Sample4_SaishuGyouMade()
    Dim lastRow As Long
    Dim i As Long

    lastRow = Cells(Rows.Count, 1).End(xlUp).Row
    Debug.Print "最終行: " & lastRow

    For i = 2 To lastRow
        Cells(i, 3).Value = Cells(i, 1).Value * Cells(i, 2).Value
    Next i
End Sub

A列に単価、B列に数量が入った表(1行目は見出し、2〜4行目にデータ)で実行すると、イミディエイトウィンドウ(Ctrl+G で開きます)に 最終行: 4 と出て、C2からC4に 200・1000・240 が入りました。

見出し行を飛ばすために、開始を 1 ではなく 2 にしているのがポイントです。End(xlUp) の書き方と、うまく取れないときの対処はVBAで最終行を取得する方法5つと使い分けにまとめてあります。

For Each…Next との使い分け

もう1つの繰り返しが For Each です。こちらは「番号で数える」のではなく「集まりの中身を1つずつ取り出す」書き方です。

Sub Sample5_ForEach()
    Dim c As Range

    For Each c In Range("A1:A5")
        If c.Value = "" Then c.Value = 0
    Next c
End Sub

A1・A3・A5に 10・30・50 が入り、A2・A4が空の状態で実行したところ、10・0・30・0・50 になりました。空のセルだけに 0 が入ります。

For…Next For Each…Next
向いている場面 何回目かの番号を使いたい 範囲やシートを順に見るだけ
逆順にできるか できる(Step -1) できない
行の削除 下から回せば安全 向かない
速さ ほぼ同じ ほぼ同じ

迷ったら、「何行目か」を使うなら For...Next、使わないなら For Each で決めて問題ありません。

入れ子(二重ループ)で表をつくる

For の中に For を書くと、縦と横の両方を回せます。次は九九の表を作るコードです。

Sub Sample6_NijuLoop()
    Dim r As Long
    Dim c As Long

    For r = 1 To 9
        For c = 1 To 9
            Cells(r, c).Value = r * c
        Next c
    Next r
End Sub

実行すると、1行目が 1〜9、9行目が 9・18・27…81 という9行9列の表ができました。外側が1回まわる間に、内側は9回まわります。合計81回です。

入れ子で気をつけるのは、Next の順番です。内側で開いたループを先に閉じます。Next r と Next c を入れ替えると、実行する前にコンパイルエラーで止まります。この種のエラーはVBAのコンパイルエラー7パターンと直し方で扱っています。

ついでの注意:「1-1」のような文字列は日付に変わる

この記事を書くために、最初は Cells(r, c).Value = r & "-" & c として「1-1」「1-2」…と入れるコードを試しました。ところが実行すると、セルには「1月1日」という日付が入ってしまいました。確かめたのが次のコードです。

Sub Sample6b_HizukeKeshiki()
    Cells(1, 1).Value = "1-1"
    Debug.Print "書式なし: " & TypeName(Cells(1, 1).Value) & " / 見え方は " & Cells(1, 1).Text

    Cells(2, 1).NumberFormat = "@"
    Cells(2, 1).Value = "1-1"
    Debug.Print "文字列書式: " & TypeName(Cells(2, 1).Value) & " / 見え方は " & Cells(2, 1).Text
End Sub

結果はこうなりました。

書式なし: Date / 見え方は 1月1日
文字列書式: String / 見え方は 1-1

ループのせいに見えて、原因は Excel 側の自動変換です。文字列として入れたいときは、先に NumberFormat = "@"(文字列書式)にしてから入れてください。

途中でやめる・飛ばす

Exit For でループを抜ける

探し物が見つかったら、それ以上回す必要はありません。Exit For でその場を抜けます。

Sub Sample7_ExitFor()
    Dim i As Long
    Dim hitRow As Long
    Dim kaisu As Long

    hitRow = 0
    For i = 1 To 1000
        kaisu = kaisu + 1
        If Cells(i, 1).Value = "大阪" Then
            hitRow = i
            Exit For
        End If
    Next i

    Debug.Print "見つかった行: " & hitRow & " / 回った回数: " & kaisu
End Sub

A3に「大阪」を入れて実行すると 見つかった行: 3 / 回った回数: 3 と出ました。Exit For が無ければ、見つかったあとも1000回目まで回り続けます。

Exit For は「内側のループ」しか抜けない

入れ子のときに間違えやすい点です。内側の For の中で Exit For を書いても、抜けるのは内側だけで、外側は次の回へ進みます。

Sub Sample7b_ExitFor_Uchigawa()
    Dim r As Long
    Dim c As Long
    Dim kaisu As Long

    For r = 1 To 3
        For c = 1 To 3
            kaisu = kaisu + 1
            If c = 2 Then Exit For
        Next c
    Next r

    Debug.Print "回った回数: " & kaisu
End Sub

結果は 回った回数: 6 でした。内側は毎回2回で抜け、それが外側の3回ぶん起きるので 2×3=6回です。外側まで抜けたいときは、Exit For を2回書くか、判定用の変数を1つ用意します。

「この回だけ飛ばす」はどう書くか

VBAには、他の言語の continue にあたる命令がありません。If で「処理するほう」を囲むのがいちばん読みやすい形です。

Sub Sample8_KuhakuWaTobasu()
    Dim i As Long
    Dim goukei As Double
    Dim kensu As Long

    For i = 1 To 10
        If Cells(i, 1).Value = "" Then
            ' 何もしない = そのまま次の回へ進む
        Else
            goukei = goukei + Cells(i, 1).Value
            kensu = kensu + 1
        End If
    Next i

    Debug.Print "合計: " & goukei & " / 足した件数: " & kensu
End Sub

A1・A3・A4・A8に 100・200・300・400 を入れ、ほかを空にして実行すると 合計: 1000 / 足した件数: 4 となりました。空のセルは足されていません。

「1回も回らない」「途中で止まる」の原因3つ

原因1:開始の数が終わりの数より大きい

いちばん多いのがこれです。For i = 5 To 1 と書くと、エラーも出さずに、処理が1回も実行されません。「マクロを実行しても何も起きない」の正体です。

Sub Sample9_Mawaranai()
    Dim i As Long
    Dim kaisu As Long

    For i = 5 To 1
        kaisu = kaisu + 1
    Next i
    Debug.Print "Step なし: " & kaisu & " 回"

    kaisu = 0
    For i = 5 To 1 Step -1
        kaisu = kaisu + 1
    Next i
    Debug.Print "Step -1 あり: " & kaisu & " 回"
End Sub

実行結果です。

Step なし: 0 回
Step -1 あり: 5 回

減らしながら回したいなら、Step -1 を必ず書く。これだけです。最終行が 1 のとき(データが0件のとき)に For i = 2 To lastRow が 2 To 1 になって動かない、というのも同じ形です。

原因2:カウンターを Integer で宣言している

Integer 型が扱えるのは −32,768 〜 32,767 までです。3万行を超える表を回すと、その手前であふれて止まります。

Sub Sample10_IntegerOverflow()
    Dim i As Integer

    For i = 1 To 40000
        ' 何もしない
    Next i
End Sub

同じループを Dim i As Integer と Dim i As Long で動かして比べたところ、Integer では「実行時エラー 6 オーバーフローしました」(エラー番号 6)が発生し、Long ではエラーは起きませんでした。

Excelの行数は最大1,048,576行あります。カウンターは必ず Long で宣言してください。迷う場面がなくなります。

原因3:Next の変数名が違う

For i で始めたのに Next j と書くと、実行する前にコンパイルエラーで止まります。Next の後ろの変数名は省略もできますが、入れ子のときは書いておいたほうが間違いに気づけます。

遅いループを速くする

行数が増えると、ループは目に見えて遅くなります。A1からA20000に連番を入れる処理を、3つの書き方で計りました。

Sub Sample11b_GamenKousinOff()
    Dim i As Long
    Dim t As Double

    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual

    t = Timer
    For i = 1 To 20000
        Cells(i, 1).Value = i
    Next i
    Debug.Print "画面更新と計算をオフ: " & Format(Timer - t, "0.00") & " 秒"

    Application.Calculation = xlCalculationAutomatic
    Application.ScreenUpdating = True
End Sub
書き方 2万行の処理時間
セルに1つずつ入れる(そのまま) 約0.93秒
画面更新と自動計算をオフにする 約0.70秒
配列にためて1回で書き戻す 約0.03秒

画面更新と自動計算を止めるだけでも、約0.93秒から約0.70秒へ2割ほど縮みました。ただし効き方は大きくありません。はっきり差が出たのは配列のほうで、同じ2万行が約0.03秒、そのまま書く場合の30分の1ほどで終わりました。計測は各1回なので、0.05秒くらいのばらつきは見込んでください。

ScreenUpdating を False にしたら、必ず最後に True へ戻してください。戻し忘れると、マクロが終わったあとも画面が更新されないままになります。配列の使い方はVBAの配列の使い方で詳しく説明しています。

よくある質問

Q. カウンターの名前は i でなくてもいいですか?

はい。変数名のルールに合っていれば何でも構いません。Dim gyou As Long として For gyou = 2 To lastRow と書けば、後から読んだときに意味が分かりやすくなります。入れ子のときは r(行)・c(列)のように役割で分けるのがおすすめです。

Q. ループの中でカウンターの値を書き換えてもいいですか?

文法としては書けますが、おすすめしません。Next のたびに Step ぶんが足されるため、どこまで進んだか追えなくなります。進み方を変えたいなら Step で指定し、途中でやめたいなら Exit For を使ってください。

Q. 回数が決まっていないときはどう書きますか?

「条件が成り立つ間ずっと」という繰り返しには Do While...Loop を使います。For...Next は回数が先に決まっているときの書き方です。ただし表の処理なら、先に最終行を求めて For で回すほうが、止まらなくなる事故を避けやすくなります。

Q. ループの途中経過を見るにはどうすればいいですか?

Debug.Print をループの中に1行入れて、イミディエイトウィンドウ(Ctrl+G)で確認します。この記事の結果もすべてこの方法で取りました。確認が終わったら消すか、行頭に ' を付けて無効にしておきます。

Q. 「型が一致しません」と出てループが止まります

セルの中身が、計算できない形(文字列や空白)になっている可能性が高いです。実行時エラー13の原因と直し方はこちらの記事にまとめてあります。

まとめ:For Next は3つの数字と Long だけ押さえる

  • 開始・終わり・Step の3つで決まる。Step を書かないと 1
  • 終わりの数を「超えたら」出る。1 To 10 Step 2 は 1・3・5・7・9 の5回
  • 行や列を消すループは必ず Step -1 で下から。上から回すと、実際に5件中2件が消し残った
  • カウンターは Long。Integer で4万回まわすとエラー6で止まった
  • 「何も起きない」の正体は For i = 5 To 1。0回で静かに終わる
  • Exit For が抜けるのは内側のループだけ(実測で 2×3=6回)

ループは、最初は「1回ずれる」「1回も動かない」で必ずつまずきます。でも原因はこの記事の数パターンにほぼ収まります。まずは「基本形」のコードを貼り付けて、A1からA5が埋まるところを見てください。そこから 5 を 10 に変えてみるだけでも、手作業が消えていく感覚がつかめるはずです。あなたが毎日くり返している作業こそ、ループがいちばん得意な仕事です。

次に読む

【動く前に止まる】VBAのコンパイルエラー7パターンと直し方|変数が定義されていません・構文エラー・End If がありません
VBAのコンパイルエラーは、マクロが動き出す前に出るエラーです。番号が出ず該当箇所が青く反転するのが目印で、原因はデータではなくコードの書き方。変数名のスペルミス・全角文字・End Ifの閉じ忘れ・参照設定など7パターンを、Microsoft公式ドキュメントの記載にもとづいて順に潰します(2026年9月12日確認)。
【コピペOK】VBAの配列の使い方|Dim・ReDim Preserve・UBoundからセル範囲の一括読み込みまで(2万行が20倍以上速くなった実測つき)
VBAの配列を、Dimでの作り方・Array関数・ReDim Preserve・UBoundから、セル範囲を配列へ一度に読み込んで書き戻す方法まで、実際にExcelで動かしたコードで解説。2万行で20倍以上速くなった実測と、エラー9・13の原因と直し方もまとめました。
【もう迷わない】VBAで最終行を取得する方法5つと使い分け|End(xlUp)が1を返す・途中の空白・UsedRangeのズレ
VBAで最終行を取るなら、まずは ws.Cells(ws.Rows.Count, 1).End(xlUp).Row の1行です。データ0件でも1が返る・シート指定の漏れ・基準列の空白・Integerのオーバーフローという4つのつまずきと、Find・UsedRange・CurrentRegionとの使い分けを、Microsoft公式ドキュメントをもとにまとめました。

出典(2026年10月3日 確認)

For…Next ステートメント (VBA)|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/fornext-statement

For Each…Next ステートメント (VBA)|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/for-eachnext-statement

Exit ステートメント (VBA)|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/exit-statement

データ型の概要|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/data-type-summary

オーバーフローしました (エラー 6)|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/language/reference/user-interface-help/overflow-error-6

Application.ScreenUpdating プロパティ (Excel)|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/api/excel.application.screenupdating

Application.Calculation プロパティ (Excel)|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/api/excel.application.calculation

Range.Delete メソッド (Excel)|Microsoft Learn
https://learn.microsoft.com/ja-jp/office/vba/api/excel.range.delete


当ブログは、Excel や VBA で手が止まった事務職のみなさんに、その場で直せる手順を届けたい思いで運営しています。
「記事が役に立った」「続きも読んでみたい」と感じていただけたら、下記リンクからのご利用・ご支援で応援してもらえると嬉しいです。

EXCEL VBA講座
スポンサーリンク
シェアする
メリ爺をフォローする

コメント

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