VBAで繰り返し処理を書くとき、多くの方が最初に覚えるのがFor...Nextステートメントです。しかし、シートやセル、ブックなどのオブジェクトを順番に処理する場合は、For Each...Nextステートメントの方が適している場面が少なくありません。
とはいえ、「For文との違いがよく分からない」「どんな場面で使えばよいのか判断できない」と感じている方も多いでしょう。
実務では、オブジェクトを順番に処理するケースが数多くあります。そのような場面でFor Eachを使えるようになると、コードが読みやすくなり、保守性も向上します。
この記事では、For Eachステートメントの基本構文から、Forステートメントとの違い、実務で使われる理由までを詳しく解説します。
✅ For Each ステートメントとは
For Eachは単なる別の繰り返し構文だと思われがちですが、それでは本来の役割を十分に理解できません。
「For文でも同じことができるのでは?」と考えてしまう方も少なくありませんが、実際には用途が異なります。
ここを理解しておかないと、すべての繰り返し処理をFor文だけで書いてしまい、読みづらく修正しにくいコードになってしまうことがあります。
実務では、処理対象に合わせてFor文とFor Eachを使い分けることが重要です。
まずはFor Eachがどのような役割を持つ構文なのかを確認していきましょう。
・For Each ステートメントの役割
For Eachステートメントとは、コレクションやオブジェクトを1つずつ順番に取り出して処理するための繰り返し構文です。
例えば、
- ワークシート
- ブック
- セル範囲
- 図形(Shape)
- グラフ
など、複数のオブジェクトをまとめて管理しているものを順番に処理する場合によく利用されます。
Forステートメントのように「1から10まで」という数値を増やしていくのではなく、「存在するオブジェクトを順番に取り出す」という考え方が特徴です。
・For文との考え方の違い
Forステートメントは、回数や番号を指定して繰り返す構文です。
例えば、
- 1行目から100行目まで処理する
- 1から10まで繰り返す
といった場面に向いています。
一方でFor Eachは、
- 存在するすべてのシート
- 存在するすべてのセル
- 存在するすべてのブック
のように、対象を順番に処理したい場合に利用します。
つまり、
- For=番号を管理する繰り返し
- For Each=オブジェクトを管理する繰り返し
という違いがあります。
For Eachはオブジェクトを順番に処理する構文ですが、行番号や回数を指定して繰り返す場合はForステートメントの方が適しています。可変データを最終行まで処理する方法については、「【VBA】For文で最終行まで繰り返す方法|可変データに対応する実務コード」で詳しく解説しています。
✅ For Each ステートメントの基本構文
For Eachは構文自体は非常にシンプルです。
しかし、変数の型や処理対象を正しく理解していないと、「なぜこの書き方なのか」が分からないまま覚えてしまうことがあります。
構文だけを暗記するのではなく、どの部分が何を意味しているのかを理解することで、さまざまなオブジェクトへ応用できるようになります。
ここでは基本構文から確認していきましょう。
・基本構文
Dim TargetSheet As Worksheet
For Each TargetSheet In Worksheets
'処理
Next TargetSheet
この構文では、
Worksheetsの中にあるワークシートを- 1枚ずつ
TargetSheetへ取り出し Nextまでの処理を繰り返します。
処理が終わると、自動的に次のワークシートが取り出されます。
最後のワークシートまで処理すると、ループは終了します。
・変数名は意味が分かる名前にする
実務では、変数名をwsやobjのように短くするよりも、役割が分かる名前にすることをおすすめします。
例えば、
Dim TargetSheet As Worksheet
であれば、
「現在処理しているワークシート」
であることがすぐに分かります。
処理対象がセルであれば、
Dim TargetCell As Range
ブックなら、
Dim TargetWorkbook As Workbook
というように、処理対象が分かる変数名を付けることで、後からコードを見直した際にも理解しやすくなります。
✅ なぜ実務では For Each がよく使われるのか
For Eachは「短く書けるから便利」という理由だけで使われているわけではありません。
実務では、コードを書く時間よりも、後から修正・保守する時間の方が長くなることがほとんどです。
そのため、「何を繰り返しているコードなのか」が一目で分かることが重要になります。
For Eachは、対象となるオブジェクトを順番に処理するという意図がコードから読み取りやすく、保守性の高いコードを書きやすいというメリットがあります。
・インデックス番号を意識しなくてよい
例えば、すべてのワークシートを処理したい場合、For文ではシート数を取得しながらインデックス番号を管理する必要があります。
一方、For Eachではその必要がありません。
「存在するすべてのシートを順番に処理する」という目的を、そのままコードで表現できます。
このように、番号を意識しなくても処理できることが、For Eachの大きな特徴です。
✅ For Each ステートメントが活躍する場面
For Eachは、すべての繰り返し処理で使う構文ではありません。
対象が「オブジェクトの集まり」である場合に力を発揮します。
逆に、回数を指定して繰り返す処理では、Forステートメントの方が適していることもあります。
それぞれの特徴を理解して使い分けることで、読みやすく保守しやすいコードを書くことができます。
ここでは、どのようなオブジェクトでFor Eachが利用されるのかを見ていきましょう。
・ワークシートを順番に処理する
実務では、ブック内のすべてのワークシートに対して同じ処理を行うことがあります。
例えば、
- シート名を変更する
- 印刷設定を統一する
- データを確認する
- 集計結果を書き込む
などです。
このような場合は、WorksheetsコレクションをFor Eachで順番に処理すると、シンプルで分かりやすいコードになります。
・ブックを順番に処理する
複数のExcelファイルを開いている場合は、Workbooksコレクションを対象にできます。
例えば、
- 開いているブックを順番に保存する
- ブック名を取得する
- 不要なブックを閉じる
といった処理で利用されます。
ブックの数が変わってもコードを書き換える必要がないため、保守性の高いコードになります。
・セルや図形などのオブジェクトにも利用できる
For Eachは、ワークシートだけでなくさまざまなオブジェクトで利用できます。
代表例としては次のようなものがあります。
RangeWorksheetsWorkbooksShapesChartObjectsNames
このように、「複数のオブジェクトをまとめて管理しているもの」であれば、For Eachを利用できるケースが多くあります。
For Eachの代表的な活用例が、セル範囲を順番に処理する方法です。セルを1つずつ操作する具体的な実装については、「【VBA】For Each を使ったセル範囲の操作方法」で詳しく紹介しています。
✅ For Each が向いていないケース
For Eachは便利な構文ですが、すべての繰り返し処理に適しているわけではありません。
「とりあえずFor Eachを使う」という考え方では、かえってコードが分かりにくくなることもあります。
実務では、処理内容に応じてForとFor Eachを使い分けることが重要です。
ここでは、For Eachが向いていない代表的なケースを紹介します。
・回数が決まっている処理
例えば、
- 1から100まで繰り返す
- 10回だけ実行する
- 5行ごとに処理する
といった場合は、Forステートメントの方が適しています。
回数を明確に指定できるため、処理内容も理解しやすくなります。
・インデックス番号が必要な処理
処理対象の「何番目」を利用したい場合も、Forステートメントが向いています。
例えば、
- 奇数行だけ処理する
- 3行ごとに色を変える
- インデックス番号を計算に利用する
といったケースです。
For Eachでは現在の番号を直接取得できないため、このような処理ではForの方がシンプルになります。
行番号や回数を管理する処理では、For EachよりもForステートメントが適しています。最終行まで安全に繰り返す方法については、「【VBA】For文で最終行まで繰り返す方法|可変データに対応する実務コード」をご覧ください。
✅ 実務で保守しやすい For Each の書き方
For Eachは短く書けることがメリットですが、実務では「短いコード」よりも「意図が伝わるコード」の方が重要です。
後から自分で修正したり、別の担当者へ引き継いだりすることを考えると、読みやすさを意識した書き方が求められます。
ここでは、保守性を高めるためのポイントを紹介します。
・処理対象が分かる変数名を付ける
例えば、
ws
よりも、
TargetSheet
のように役割が分かる名前の方が、コードを読んだときに処理内容を理解しやすくなります。
同様に、
TargetWorkbookTargetCellTargetShape
など、処理対象が分かる命名を意識すると保守性が向上します。
・途中で処理を終了する場合は Exit For を利用する
すべてのオブジェクトを処理する必要がない場合は、Exit Forを利用してループを終了できます。
例えば、
- 条件に一致するシートが見つかった
- 必要なセルを取得できた
- 探していたブックが見つかった
といったケースでは、残りのオブジェクトを処理する必要はありません。
不要なループを避けることで、処理時間の短縮やコードの意図を明確にすることにつながります。
保守性の高いコードを書くには、For Eachの使い方だけでなく、分かりやすい変数名を付けることも重要です。命名規則について詳しく知りたい方は、「【VBA】変数名の付け方|キャメルケース・スネークケースなど命名規則を徹底解説」もぜひ参考にしてください。
✅ 実務では「何を繰り返すか」で For と For Each を選ぶ
ForとFor Eachは、どちらが優れているという関係ではありません。
重要なのは、「何を繰り返したいのか」を基準に選択することです。
回数や番号を管理したいのであればFor、オブジェクトを順番に処理したいのであればFor Eachを選ぶことで、コードの可読性や保守性を高められます。
また、For Eachを理解すると、セル範囲だけでなく、ワークシートやブック、図形などさまざまなオブジェクトを効率よく操作できるようになります。
実務では、For Eachを使ったセル範囲の処理や、Findと組み合わせた検索処理もよく利用されます。基本構文を理解したうえで応用例を学ぶことで、より実践的なVBAコードを書けるようになるでしょう。
実務では、Findメソッドで検索したセルをFor Eachと組み合わせて処理する場面も多くあります。具体的な実装例については、「【VBA】条件に一致するセルを取得する方法|Find・For Each・SpecialCells」を参考にしてください。
条件に一致するセルが複数ある場合は、For Eachで順番に処理すると効率よく実装できます。詳しくは「【VBA】条件に一致するセルを複数取得する方法|Find・For Each・SpecialCells」で紹介しています。
✅ まとめ:For Each ステートメントを理解して保守しやすいVBAを書こう
For Eachステートメントは、オブジェクトを順番に処理するための繰り返し構文です。
今回紹介したポイントを振り返ると、次のようになります。
For Eachはオブジェクトを順番に処理する構文Forは回数やインデックス番号を管理する構文- ワークシート・ブック・セル・図形などで利用できる
- 回数が決まっている処理には
Forの方が適している - 処理対象が分かる変数名を付けることで保守性が向上する
- 条件によっては
Exit Forで途中終了すると効率的になる
For Eachの考え方を身に付けることで、オブジェクトを扱うVBAコードをより読みやすく、保守しやすく記述できるようになります。まずはワークシートやブックなど身近なオブジェクトを対象に、Forとの違いを意識しながら使い分けてみてください。