Excel VBAでセル範囲を順番に処理したい場合、「For文」と「For Each」のどちらを使えばよいのか迷うことはありませんか。
特に、セル一つひとつに対して同じ処理を行いたい場面では、For文でも実現できますが、コードが長くなったり、行番号や列番号の管理が複雑になったりすることがあります。
そのような場面で活躍するのがFor Eachです。
セル範囲を直接順番に取り出して処理できるため、コードが読みやすくなり、保守もしやすくなります。
この記事では、For Eachを使ってセル範囲を操作する基本的な方法から、実務で使いやすいコードの考え方まで解説します。
✅ VBAでFor Eachを使ってセル範囲を操作する方法
セル範囲を繰り返し処理する際、多くの初心者はFor文だけで実装しようとしがちです。
もちろんFor文でも処理はできますが、セル範囲そのものを対象にする場合は、For Eachの方がシンプルに書けるケースが多くあります。
ここを理解していないと、不要に複雑なコードを書いてしまい、後から修正しづらくなることがあります。
まずは、For Eachがセル範囲をどのように処理していくのかを理解しましょう。
・セル範囲を順番に処理する仕組み
For Eachは、指定したセル範囲のセルを一つずつ取り出して処理します。
例えば、
- A1
- A2
- A3
- A4
- A5
という範囲を指定すると、
A1 → A2 → A3 → A4 → A5
の順番でセルを取得しながら処理が実行されます。
行番号や列番号を自分で増やす必要がないため、コードを簡潔に記述できることが大きな特徴です。
・Rangeと組み合わせる基本コード
セル範囲をFor Eachで処理する基本コードは次のようになります。
処理対象をRangeとして指定するだけで、セルを一つずつ取得できます。
Sub LoopRange()
'セルを格納する変数
Dim targetCell As Range
'A1:A5を順番に処理
For Each targetCell In Range("A1:A5")
Debug.Print targetCell.Value
Next targetCell
End Sub
このコードでは、A1からA5までのセルを順番に取得し、それぞれの値をイミディエイトウィンドウへ表示しています。
変数名をtargetCellのように役割が分かる名前にしておくことで、後からコードを見返したときも理解しやすくなります。
For Eachではセルそのものを取得して処理するため、Valueプロパティを使用する場面が多くあります。Cells・Range・Valueの違いや安全な使い分けについては、「文字列として取得する方法」の記事も参考にしてください。
✅ For Eachでセル範囲を処理するメリット
For Eachは「短く書けるから便利」というだけではありません。
実務では、コードの保守性や可読性を高められることが大きなメリットになります。
ここでは、なぜセル範囲の処理でFor Eachがよく使われるのかを見ていきましょう。
・行番号や列番号を意識しなくてよい
For文では、通常はカウンタ変数を利用します。
例えば、
For rowIndex = 1 To 10
のように、何行目を処理しているのかを常に管理する必要があります。
一方、For Eachではセルそのものを取得するため、
For Each targetCell In Range("A1:A10")
と書くだけで済みます。
そのため、処理対象がセルであることがコードから一目で分かります。
・コードが読みやすくなる
セル範囲を処理する場合は、
「何行目を処理しているか」
よりも、
「どのセルを処理しているか」
の方が重要になるケースが多くあります。
For Eachはセルそのものを扱うため、
targetCell.Value
という書き方だけで処理内容が理解できます。
コードレビューや保守の際にも、処理の流れを把握しやすくなることが実務では大きなメリットになります。
✅ セル範囲に対してよく使う処理
For Eachはセル範囲を取得できるため、さまざまな処理へ応用できます。
単に値を表示するだけでなく、値を書き換えたり、条件に応じて処理を分けたりと、実務でも幅広く活用されています。
ここでは、代表的な活用例を紹介します。
・セルの値を書き換える
セル範囲全体に対して同じ処理を行う場合は、For Eachが非常に便利です。
例えば、すべてのセルを大文字へ変換する場合は次のように記述できます。
Sub ConvertUpperCase()
'セルを格納する変数
Dim targetCell As Range
'A1:A5を順番に処理
For Each targetCell In Range("A1:A5")
targetCell.Value = UCase(targetCell.Value)
Next targetCell
End Sub
セルを直接取得しているため、どのセルを処理しているのかが分かりやすく、コードの意図も伝わりやすくなります。
✅ 空白セルを考慮してセル範囲を操作する方法
セル範囲を処理する場合、すべてのセルに値が入っているとは限りません。
実務では、途中に空白セルが含まれていることも珍しくなく、そのまま処理すると意図しない結果になることがあります。
そのため、セル範囲を繰り返し処理するときは、「空白セルをどう扱うか」をあらかじめ設計しておくことが重要です。
・空白セルを除外して処理する
空白セルを処理対象から除外したい場合は、セルの値を判定してから処理を行います。
次のコードでは、値が入力されているセルだけを処理します。
Sub ProcessNonBlankCells()
'セルを格納する変数
Dim targetCell As Range
'セルを順番に処理
For Each targetCell In Range("A1:A10")
'空白セルは処理しない
If targetCell.Value <> "" Then
Debug.Print targetCell.Value
End If
Next targetCell
End Sub
このように判定を追加しておくことで、空白セルによる不要な処理を防げます。
実務ではデータ件数が毎回異なることも多いため、このような条件分岐を組み合わせる場面は非常によくあります。
空白セルや空白行を考慮したループ処理は、実務では欠かせません。空白行を基準に安全に処理を終了する方法については、「For文で空白行まで繰り返す方法」の記事で詳しく解説しています。
・条件に一致するセルだけ処理する
For Eachは、空白判定だけでなく条件分岐とも相性が良い構文です。
例えば、数値が100以上のセルだけ色を付けたい場合なども、セルを一つずつ判定しながら処理できます。
セルを取得してから条件を判断するという流れは、実務で最もよく利用されるパターンの一つです。
今回はセル範囲全体を順番に処理しましたが、特定の条件に一致するセルだけ取得したい場合はFindメソッドを利用すると効率的です。詳しくは、「条件に一致するセルを取得する方法」をご覧ください。
✅ For文とFor Eachはどのように使い分けるべきか
For Eachを覚えると、「すべてFor Eachで書けばよいのでは?」と思う方もいます。
しかし、実務ではFor文の方が適している場面もあります。
重要なのは、「何を繰り返したいのか」を基準に使い分けることです。
・セルを処理するならFor Each
セル範囲を順番に処理するのであれば、基本的にはFor Eachがおすすめです。
例えば、
- セルの値を取得する
- セルへ値を書き込む
- セルの背景色を変更する
- フォントを変更する
など、セルそのものを対象にする処理では、For Eachの方がコードを簡潔に書けます。
セルそのものを順番に処理する場合はFor Eachが便利ですが、最終行を基準に繰り返す処理ではFor文の方が適しているケースもあります。可変データを扱う方法については、「For文で最終行まで繰り返す方法」もあわせてご覧ください。
・番号を利用するならFor文
一方で、
- 1行おきに処理する
- 末尾から逆順で処理する
- 行番号を計算に利用する
といった場合は、For文の方が適しています。
例えば、
For rowIndex = 2 To lastRow
のように行番号を利用する処理では、For文の方が柔軟に制御できます。
つまり、
- セルを順番に扱うならFor Each
- 番号を制御するならFor文
という考え方を覚えておくと、実務でも迷いにくくなります。
For文とFor Eachは、処理内容によって使い分けることが重要です。For文とIF文を組み合わせた実践的なデータ抽出については、「条件に合うデータを抽出する方法」の記事もおすすめです。
✅ 実務で保守しやすいFor Eachコードを書くポイント
For Eachは簡潔に書ける構文ですが、読みやすさを意識することで、さらに保守しやすいコードになります。
将来的に修正することを考えながら記述することも、実務では重要です。
・意味が分かる変数名を付ける
例えば、
Dim c As Range
でも動作します。
しかし、
Dim targetCell As Range
のように記述した方が、
「処理対象となるセル」
であることがすぐに分かります。
コードを数か月後に見返したときや、別の担当者が修正する場合にも理解しやすくなります。
targetCellのように役割が分かる変数名を付けることで、コードの可読性や保守性が向上します。実務で使われる命名規則については、「変数名の付け方」の記事で詳しく解説しています。
・処理内容をコメントで残す
For Eachの処理が長くなる場合は、適切にコメントを追加しましょう。
例えば、
'入力済みセルのみ処理
や
'売上金額を更新
といったコメントを付けておくだけでも、コード全体の意図が伝わりやすくなります。
コメントは処理を一行ずつ説明するためではなく、「なぜその処理をしているのか」を伝えるために書くことが大切です。
✅ FindやSpecialCellsとの使い分け
For Eachは便利な構文ですが、すべての場面で最適というわけではありません。
目的によっては、FindメソッドやSpecialCellsを利用した方が効率的な場合もあります。
例えば、
- 特定の文字列だけ検索したい
- 数式セルだけ取得したい
- 空白セルだけ取得したい
といった場合は、For Eachですべてのセルを確認するよりも、専用のメソッドを利用した方が高速でコードも分かりやすくなります。
実務では、
- セル範囲全体を順番に処理するならFor Each
- 条件に一致するセルだけ取得するならFind
- 特定の種類のセルだけ取得するならSpecialCells
というように、目的に応じて使い分けることが重要です。
条件に一致するセルが複数存在する場合は、FindやFor Eachを組み合わせることで柔軟な処理ができます。複数セルの取得方法については、「条件に一致するセルを複数取得する方法」をご覧ください。
空白セルや数式セルなど、特定の種類のセルだけを取得したい場合はSpecialCellsメソッドが便利です。用途や使い分けについては、「SpecialCellsメソッドで特定のセルを一括抽出する方法」で詳しく解説しています。
✅ まとめ:For Eachでセル範囲を効率よく操作しよう
今回は、For Eachを使ったセル範囲の操作方法について解説しました。
セル範囲を順番に処理する場合は、For文よりもFor Eachを利用した方が、コードをシンプルかつ読みやすく記述できる場面が多くあります。
また、空白セルの判定や条件分岐を組み合わせることで、実務でも再利用しやすいコードになります。
この記事のポイントをまとめます。
- For Eachはセル範囲を順番に処理する構文
- Rangeと組み合わせることでセルを一つずつ取得できる
- セルを対象とした処理はFor Eachが読みやすい
- 空白セルや条件分岐を組み合わせると実務で活用しやすい
- 行番号や列番号を制御する場合はFor文が適している
- FindやSpecialCellsと目的に応じて使い分けることが重要
セル範囲を扱うマクロでは、For Eachは最も使用頻度の高い構文の一つです。
まずは基本的なセル範囲の繰り返し処理から慣れ、用途に応じてFor文やFind、SpecialCellsと使い分けられるようになると、より保守性と再利用性の高いVBAコードを書けるようになります。