「配列やコレクションの中身を1つずつ取り出す」イメージを、文字だけで掴めるようにASCII図で解説します。For Eachは配列・コレクションの要素を順に取り出して処理する構文で、要素数を数えなくても自然にループできます。
基本イメージ(一次元配列)
配列の中身
Index: 0 1 2 3
Array: [10] [20] [30] [40]
For Each のポインタ移動
For Each elem In Array
^
Step1: elem = 10
For Each elem In Array
^
Step2: elem = 20
For Each elem In Array
^
Step3: elem = 30
For Each elem In Array
^
Step4: elem = 40
(最後の要素まで到達 → ループ終了)
コード例
Sub DemoOneDim()
Dim nums As Variant
nums = Array(10, 20, 30, 40)
Dim elem As Variant
For Each elem In nums
Debug.Print elem
Next elem
End Sub
VB- For Eachは「次の要素」へ自動で進むので、インデックスを自前で増やす必要がありません。
二次元配列(表形式)のイメージ
二次元配列(Rows × Cols)は、For Eachだと「内部メモリ順(多くのVBA実装で行方向に連続)」で1セルずつ走査します。ExcelのRange.Valueで取得した配列は、一般に [1..Rows, 1..Cols] のインデックスで行→列の順に並びます Qiita。
2×3の配列例(行→列の順で走査)
Row\Col 1 2 3
1 [A11] [A12] [A13]
2 [A21] [A22] [A23]
For Each の走査順(概念図)
順番: A11 → A12 → A13 → A21 → A22 → A23
コード例(Rangeから配列を取得)
Sub DemoTwoDim()
Dim data As Variant
data = Sheet1.Range("A1:C2").Value ' 2行×3列の二次元配列
Dim cellVal As Variant
For Each cellVal In data
Debug.Print cellVal
Next cellVal
End Sub
VB- For Eachは二次元でも「1要素ずつ」取り出します。行列インデックスが必要なら、For Nextの二重ループで扱う方が位置が明確です。
ヒント: 二次元は「場所(行・列)」を伴う処理が多いので、値だけでなく座標が欲しいときは For Next で i、j を使いましょう。
コレクション・Range・Worksheetsのイメージ
For Eachは「集まり(コレクション)」と相性がよく、要素数が変わっても安全です。
Worksheets の例(Workbook内の全シート)
ThisWorkbook.Worksheets:
[Sheet1] → [Sheet2] → [Sheet3] → ...
Sub LoopSheets()
Dim ws As Worksheet
For Each ws In ThisWorkbook.Worksheets
Debug.Print ws.Name
Next ws
End Sub
VBRange の例(選択範囲内のセル)
選択範囲 A1:B2
[A1] → [A2] → [B1] → [B2] (Excelの内部順序に従う)
Sub LoopCells()
Dim c As Range
For Each c In Sheet1.Range("A1:B2").Cells
Debug.Print c.Address & " = " & c.Value
Next c
End Sub
VB- コレクションは「数えなくていい・順番に取り出せる・途中で要素数が変わっても安全(削除等は注意)」がメリットです vba-work-motegi-office.com saiseich.com。
For Each と For Next の向き不向き
- For Each
- メリット: インデックス管理不要、可読性高い、コレクション・Range・配列の全要素処理に向く。
- 弱点: 位置情報(何行目・何列目)を直接使う処理には不向き。
- For Next
- メリット: インデックスで場所を制御できる、部分範囲・ステップ幅の制御に強い。
- 弱点: 要素数の取得や境界管理が必要でコードが長くなりがち。
つまずきやすいポイントと対策
- 二次元配列で「どの順に処理されるか」分かりづらい
- 対策: 値だけでよければ For Each、座標が必要なら For Next の二重ループ。
- 配列要素を変更したい
- For Each の変数に代入しても元配列は変わらないことが多い。インデックス指定の For Next で Array(i) = … と更新する。
- Variant配列にしておく
- Range.Valueの返りは二次元Variant配列。受け皿は Variant にしておくと安心。


