VBA Stepup11
第11章 ループ処理(For Eachステートメント)
For Eachステートメントは、For Nextステートメント同様に、ループ処理に使用します。 For Nextステートメントが初期値と終了値を指定するのに対して、For Eachステートメントは配列やコレクションを指定します。配列やコレクションのすべてに対して行うので、一律の処理をしたい場合に向いています。
ところでコレクションとは何かというと、オブジェクトの集まりのことで、選択範囲やブック内のワークシートや図形などがあります。
For Eachステートメント は、配列やコレクションの中から、個別の要素を順番に取り出して処理を繰返し、全ての要素に対し処理を行うと、ループは終了します。
配列での使用
CSVデータを配列に分割して、For Eachステートメントで2行目のセルに取り出す処理は以下の通りとなります。
Dim dArray() As String
(Dim dArray As Variant ←バリアント型にするとSplit関数で配列に変わる)
Dim dItem As Variant ←ループ中に、現在の配列の要素を入れる
Dim i As Long
dArray = Split(CSVデータ)
i = 0
For Each dItem In dArray()
(バリアント型ならdArrayで括弧は不要)
i = i + 1
Cells(2, i).Value = dItem
Next
配列に関してはわざわざ配列内の要素を変数に移しているので、For Nextステートメントの方がわかりやすいかもしれません。 ただし、配列内の要素数を気にしたりしないで済むので、配列内を単純に処理する場合はFor Eachステートメントは便利です。
コレクションでの使用
ブック内のワークシートのシート名が営業部員名で、1行目を挿入して、各シートのA1セルにシート名+「売上一覧表」という文字を代入する処理は、以下の通りとなります。
Dim ws As Worksheet
For Each ws In Worksheets
ws.Rows(1).Insert
ws.Cells(1, 1).Value = ws.Name & "売上一覧表"
Next
コレクションには、ワークシートの他に選択範囲や図形などがあります。 For Eachステートメントはすべてのコレクションを対象とするので、開いているすべてのブックに同じ処理をしたり、ブック内のワークシートなどに同様の処理や設定にするときに使います。
また、コレクション内を無条件にすべて処理するため、名前が変更されても影響を受けません。この例では、シート名が変更されたとしても、エラーになることはなく、VBAのコードの修正は発生しません。
ただ、複雑なループになるとFor Eachステートメントでは使いにくくなるので、その場合はFor NextステートメントかDo Loopステートメントを使います。私が現役プログラマのころは存在していないものなので、For Eachステートメントが使えるのに、For Nextの方を使ってしまうことがしばしばあり、後から後悔したこともあります。