和風スパゲティのレシピ

日本語でコーディングするExcelVBA

セルを結合・解除する - Merge/UnMerge

セルを結合・解除する方法を解説します。

RangeオブジェクトのMerge/UnMergeメソッドを使用します。

セルを結合する

基本構文

結合したいセル範囲.Merge

サンプルコード

以下はすべてA1:C3セルを結合するコードです

Range("A1:C3").Merge
Range(Cells(1, 1), Cells(3, 3)).Merge
Range("A1").Resize(3, 3).Merge
Cells(1, 1).Resize(3, 3).Merge

解説

セル範囲.Mergeメソッドを実行すると、
そのセル範囲を結合することができます。

本家Excel上で実行した場合と違い、
セル内テキストの中央揃えは実行されません。


セル範囲の指定方法はいくつかありますが、
Resizeプロパティが便利に使えるパターンが多いので覚えておきましょう。

エラーパターン

Mergeメソッドを実行した際、エラーになるパターンとしては、
まず「結合範囲内に複数値があった場合」です。

この時は、Excelから実行したときと同様、
セル結合の警告
このメッセージが表示されます。


ここで「キャンセル」を押してしまうと、
「アプリケーションまたはオブジェクト定義のエラーです」
エラーが発生してしまいます。


これを防ぐには、以下のいずれかのコードで対応します。

' 複数値があっても警告を無視してセル結合を実行する場合
Application.DisplayAlerts = False
Range("A1:C3").Merge
Application.DisplayAlerts = True

' ユーザーがキャンセルを押した場合はセル結合を実行しない場合
On Error Resume Next
Range("A1:C3").Merge
On Error GoTo 0

状況に応じて使い分けてください。


その他のエラーパターンですが、Mergeメソッドはあまりエラーにならず、
ある程度無理矢理実行しても処理されてしまいます。

例えば、単独セルに実行しても何も起きないだけでエラーになりません。

Range("A1").Merge ' ← 実行可

 
続いて、Excel上では「一旦セル結合を解除」が実行される、
「既にセル結合された範囲を含むセル結合」も実行できます。

例えば、A1:B2がセル結合されている際も以下のコードは実行できます。

Range("A1:C3").Merge ' ← 実行可

 
それどころか、

  • A1:C3結合時にA1:B2を結合してもノーエラー(何も起きない)
  • A1:C1とA3:C3結合時にA1:C3を結合も可能
  • A1:C1結合時にA1:A3を結合すると合成されてA1:C3が結合セルに

と、何でもありの様相を呈しています。


エラーが起きないというのはいいことという訳ではなく、
意図しない実行をしても止まってくれないということでもあります。

Mergeはほぼエラーにならず実行されるというのは覚えておいてください。

セルを横方向に結合する

Excel上で「横方向に結合」
横方向に結合UI
を実行したときは、


以下のような結合を一気に実行できます。
結合前
     
結合後


この操作をVBAから実行する場合は、
Mergeメソッドの第2引数「Across」をTrueにします。

Range("A1:C3").Merge True
' または
Range("A1:C3").Merge Across:=True

 
Mergeメソッドの引数はこれひとつですので、
個人的には名前付き引数はなくても良いと思います。

ただ引数にTrueを渡すだけでこの処理ができるのは非常に便利なので、
この設定ができることは覚えておきましょう。

セル結合を解除する

セル結合を解除するにはUnMergeメソッドを実行します。

A1:C3セルが結合されているときに、
以下のいずれのコードでもこのセル結合を解除可能です。

Range("A1:C3").UnMerge
Range("A1").UnMerge ' 内部のセルならどこでもOK
Range("C3").UnMerge ' 同上
Range("A1:D4").UnMerge ' セル結合を含む大きな範囲でもOK
Range("1:1").UnMerge ' 交差する範囲指定でもOK
Range("A:A").UnMerge ' 同上

 
Mergeメソッドと同様、ほとんどエラーになることはなく、
割とどんな指定でも解除可能です。

範囲内に結合セルがなくてもエラーにはなりませんし、
単独セル.UnMergeも何も起きないだけでエラーにはなりません。

シート内のすべてのセル結合を解除

UnMergeメソッドは結合セルを複数含む大きな範囲から実行することで、
複数のセル結合を一括で解除することが可能です。

例えば特定のワークシートにあるすべてのセル結合を解除する場合は、
以下のコードを実行するだけでOKです。

