For Each は「集まりの中身を一つずつ取り出して処理する」ための文
For文は「番号で回すループ」でした。i = 1 から 10 まで のように、「番号(インデックス)」を自分で管理します。
一方 For Each は、
「集まり(コレクション)の中身を、一つずつ順番に取り出して処理する」
ためのループです。
人間の言葉にすると、
「この箱に入っているものを、上から順に一個ずつ手に取って処理してね」
というイメージです。
「何番目か」は意識せず、「中身そのもの」を順番に触っていきます。
For と For Each の違いをざっくり掴む
For は「番号で回す」
Dim i As Long
For i = 1 To 10
' i 行目を処理
Next i
VBこれは、「1行目」「2行目」…と、番号を使って回るループです。
「何番目か」を自分で意識している感じです。
For Each は「要素そのものを回す」
Dim c As Range
For Each c In Range("A1:A10")
' c というセルを処理
Next c
VBこれは、「A1~A10 という“集まり”の中のセルを、一つずつ取り出して処理する」ループです。
「今は何番目か」は意識せず、「今触っているセルそのもの(c)」だけを扱います。
For → インデックス(番号)で回る
For Each → 要素そのものを回る
この対比を頭に置いておくと、使い分けが見えやすくなります。
For Each の基本構文と動き方
基本構文
形はこうです。
For Each 要素変数 In 集まり(コレクション)
' 要素変数に対する処理
Next 要素変数
VBExcel VBAで一番よく見るのは、Range に対する For Each です。
Sub SampleForEachBasic()
Dim c As Range
For Each c In Range("A1:A5")
c.Value = "OK"
Next c
End Sub
VBこのコードは、
A1, A2, A3, A4, A5 の各セルに対して、順番に c.Value = "OK" を実行します。
動きを言葉で追うと、
- 集まり:Range(“A1:A5”)
- その中から、最初のセル(A1)が c に入る
- c.Value = “OK” → A1 に “OK”
- 次のセル(A2)が c に入る
- 同じ処理 → A2 に “OK”
- A5 まで終わったらループ終了
という流れです。
For Each が「めちゃくちゃ気持ちいい」典型パターン
範囲内のセルを全部なめたいとき
Sub SampleColorRed()
Dim c As Range
For Each c In Range("A1:A10")
c.Interior.Color = vbYellow
Next c
End Sub
VBこのコードは、A1~A10 のセルを一つずつ取り出して、
そのセルの背景色を黄色にします。
ここでのポイントは、
Range(“A1:A10”) という“集まり”の中の
「一つ一つのセル」を c として扱っている
ということです。
For で書くとこうなります。
Dim i As Long
For i = 1 To 10
Range("A" & i).Interior.Color = vbYellow
Next i
VBどちらも正解ですが、
「セルの集まりをそのまま回したい」だけなら、For Each のほうが自然で読みやすいです。
条件付きで処理する
Sub SampleForEachCondition()
Dim c As Range
For Each c In Range("A1:A10")
If c.Value = "完了" Then
c.Interior.Color = vbGreen
End If
Next c
End Sub
VBこのコードは、
A1~A10 の中で、値が「完了」のセルだけ背景色を緑にします。
「範囲を For Each で回す」+「If で条件判定」
この組み合わせは、実務で本当に頻繁に出てきます。
For Each が特に向いている「コレクション」という考え方
コレクション=“何かの集まり”
For Each が使えるのは、「コレクション」と呼ばれる“集まり”です。
Excel VBA だと、例えばこんなものがあります。
Worksheets(ワークシートの集まり)
Workbooks(ブックの集まり)
Range(“A1:A10”)(セルの集まり)
これらは、「何番目か」を意識しなくても、
「一つずつ順番に取り出す」という操作ができます。
シートを全部回る例
Sub SampleForEachSheets()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
Debug.Print ws.Name
Next ws
End Sub
VBこのコードは、ブック内のすべてのシートを一つずつ取り出して、
イミディエイトウィンドウにシート名を表示します。
ここでも、
集まり:ThisWorkbook.Worksheets
要素:Worksheet(ws)
という構造になっています。
「ブック内の全シートに同じ処理をしたい」
というとき、For Each はとても自然に書けます。
For と For Each の使い分けをもう一歩深く
For が向いている場面
番号を意識したいとき
「何行目か」「何番目か」を使って別のことをしたいとき
Step で飛ばしたり、逆順に回したりしたいとき
例:
For i = 1 To 10 Step 2
Range("A" & i).Value = i
Next i
VB「奇数行だけ」「下から上へ」など、
“番号のコントロール”が必要なときは For が向いています。
For Each が向いている場面
「集まりの中身を、全部、一つずつ触りたい」
「何番目かはどうでもよくて、とにかく全部回りたい」
例:
For Each c In Range("A1:A10")
If c.Value = "完了" Then
c.Interior.Color = vbGreen
End If
Next c
VB「セルの集まり」「シートの集まり」「ブックの集まり」など、
“コレクション”をそのまま回したいときは For Each が気持ちよくハマります。
For Each でつまずきやすいポイント
要素変数の型をちゃんと合わせる
Dim c As Range
For Each c In Range("A1:A10")
' c は Range 型として扱える
Next c
VBRange の集まりを回すなら、要素変数は Range 型にします。
Worksheet の集まりなら Worksheet 型、Workbook の集まりなら Workbook 型です。
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
' ws は Worksheet 型
Next ws
VBVariant でも動きますが、
型をきちんと合わせておくと、
「この変数には何が入るのか」が自分にもコンパイラにも伝わるので、
エラーに気づきやすくなります。
For Each は「インデックス指定」ができない
For なら、
Range("A" & i)
VBのように、「何番目か」を使って別の場所を触れますが、
For Each の要素変数は「今の要素そのもの」なので、
「今何番目か」を直接知ることはできません。
もし「何番目か」を使いたいなら、
別途カウンタ変数を用意する必要があります。
Dim c As Range
Dim i As Long
i = 0
For Each c In Range("A1:A10")
i = i + 1
Debug.Print "今 " & i & " 個目: " & c.Address
Next c
VBまとめ:For Each は「コレクションを素直に回すためのループ」
For Each の本質は、
「集まり(コレクション)の中身を、一つずつ取り出して処理する」
というシンプルなものです。
押さえておきたいポイントをコンパクトにまとめると、
For は「番号で回る」、For Each は「要素そのもので回る」
Range(“A1:A10”) や Worksheets など、“集まり”に対して使う
「全部のセル」「全部のシート」に同じ処理をしたいときに特に強い
インデックス操作や Step が必要なら For、そうでなければ For Each が読みやすい
