【VBA】For Eachの使い方|セル・シート・配列を一括処理

スポンサーリンク

「セル範囲を全部チェックしたいのに、番号の指定が面倒……」

そんな悩み、VBAを書いていると一度は感じますよね。
ループ回数を自分で管理するのは手間ですし、範囲が変わるたびにコードを直すのも大変です。

For Each~Nextを使えば、対象のセルやシートをまるごとループできます。
番号の管理が不要になり、コードもすっきり書けますよ。

この記事では、For Eachの基本構文から実務パターンまでまとめて解説します。

For Each~Nextとは?基本の書き方をおさらい

For Each~Nextは、コレクション(まとまり)の中身を1つずつ取り出して処理するループ構文です。

「セル範囲のすべてのセル」「ブック内のすべてのシート」など、グループの要素をまとめて処理したいときに使います。

基本の構文は次のとおりです。

For Each 変数 In コレクション
    '繰り返したい処理
Next 変数

変数にはコレクションの要素が1つずつ代入されます。
すべての要素を処理し終わると、自動的にループを抜けます。

ポイントは、ループの回数を指定しなくてよいことです。
コレクションの要素数が変わっても、コードの修正は不要ですよ。

For~Nextとの違いはなに?

For~Nextは、回数を指定して繰り返すループ構文です。
一方、For Eachは対象のまとまりを順に処理する構文です。

ざっくりまとめると、こんなイメージになります。

  • For~Next: 「1番目から10番目まで処理して」
  • For Each: 「この中の全部を処理して」

回数が決まっている処理にはFor~Nextが向いています。
「全部に同じ処理をしたい」ならFor Eachが便利です。

使い分けの詳しい判断軸は、記事の後半で解説しますね。

【パターン1】セル範囲を一括処理する

For Eachでもっともよく使うのが、セル範囲のループです。
指定した範囲のすべてのセルに、同じ処理を適用できます。

Rangeに対してFor Eachを使う基本構文

セル範囲をFor Eachで処理するときは、Rangeオブジェクトをコレクションに指定します。

Sub セル範囲をループ()
    Dim cell As Range '処理対象のセル

    For Each cell In Range("A1:A10")
        cell.Value = cell.Value * 2 '値を2倍にする
    Next cell
End Sub

cellには、A1→A2→A3……と順にセルが代入されます。
各セルの値を2倍にする、シンプルな処理ですね。

なお、セルの処理順序は公式には保証されていません。
通常は左上から右下へ処理されますが、順序に依存するコードは避けるのがベターです。

実務サンプル:指定範囲のセルに処理を一括適用

実務では、動的な範囲を対象にすることが多いです。
最終行の取得と組み合わせたサンプルを見てみましょう。

Sub 空欄セルを強調表示()
    Dim lastRow As Long '最終行
    Dim cell As Range   '処理対象のセル

    lastRow = Cells(Rows.Count, "A").End(xlUp).Row

    For Each cell In Range("A1:C" & lastRow)
        If cell.Value = "" Then
            cell.Interior.Color = RGB(255, 200, 200) '薄い赤で塗る
        End If
    Next cell
End Sub

A列の最終行までの範囲で、空欄セルを薄い赤色にハイライトします。
データの入力漏れチェックに、そのまま使えますよ。

ループの途中で処理を抜けたいときは、Exit Forを使います。
最初の空欄が見つかった時点で止めるなら、こう書きます。

If cell.Value = "" Then
    MsgBox cell.Address & " が空欄です"
    Exit For '最初の空欄で停止
End If

【パターン2】全シートに同じ処理をする

ブック内の全シートにまとめて処理をかけたいとき、For Eachが活躍します。
シート数が増減しても、コードの変更は不要です。

WorksheetsコレクションとFor Eachの組み合わせ

WorksheetsコレクションをFor Eachに渡すと、全シートを順に処理できます。