Worksheets("○○").UsedRangeUnMerge

 

結合セルか判定する

対象のセル範囲が結合セルか判定するには、
MergeCellsプロパティを参照します。

A1:C3セルが結合されているときに、
以下のコードはいずれもTrueとして処理されます。

If Range("A1").MergeCells = True Then

If Range("C3").MergeCells = True Then

If Range("A1:C3").MergeCells = True Then

結合セル全体でも、内部のセルでもすべてTrueとなります。


ちなみにこのMergeCellsは意外にも読取専用プロパティではなく、
以下のコードのように代入してMerge/UnMergeをこなすこともできます。

' セル結合
Range("A1:C3").MergeCells = True

' セル結合の解除
Range("A1:C3").MergeCells = False

 
結合の仕様やエラーパターンなどもMerge/UnMergeと全く同じです。

わざわざこちらを使う必要はありませんが、
使われたコードを読む場面もあるかもしれないので覚えておきましょう。

結合セルのアドレス(位置・大きさ)を取得する

結合セルのアドレスを取得する場合は、
MergeAreaプロパティを参照します。

例えばA1:C3セルが結合されているときに、
MergeAreaプロパティは以下のような値になります。

' 結合アドレスを取得
MsgBox Range("A1").MergeArea.Address ' $A$1:$C$3
MsgBox Range("B2").MergeArea.Address ' $A$1:$C$3
MsgBox Range("C3").MergeArea.Address ' $A$1:$C$3
MsgBox Range("A1:C3").MergeArea.Address ' エラー

 
MergeAreaプロパティは今までのメソッドとは違い、
単独セルから実行しないと常にエラーとなります。

逆に単独セルであれば、結合内部であればどのセルからでも実行可能です。


さらには結合されていないセルからでも実行が可能で、
その場合は単独のセルが返ります。

MsgBox Range("A1").MergeArea.Address ' 結合されていなければ$A$1が返る

 
MergeAreaプロパティはRangeオブジェクトを取得しますので、
以下のようなコードも実行可能です。

MsgBox Range("A1").MergeArea.Rows.Count ' 結合セルの行数
MsgBox Range("A1").MergeArea.Columns.Count ' 結合セルの列数
MsgBox Range("A1").MergeArea.Cells.Count ' 結合セルの内部セル数

 
結合セルの範囲や大きさを調べる際は、
このようにMergeAreaプロパティを使用してください。

結合セルをFor Each文でループする

結合セルを含むセル範囲内のセルをForEach文で回す際は、
結合セルの内部セルは処理から除外する必要があります。

このとき「結合セル範囲の第1(左上)セル」か判定するには、
MergeCellsとMergeAeraを組み合わせた以下のコードを使用します。

Sub 結合内部セルを除くすべてのセルを処理()
    
    Dim セル範囲 As Range
    Set セル範囲 = Range("A1:E100")
    
    Dim 処理セル As Range
    For Each 処理セル In セル範囲.Cells
        
        If 処理セル.MergeCells = False _
        Or 処理セル.MergeArea.Cells(1).Address = 処理セル.Address Then
        
            ' ここに各セルへの処理
            
        End If
    Next
    
End Sub

 
MergeCellsがFalseの単独セルは処理を行い、
それ以外は「MergeAreaの第1セル」だけを処理するコード
です。


MergeAreaの第1セルはMergeArea.Cells(1)で取得できますので、
あとは処理セルとAddress同士を比較して第1セルかを判定しています。

結合セルが含まれる範囲をFor Each文でループする場合は、
こちらのコードを使用してください。


ちなみにMergeAreaは結合していないセルにも実行できるため、
実は上記のコードは「処理セル.MergeCells = False 」の判定はなくても動きます。


しかし、この仕様を熟知している方でないと、この判定がないコードは
パっと見「結合セルだけを処理している」ように見えてしまいます。

「単独セルも処理をしている」ことを明示するためにも、
「処理セル.MergeCells = False」はしっかり書いておきましょう。


この手の仕様が自明でないプロパティを扱う際は、
「漏れなくダブりなく」より「読みやすさ」が大事です。



以上でセル結合を実行/解除/判定するMerge関連の解説を終わります。

判定や範囲の取得をすると少々複雑なコードとなりますが、
Excel帳票の処理には重要なプロパティですのでしっかり修得しておきましょう。