ES000004_VBAエキスパート(ExcelVBAスタンダード)合格講座/第四回:For Each … Nextステートメント

VBAエキスパート(ExcelVBAスタンダード)合格講座/第四回:For-Each-…-Nextステートメント ExcelVBA Standard

このページの内容について

このページは、VBAエキスパート(ExcelVBAスタンダード)試験合格講座の第四回記事です。公式テキスト第3章「ステートメント」の内容について解説します。ExcelVBA(マクロ)には繰り返し処理が複数用意されています。自分でも手を動かしながら読み進めてください。主に講座受講者の復習での利用を想定しています。

For Each … Nextステートメント

「For … Next」ステートメントはカウンタ変数を使用して指定した回数の繰り返しを実現しました。これから解説する「For Each … Next」ステートメントはコレクションや配列に格納された要素をひとつずつ取り出しながら、要素をすべて取り出すまで繰り返します。

文法

For Each 取り出した要素を格納する変数 In コレクションや配列
繰り返し処理
Next [取り出した要素を格納する変数]

コレクションの繰り返し

コレクションとは同じオブジェクトの集合体です。例えば「WorkSheets(1)」のようにコレクションに格納されたオブジェクトはインデックスを指定して取得、操作することができます。「For Each … Next」ステートメント要素の1番目から順番に要素を取り出し繰り返し処理を実行します。

サンプルコード(クリックでコピー)

Private Sub Test_ForEachCollection()

Dim ws As Worksheet

For Each ws In ThisWorkbook.Worksheets

Debug.Print ws.Name

Next ws

End Sub

実行結果

上記サンプルコードはマクロが格納されたブック(ThisWorkbook)のWorkSheetsコレクションを先頭から順番に1つずつとりだしオブジェクト変数「ws」に格納し、シート名をイミディエイトウィンドウに出力します。

セル範囲の繰り返し

Cells

VBAでは、本来、コレクションは一つのインデックスで1つのオブジェクトを特定できます。ただし、ExcelVBA専用に作成された「Cells」は「行番号, 列番号」を指定する必要がある特殊なコレクションです。しかし「Cells」も一種のコレクションであるため「For Each … Next」ステートメントで操作をすることができます。

サンプルコード(クリックでコピー)
Private Sub Test_ForEachCells()

Dim rng_obj As Range

For Each rng_obj In ThisWorkbook.Worksheets(1).Cells

Debug.Print rng_obj.Row & ", " & rng_obj.Column
DoEvents

Next rng_obj

End Sub
実行結果

上記サンプルコードはマクロが実行中のブックのシート一番目のセルがすべて格納されたCellsコレクションから要素をひとつずつ取り出します。取り出されたセルの行番号、列番号をイミディエイトウィンドウに出力しますが、このマクロは現実的な時間では終了しませんので、動きを確認したら停止ボタンで終了させてください。

セルの繰り返し処理の順番はA1、B1、C1と列方向に向かって処理され、最終列まで処理されると、次の行の処理(A2、B2、C2..)に移ることが確認できます。この実行順はマクロを何度実行しても変わりません。

Range

「Cells」ではセルの範囲を指定するのが難しいのでセルの範囲を処理する「For Each … Next」ステートメントを記述するときは、通常、Rangeオブジェクトでセル範囲を指定します。Rangeオブジェクトも「Cells」と同様、ExcelVBA専用に特別に作成されたものであるため、オブジェクトでありながら「For Each … Next」ステートメントで処理することができます。

サンプルコード(クリックでコピー)
Private Sub Test_ForEachRange()

Dim ws As Worksheet
Dim rng_obj As Range

Set ws = ThisWorkbook.Worksheets(1)

For Each rng_obj In ws.Range("A1:C10")

Debug.Print rng_obj.Value

Next rng_obj

End Sub
実行結果

上記サンプルコードはマクロが実行中のブックのシート一番目のセル範囲「A1:C10」からセルを一つずつ取り出して格納された値をイミディエイトウィンドウに出力します。Cellsの処理と同様、列方向に向かって処理されます。

「Selection」は選択中のオブジェクトをすべて返します。選択されているのがセルであれば「For Each … Next」ステートメントで処理することができます。

配列の繰り返し

コレクションやセル範囲と同じように配列も要素を一つずつ取り出して繰り返しさせることができます。

サンプルコード(クリックでコピー)

Private Sub Test_ForEachArray()

Dim arr()
Dim val

ReDim arr(0 To 2, 0 To 4)

arr(0, 0) = "あ"
arr(0, 1) = "い"
arr(0, 2) = "う"
arr(0, 3) = "え"
arr(0, 4) = "お"
arr(1, 0) = "か"
arr(1, 1) = "き"
arr(1, 2) = "く"
arr(1, 3) = "け"
arr(1, 4) = "こ"

For Each val In arr

Debug.Print val

Next val

End Sub

実行結果

上記サンプルコードは配列に「あ~お、か~こ」を格納し、その後すべての要素をイミディエイトウィンドウに出力します。

Cells(行番号, 列番号)を「For Each … Next」ステートメントで処理する場合、列方向に処理が進みます。しかし二次元配列(一次元目のインデックス, 二次元目のインデックス)を処理する場合は、1次元目の要素から順番に処理されます。配列とセルでは処理の方向が異なる点に注意しましょう。

【PR】VBAエキスパート試験対策記事

当サイトでは、オデッセイコミュニケーションズ社が運営する試験であるVBAエキスパートExcel VBA ベーシックExcel VBA スタンダード)の出題範囲をベースに用語や各種関数の解説などを行っています。試験合格に向けて必須と言われる公式テキストに沿って解説をしています。受験をするか悩んでいる方、テキストとは別視点の解説を見てみたい方、受験はしないがExcelVBA(マクロ)に興味がある方へ向けた記事です。

Comment