エクセルVBAを使うならば、出来る限り結合セルは使いたくないですよね。
見栄えを優先してセルを結合している場合、並べ替えを行うとエラーになりますがどうしても結合セルを並べ替えする場合ありませんか?
その場合は、並べ替える前にまず結合セルを解除してから並べ替えを実行し、その後に結合すれば可能です。
セルの結合Merge・セル解除UnMergeメソッド
エクセルVBAでセルを結合するにはRangeオブジェクトのMergeメソッドを使います。
![波乗りアヒル](https://tripbowl.com/excel-vba/wp-content/uploads/2017/12/vba150x150.jpg)
ここでは、ユーザーフォームに配置したコマンドボタンにVBAコードを書き込む例をお話しします。
空欄セルを1か所結合・解除する
セルの範囲がA1:B1を結合します。
Private Sub CommandButton1_Click()
Range(“A1:B1”).Merge
End Sub
- コマンドボタン1が押されたら
- セル範囲A1:B1を結合する
- マクロ終了
結合されているセルの範囲がA1:B1を解除します。
Private Sub CommandButton2_Click()
Range(“A1:B1”).UnMerge
End Sub
- コマンドボタン2が押されたら
- セル範囲A1:B1を結合解除する
- マクロ終了
セルの結合時と違い、セルの解除は結合されていないセルを選択してもエラーにはならないので、A列全体(”A:A”)を指定しても大丈夫です。
値が入力済みのセルを1か所結合・解除する
先ほどと同じくセルの範囲がA1:B1を結合しますが、それぞれのセルに値(文字や数字)などが入力されていると、
「セルを結合すると、左上の値のみが保持され、他のセルの値は破棄されます。」
なんていうメッセージ出ますよね。
![](https://tripbowl.com/excel-vba/wp-content/uploads/2019/08/3b3f9d811effcde7c06b8f2787ea1d57.jpg)
初めてならばいいのですが、毎度の作業で見慣れてくると邪魔に感じるので、セルの結合時に表示される確認メッセージが出ないようにVBAコードを付け加えましょう。
Private Sub CommandButton1_Click()
Application.DisplayAlerts = False
Range(“A1:B1”).Merge
Application.DisplayAlerts = True
End Sub
- コマンドボタン1が押されたら
- 確認のメッセージを非表示にする
- セル範囲A1:B1を結合する
- 確認のメッセージを表示するに戻す
- マクロ終了
結合されているセルの範囲がA1:B1を解除する方法は、空欄セルの解除の時と一緒です。
指定したセル範囲を行単位で結合する
セルを結合したい場所が複数ある場合に(”A1:B1″)(“A2:B2”)(“A3:B3”)・・・とVBAコードを書き続けるのは面倒なので、RangeオブジェクトのMergeメソッドの引数「Across」を”True”にすると指定した範囲を行単位で結合してくれます。
Private Sub CommandButton1_Click()
Range(“A1:B3”).Merge True
End Sub
- コマンドボタン1が押されたら
- セル範囲A1:B3を行単位で結合する
- マクロ終了
Trueを付け加えただけなので簡単で、一応Trueの代わりにFalseまたは省略すると指定した全ての範囲を結合しますので、最初の空欄セル結合と一緒なのです。
セルの結合の実用例
ここまでは基本的なVBAコードを使ったセルの結合と解除をお話ししましたが、実際にMergeメソッドを使うには、エクセル自体が判断して自動的に結合と解除をやってもらわなくては作業効率化にはなりません。
同じ内容のセルを結合する
支店ごとにセルを結合したり顧客名簿の「あいうえお順」などの見出しを結合などを、コマンドボタン1回押すだけで自動的にエクセルが作業してくれるので一瞬で仕事が片付きますよ。
ここではA列の同じ支店名が並んだ時に自動的にセルを結合させることを書いてみました。
Private Sub CommandButton1_Click()
Application.ScreenUpdating = False
Dim i As Integer, j As Integer
Application.DisplayAlerts = False
i = 3
Do Until Cells(i, “A”).Value = “”
j = 1
Do While Cells(i, “A”).Value = Cells(i + j, “A”).Value
j = j + 1
Loop
Range(Cells(i, “A”), Cells(i + j – 1, “A”)).Merge
i = i + j
Loop
Application.DisplayAlerts = True
Application.ScreenUpdating = Ture
End Sub
- コマンドボタン1が押されたら
- 画面更新停止して処理を速くする
- 整数型の変数iとjを宣言
- 確認メッセージを非表示にする
- データが3行目から入力されているので「3」とする
- A列のi行目の値が空白になるまで繰り返し処理を始める
- 1行下のセルの値を見るので「1」とする
- A列のi行目とi+j行目の値が同じ場合はjに1を加えて調べ続ける
- 同じ値だった行を結合する
- この作業をくり返す
- 確認のメッセージを表示に戻す
- マクロ終了
これでA列の支店名が同じ時はこのように結合されました。
ちなみに、A列と同じことをD列でも一緒に行うならば、Application.DisplayAlertsで挟まれた部分のVBAコードを続けて並べれば可能です。
![波乗りアヒル](https://tripbowl.com/excel-vba/wp-content/uploads/2017/12/vba150x150.jpg)
また、同じ内容のセルを結合するには下記コードでも可能です。
Private Sub CommandButton1_Click()
Application.ScreenUpdating = False
Dim i As Range, j As Long
Set i = Range(“A1”)
For j = 1 To Cells(Rows.Count, 1).End(xlUp).row
With Cells(j, 1)
If .Value = .Offset(1, 0).Value Then
Set i = Union(i, .Offset(1, 0))
Else
Application.DisplayAlerts = False
i.Merge
Application.DisplayAlerts = True
Set myRange = .Offset(1, 0)
End If
End With
Next
Application.ScreenUpdating = Ture
End Sub
- コマンドボタン1が押されたら
- 画面更新停止して処理を速くする
- データ型(Range)の変数iと整数型(Long)の変数jを宣言する
- 変数iにはA1セルを格納
- 変数jには最終行を格納
- 一緒にセル(j,1)
- もし1行下のセルの値が同じでない時は何もせず
- 確認メッセージを非表示にする
- 同じ値のセルを結合する
- 確認メッセージを表示するに戻す
- 1行下のセルの処理を繰り返す
- Ifステートメント終了
- withステートメント終了
- 繰り返す
- 画面更新再開に戻す
- マクロ終了
結合セルに連番を自動付与する
データが入力されると自動的に連番を付与していて、セルの結合などで連番が変わってしまうので、セル結合後に再度番号を付与させる方法です。
Private Sub CommandButton1_Click()
Application.ScreenUpdating = False
Dim i As Integer, myRange As Range
Set myRange = Range(“A2”)
For i = 1 To 5
Set myRange = myRange.Offset(1).MergeArea
myRange.Value = i
Next i
Set myRange = Nothing
Application.ScreenUpdating = Ture
End Sub
- コマンドボタン1が押されたら
- 画面更新停止して処理を速くする
- 変数iとデータ型(Range)の変数myRangeを宣言する
- 変数myRangeに自動連番開始セルとなる「A2」をあてる
- 1から5の連番を付与する為にFor~Nextステートメントで繰り返し処理を開始する
- 変数myRangeの1行下の結合セルに1つずつ移動する
- 変数myRangeの値は連番の変数iにする
- 指定した5まで繰り返す
- メモリ解放
- マクロ終了
この結合セルに自動連番を付与するVBAコードを単独で使用したことはありません。
上記の「同じ内容のセルを結合する」VBAコードに追加記述して、一括で処理する時に時々使っています。
理由は簡単で、セルを結合してから連番を付与するのではなく、単純に指定したセルに連番を付与するだけのVBAコードだからです。
指定範囲のセルの結合・解除を自動判別して行う
簡単に例えるとスイッチのON・OFFみたいなもので、セルが結合されている時にコマンドボタンを押すと結合セルが解除され、解除されている時に押すと結合するというものです。
Private Sub CommandButton1_Click()
If Range(“A3”).MergeCells Then
Range(“A3”).MergeCells = False
Else
Range(“A3:A72”).MergeCells = True
End If
End Sub
- コマンドボタン1が押されたら
- セルA3が結合されている場合
- セルA3を含む結合セルを解除する
- そうでない場合(解除されている時)
- セルA3~A72まで結合する
- マクロ終了
とてもシンプルなVBAコードですが、このままだと画面更新停止処理も確認メッセージの扱いも入れていませんので、画面があちこち移動したり、メッセージが出たりするので、実際使う時はそれぞれのVBAコード忘れずに入れておいてくださいね。
結合セルを解除して各セルに同じ値を入れる
結合セルを解除すると最初のセルにだけ値が入力されますが、残りの解除されたセルは空欄のままで、罫線も消えてしまいます。
リストを結合前の元通りにするイメージで、結合セルを解除と同時に各セルに結合前と同じ値を入力して罫線も付けるようにVBAコードを書いて使っています。
Private Sub CommandButton2_Click()
Application.ScreenUpdating = False
Range(“A:A,D:D”).UnMerge
Dim i As Integer
For i = 3 To 145
Cells(i, 1).Value = Cells(i, 27).Value
Cells(i, 4).Value = Cells(i, 30).Value
Next
Range(“A2:F72,A75:F145”).Borders.LineStyle = xlContinuous
Range(“A2:D72,A75:D145,D2:F72,D75:F145”).BorderAround Weight:=xlMedium
Application.ScreenUpdating = Ture
End Sub
- コマンドボタン2が押されたら
- 画面更新停止して処理を速くする
- セルA列、D列をそれぞれ結合解除する
- 整数型の変数iを宣言する
- 変数iは3~145とする
- セルi行目の1列目(セルA3)の値はセルi行目の27列目(セルAA3)の値を入力
- セルi行目の4列目(セルD3)の値はセルi行目の30列目(セルAD3)の値を入力
- 変数Iの145行目まで処理を繰り返す
- セルA2~F72とA75~F145に罫線を実践で引く
- セルA2:D72とA75:D145とD2:F72とD75:F145に外枠を中太線で引く
- 画面更新再開に戻す
- マクロ終了
これはあらかじめ、リストアップされたリストをAA列から順に用意しておいて、ここからA列から順に映して表にしています。
この他にも最終行に関して活用できると作業効率化できますよ。
- 入力済み最終行を取得する
- 入力済み最終行の下に新しく入力する
- 入力済み最終行を探して同じ行の複数セルの値を一括取得する
- 入力済み最終行まで同じ値のセルを結合・解除する
- 入力済み最終行まで不要な行を非表示にする
![波乗りアヒル](https://tripbowl.com/excel-vba/wp-content/uploads/2017/12/vba150x150.jpg)