🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

Excel VBA の Union — 離れた範囲を 1 つの参照にまとめる(そしてなぜ重複を取り除かないのか)

|

Excel VBA の Union — 離れた範囲を 1 つの参照にまとめる(そしてなぜ重複を取り除かないのか)

TL;DRUnion は、散らばった長方形を 1 つの参照に貼り合わせ、離れた複数の ブロックを一度に操作できるようにします。複数のエリアを Ctrl を押しながらクリックする ことのコード版です。最も大事なルール:Union連結するだけで、重複を取り除きません — 重なったセルは二重に数えられるので、これは数学的な集合の和ではなくバッチのリストです。 最も役立つ形は、ループでセルを集めて一度だけ操作する蓄積パターンです。

Dim flagged As Range, c As Range
For Each c In ThisWorkbook.Worksheets("Data").Range("B2:B1000")
    If c.Value < 0 Then
        If flagged Is Nothing Then Set flagged = c Else Set flagged = Union(flagged, c)
    End If
Next c
If Not flagged Is Nothing Then flagged.Interior.Color = vbRed   ' 一致したすべてを 1 回で色づけ

ここまでのどの参照も、1 つの長方形を保持していました。Union はその限界を破ります。 1 つの範囲変数が、いまや B2D5:D9F1 を同時に保持でき、1 行でその 3 つすべてを色づけ・ 消去・コピーできます。SpecialCellsExcelに非連続な集合を選ばせるのに対し、Unionあなたが意図して 1 つを組み立てます。本記事は 1 つの考えを軸にしています。Union は、 一度だけ操作するためのバッチを組み立てる手段であって、重複を除いた集合を計算する方法ではない。 これを押さえれば、.Count の意外な結果も Nothing エラーも、どちらも腑に落ちます。

この記事で学べること

  • 考え方の軸 — Union は離れた範囲を1 つの参照にまとめる(コードでの Ctrl クリック)
  • 最も大事なルール — 連結であって重複排除ではないので、重なりは二重に数えられる
  • 蓄積パターン — If Is Nothing ... Else Union と、それが実行時エラーを避ける理由
  • バッチ操作 — 多数のブロックをループではなく1 回の呼び出しで色づけ・消去・コピー
  • 制約 — 引数は 2 つ以上、Nothing は不可、すべてのエリアは同じシート
  • Union(∪、まとめる)が Intersect(∩、重なり)とどう違うか

考え方の軸:Union は離れた範囲を 1 つの参照にまとめる

Union は 2 つ以上の範囲を取り、そのすべてを覆う 1 つの範囲を返します。

Dim multi As Range
Set multi = Union(Range("A1:A3"), Range("C1:C3"), Range("E1"))
multi.Interior.Color = vbYellow   ' 3 つの別ブロックをまとめて強調する

その参照は、ほとんどの操作でほかの範囲と変わらず振る舞います — 1 回の .Interior.Color、 1 回の .ClearContents、1 回の .Copy がすべてのブロックに効きます。Ctrl を押しながら手で セルを選ぶさまを思い浮かべてください。A1:A3 をクリックし、次に C1:C3、そして E1 をクリックすると、 それらはグループとして動きます。Union はその Ctrl クリックをコードで表したもので、非連続な 1 つの選択を 1 つの操作へ渡す唯一の方法です。

最も大事なルール:Union は連結であって重複排除ではない

ここで名前が人を惑わせます。集合論の「和(union)」は重複を取り除きます。VBA の Union は 取り除きません。エリアをそのまま縫い合わせるので、複数の引数に現れるセルは二重に 数えられます。

Dim u As Range
Set u = Union(Range("A1:A5"), Range("A3:A8"))
Debug.Print u.Count    ' 8 ではなく 11 と表示(5 + 6) - A3:A5 が二重に数えられる

重なりの A3:A5 は両方の引数から含まれるので、.Count は、実際には 8 個しかない別々のセルに 対して 11 と報告します。参照を操作している分にはこれは無害です — 同じセルに 2 回色を 設定しても悪いことは起きません — が、結果を .Count したり、合計したり、別々のセルを前提と する場所へ渡したりするなら、これは本物のバグです。要点はこうです。Union操作すべきセルを 組み立てるために使い、別々のセルが何個あるかを計算するために使ってはいけません。本当に 重複を除いた集合が必要なら、代わりに AutoFilter でデータを絞りましょう。

蓄積パターン:ループの中で参照を組み立てる

Union の最も価値ある使い方は、ループの最中に一致を集め、最後に一度だけそれらを操作する ことです。ただし落とし穴があります。Union は少なくとも 2 つの実在する範囲を要求し、Nothing拒否するので、rngAll がまだ空のとき最初の反復で Union(rngAll, c) は失敗します。定番の イディオムは、最初のセルをガードします。

Dim rngAll As Range, c As Range
For Each c In Range("A2:A1000")
    If Len(Trim(c.Value)) = 0 Then                 ' 条件は何であれ
        If rngAll Is Nothing Then
            Set rngAll = c                          ' 最初の一致: そのまま種にする
        Else
            Set rngAll = Union(rngAll, c)           ' 以降の一致: 参照を広げる
        End If
    End If
Next c
If Not rngAll Is Nothing Then rngAll.EntireRow.Delete   ' すべての一致を 1 回で削除

このガードはこう読みます。最初の一致で参照を種づけし、あとは残りを次々に Union で足していく。 If rngAll Is Nothing の分岐を飛ばすのが Union エラーの第 1 位です — 引数として Nothing を 渡すと、ループが最初の一致を見つけた瞬間に実行時エラーが発生します。

