For Eachステートメントって使ってますか?
For Eachステートメントは配列やコレクションなどですべての要素にアクセスする場合に使用すると手短に記述することができて便利です。
この記事では、For Eachステートメントについて
- For Eachとは
- For Eachの使い方
- Selectionを操作する方法
- コレクションを操作する方法
- フォルダ内のファイル名を取得する方法
など基本的な内容から、応用的な内容についても解説していきます。
今回はFor Eachステートメントについて、使い方をわかりやすく解説します!
For Eachステートメントとは
For Eachステートメントとは、配列やコレクションなどのグループの各要素に対して繰り返し処理を行う場合に使用します。
ちなみにコレクションとは、オブジェクトの集合のことです。繰り返し処理を行うよく似たステートメントにFor Nextステートメントがあります。For Nextステートメントは配列やコレクションに限らず用いられます。
これに対して、For Eachステートメントは配列やコレクションなどのグループに対して用いることで効果を発揮します。
それではFor Eachステートメントの効果について確認していいきましょう!
For Eachの使い方
For Eachステートメントは以下のように記述して使います。
Dim 要素を受け取る変数名 As Variant For Each 要素を受け取る変数名 In 配列やコレクションなどのグループ名 処理 Next 要素を受け取る変数名
配列やコレクションの要素を受け取る変数を宣言しますが、For Eachステートメントで使う要素の型はバリアント型もしくはオブジェクト型で指定する必要があります。
なお、Dimステートメントを使った変数の宣言については省略することもできます。
それでは具体例についてみていきましょう!
配列を操作する方法
配列の要素を操作する方法についてサンプルコードでみていきましょう。
Sub macro1() Dim arr() As Variant arr = Array(1, 2, 3, 4, 5) Dim str As String For Each Var In arr 'Variant型変数Varの宣言は省略 str = str & Var & ", " Next Var MsgBox str End Sub
実行結果:
このサンプルコードでは要素のデータ型がバリアント型の動的配列arrを宣言しています。
Array関数を使って配列arrを初期化しています。配列arrの要素にアクセスするためにFor Eachステートメントを使用しています。
配列の要素を受け取る変数VarはDimステートメントを使った宣言を省略して使っています。配列の使い方についてはこちらで詳しく解説していますので、ぜひ参考にしてください。
For Nextとの使い分けについて
先ほどのFor Eachステートメントを使ったサンプルコードをFor Nextステートメントを使って書き換えてみましょう。
Sub macro2() Dim arr() As Variant arr = Array(1, 2, 3, 4, 5) Dim str As String Dim i As Integer 'インデックス番号の変数を宣言 For i = LBound(arr) To UBound(arr) str = str & arr(i) & ", " Next i MsgBox str End Sub
実行結果:
このサンプルコードでは、配列arrの要素にアクセスするためにFor Nextステートメントを使用しています。For Nextステートメントを使用する場合は、インデックス番号に用いる変数iを宣言する必要があります。
また、LBound関数とUBound関数を使ってFor Nextステートメントのカウンタの初期値と到達値を指定する必要があります。これによってFor Eachステートメントを使う場合に比べて、記述が長くなり面倒が生じます。
配列やコレクションのようなグループの要素にアクセスする場合はFor Eachステートメントを使う方が手短に記述できるのでオススメです。
For Next文の使い方については、こちらで詳しく解説していますので、ぜひ参考にしてください。
逆順でループを回すには?
配列やコレクションの要素に逆順でアクセスしたい場合がありますよね?でも、For Eachステートメントでは順番を指定することはできません。
ですので、逆順でアクセスするなど順番を指定する場合はFor Nextステートメントを使う必要があります。
For Nextステートメントを使って、逆順で要素にアクセスするサンプルコードをみていきましょう。
Sub macro3() Dim arr() As Variant arr = Array(1, 2, 3, 4, 5) Dim str As String Dim i As Integer For i = UBound(arr) To LBound(arr) Step -1 str = str & arr(i) & ", " Next i MsgBox str End Sub
実行結果:
このサンプルコードでは、配列arrの要素に逆順でアクセスするためにFor Nextステートメントを使用しています。
Selectionを操作する方法
Selectionとは、Excelシート上で選択されたセルの範囲のことです。
For EachステートメントではこのSelection内のセルを要素として受け取ることができます。
サンプルコードで確認していきましょう。
Sub macro4() Dim myRange As Range For Each myRange In Selection myRange.Value = "Hello VBA!" Next myRange End Sub
実行結果:
このサンプルコードでは、Excelのシート上で選択した範囲の複数のセルにFor Eachステートメントを使って文字列を入力しています。
コレクションを操作する方法
コレクションの要素にアクセスする場合にも、For Eachステートメントを使うと便利です。
VBAで既存のコレクションといえば、Worksheetsがあります。
Worksheetsコレクションを例にしてサンプルコードで確認していきましょう。
Sub macro5() Dim str As String For Each ws In Worksheets str = str & ws.Name & ", " Next ws MsgBox str End Sub
実行結果:
このサンプルコードでは、Worksheetsコレクションの要素にFor Eachステートメントを使ってアクセスし、各Worksheetのシート名を取得しています。
Collection(コレクション)の使い方につていはこちらで詳しく解説していますので、ぜひ参考にしてください。
フォルダ内のファイル名を取得する方法
フォルダ内のブックを一括処理したい場合があります。そんな場合にもFor Eachステートメントを使うと手短に記述できて便利です。
For Eachステートメントでフォルダ内のファイルを扱うにはFileSystemオブジェクトを使用する必要があります。
サンプルコードで確認しましょう。
Sub macro6() 'FieSystemオブジェクトの作成 Dim myObj As Object Set myObj = CreateObject("Scripting.FileSystemObject") Dim str As String For Each obj In myObj.getfolder(ThisWorkbook.Path).Files str = str & obj.Name & vbCrLf Next obj MsgBox str End Sub
このサンプルコードでは、まずCreateObject(“Scripting.FileSystemObject”)と記述してFileSystemオブジェクトmyObjを作成しています。
オブジェクトmyObjからgetfolderメソッドを呼び出しこのワークブックのパスを指定しています。パスに含まれるファイルに関する情報をFilesコレクションで取得しています。
For Eachステートメントを使ってFilesコレクションのすべての要素にアクセスし、同じフォルダ内のすべてのファイルのファイル名を取得しています。
まとめ
ここでは、For Eachステートメントについて説明しました。
For Eachステートメントは配列やコレクションなどの要素にアクセスする場合は、For Nextステートメントよりも手短に記述することができます。
使いこなすことができるように、この記事を何度も参考にして下さいね!