ITサポーターTsuchida

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の方を使ってしまうことがしばしばあり、後から後悔したこともあります。