バッチ操作:ループではなく 1 回の呼び出し

見つけるたびに各セルを操作するのではなく、そもそもなぜ参照を組み立てるのか? 速度です。 セルごとに 1 回ワークシートに触れることは、マクロが遅くなる第 1 位の原因です。Union でセルを 集め、それからグループ全体へ1 回の操作を行います — ループの中で判断し、範囲に適用する。

' 遅い: 一致する行ごとにシートへ書き込む
For Each c In rng
    If c.Value > 100 Then c.Interior.Color = vbGreen   ' 一致ごとに 1 回シートへ触れる
Next c

' 速い: まず集め、一度だけ色づけ
For Each c In rng
    If c.Value > 100 Then _
        Set hot = IIf(hot Is Nothing, c, Union(hot, c))
Next c
If Not hot Is Nothing Then hot.Interior.Color = vbGreen   ' シートへの操作は 1 回だけ

これは cell-color のガイドが強調に勧めるのと同じ流儀です。対象を 集め、書式を一度だけ適用する。数千行では、その差は秒とミリ秒の違いになります。

制約:引数は 2 つ、Nothing 不可、同じシート

3 つの制約が人を捕まえますが、どれも一言で言えます。

  • 範囲は 2 つ以上。 Union は 2 つ以上の引数を要求し、そのどれも Nothing であっては なりません — だから上の蓄積ガードが要るのです。
  • 同じワークシート。 union するすべての範囲は同じシート上になければなりません。2 つの シートの範囲を組み合わせると error 1004 が発生します。シートをまたぐ作業が必要なら、 各シートの union を別々に処理しましょう。
  • 結果は複数エリア。 SpecialCells と同じく、union は非連続な 参照です。連続する各ブロックが必要なら For Each area In u.Areas でループし、.Count は すべてのエリアのセルを合計する(重なりは二重に数える)ことを忘れないようにしましょう。

Union と Intersect:まとめる vs 重なり

UnionIntersect は、範囲に対する 2 つの集合演算子で、正反対です。 Union(A, B) は A または B のどちらかにあるすべて — 合わさった領域 — を返します。 Intersect(A, B)両方にあるものだけ — 重なり、触れ合わなければ Nothing — を返します。 Union は参照を大きくし、Intersect は共有部分へ小さくします。散らばったセルを 1 つのバッチに 組み立てるには Union判定したり制限したりするには Intersect に手を伸ばしましょう — 最も有名なのは「ユーザーは、私が気にかける範囲の中のセルを編集したか?」を尋ねる用途です。

ExcelMaster の活用

Union は見かけによらず単純ではありません。蓄積のガードは最初の反復で忘れやすく、.Count の 二重数えはあらゆる集計を静かに壊し、「同じシートのみ」は予期しない 1004 として現れます。 どれも、それを引き起こす正確な入力が来るまで表に出ません。

ExcelMaster なら、代わりに結果を 述べるだけで済みます。「残高がマイナスの行をすべて強調して」や「A 列の空白行をすべて削除して」 と言えば、ループを書き、最初の一致で参照を種づけし、Union で広げ、グループ全体へ 1 回の操作を 行います — Nothing クラッシュもセルごとの遅延もない、速くてガード付きの版です。ブックも コードもあなたの手元に残り、ループがシートに 1 万回触れた、あの一巡を飛ばせます。

よくある質問

Excel VBA の Union メソッドは何をしますか?

Union は、2 つ以上の範囲を、それらがたとえ隣り合っていなくても、すべてを覆う1 つの参照に まとめます。そのあと、すべてのブロックを 1 回の操作で色づけ・消去・コピー・削除できます。 シート上の複数のエリアを Ctrl クリックして 1 つの選択として扱うことの、コード版です。

VBA の Union は重複したセルを取り除きますか?

いいえ。Union は重複を除かずに範囲を連結するので、複数の引数に現れるセルは二重に 数えられます。Union(Range("A1:A5"), Range("A3:A8")).Count は 8 ではなく 11 を返します。これは 参照を操作する分には無害ですが、数えたり合計したりするなら誤りです — Union は操作すべき セルを組み立てるために使い、別々の集合を計算するためには使わないでください。

なぜ Union はループの中でエラーを投げるのですか?

Union が少なくとも 2 つの実在する範囲を要求し、Nothing を拒否するからです。最初の反復では 蓄積用の変数がまだ Nothing なので、Union(rngAll, c) は失敗します。ガードしましょう。 If rngAll Is Nothing Then Set rngAll = c Else Set rngAll = Union(rngAll, c) — 最初の一致で 種づけし、あとは残りを union します。

Union は別々のワークシートの範囲を組み合わせられますか?

いいえ。Union に渡すすべての範囲は同じワークシート上になければなりません。シートを混ぜると error 1004 が発生します。シートをまたいで作業する必要があるなら、各シートごとに別々の union を 組み立てて処理しましょう。

VBA で Union と Intersect の違いは何ですか?

範囲に対する正反対の集合演算です。Union は、どちらか一方の範囲にあるすべて — 合わさった領域 — を返します。Intersect両方にあるものだけ — 重なり、触れ合わなければ Nothing — を返します。 散らばったセルを 1 つのバッチに組み立てるには Union、ある範囲が別の範囲の中に入るかを判定するには Intersect を使いましょう。

検証環境

検証環境: Excel 365 (Windows 11), VBA 7.1 — 最終確認 2026-08-16。

関連ガイド: VBA Intersect · VBA SpecialCells · VBA Range · VBA Cell Color · VBA For Loop