【VBA入門】For Eachで配列やコレクション、Selectionを操作

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

実行結果:
ForEach05

このサンプルコードでは要素のデータ型がバリアント型の動的配列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

実行結果:
ForEach05

このサンプルコードでは、配列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

実行結果:
ForEach06

このサンプルコードでは、配列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

実行結果:
ForEach03

このサンプルコードでは、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

実行結果:
ForEach07

このサンプルコードでは、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ステートメントよりも手短に記述することができます。

使いこなすことができるように、この記事を何度も参考にして下さいね!

この記事を書いた人

熊本在住のフリープログラマ兼ライターです。C/C++/C#、Java、Python、HTML/CSS、PHPを使ってプログラミングをしています。専門は画像処理で最近は機械学習、ディープラーニングにはまっています。幅広くやってきた経験を活かしてポイントをわかりやすくお伝えしようと思います。
お問合せはこちらでも受け付けています。
info@sss-lab.com

目次