Sub 全シート名を表示()
    Dim ws As Worksheet '処理対象のシート

    For Each ws In Worksheets
        Debug.Print ws.Name 'イミディエイトウィンドウに出力
    Next ws
End Sub

変数wsWorksheet型で宣言するのがポイントです。

ひとつ注意があります。
Worksheets非表示のシートも含みます
xlSheetVeryHiddenで隠したシートも対象になります。
表示シートだけ処理したいときは、条件を追加しましょう。

実務サンプル:全シートのA1セルをクリアする

Sub 全シートA1クリア()
    Dim ws As Worksheet '処理対象のシート

    For Each ws In Worksheets
        If ws.Visible = xlSheetVisible Then '表示シートのみ
            ws.Range("A1").ClearContents
        End If
    Next ws
End Sub

ws.Visible = xlSheetVisibleの条件で、表示中のシートだけを対象にしています。

特定のシートを除外したい場合もあるでしょう。
そのときはIf ws.Name <> "集計" Thenのように、シート名で判定してください。

【パターン3】配列のループにFor Eachを使う

For Eachは配列のループにも使えます。
ただし、注意点があるので確認しておきましょう。

配列に対してFor Eachを使う書き方

Sub 配列をループ()
    Dim arr As Variant '配列
    Dim item As Variant '配列の要素 ※Variant型が必須

    arr = Array("東京", "大阪", "名古屋")

    For Each item In arr
        Debug.Print item
    Next item
End Sub

ここで大事なポイントがあります。
配列をFor Eachで回すとき、変数は必ずVariant型にしてください。
Dim item As Stringのように宣言するとエラーになります。

コレクション(Worksheetsなど)では専用の型が使えます。
しかし、配列はVariant限定です。
つまずきやすいので覚えておきましょう。

For~Nextとどちらが向いている?比較まとめ

配列のループでは、For~Nextのほうが向いているケースもあります。

比較項目For EachFor~Next
インデックス(番号)の取得できないできる
要素の書き換えできない(読み取り専用)できる
コードのシンプルさシンプルやや冗長
変数の型Variant限定自由に指定可

配列の要素を読み取るだけならFor Eachが手軽です。
要素の書き換え番号が必要な処理には、For~Nextを選びましょう。

For EachとFor~Next どちらを使えばいい?

ここまで3つのパターンを見てきました。
「結局どっちを使えばいいの?」と迷ったときの判断軸をまとめます。

使い分けの判断軸まとめ

やりたいことおすすめ
セル範囲に同じ処理をしたいFor Each
全シートに同じ処理をしたいFor Each
配列を読み取りたいFor Each
ループ回数が決まっているFor~Next
インデックス番号が必要For~Next
配列の要素を書き換えたいFor~Next
条件で繰り返し回数が変わるDo Loop

迷ったら「対象のまとまりがあるか」で判断するのがコツです。
Range・WorksheetsなどのコレクションがあるならFor Eachです。
回数やインデックスが重要ならFor~Nextを選びましょう。

よくあるエラーについても触れておきます。
配列でVariant以外の型を使うと型の不一致エラーになります。
また、オブジェクト変数にSetを付け忘れるとエラー91が発生します。
変数の型宣言は慎重に行ってくださいね。

まとめ

この記事では、VBAのFor Each~Nextについて解説しました。

  • 基本構文: For Each 変数 In コレクション ... Next
  • セル範囲: Rangeを指定して全セルを一括処理
  • 全シート: Worksheetsで全シートをまとめて処理
  • 配列: Variant型の変数で要素を読み取り
  • 使い分け: コレクションがあればFor Each、回数指定ならFor~Next

For Eachを使いこなすと、繰り返し処理がぐっとシンプルになります。
まずはセル範囲のループから、ぜひ試してみてくださいね。

なお、作成したマクロは.xlsm(マクロ有効ブック)形式で保存してください。
.xlsxで保存するとマクロが消えてしまうので注意です。

タイトルとURLをコピーしました