雪ん子パースペクティヴ

読むとちょっとタメになるエントリー。コメントあると嬉しいです。

【VBA】任意のセルからセルまでを指定して結合させ、その処理を指定した任意のセルまで繰り返す。【Excel】

同じ作業は繰り返したいよね。

 

はろー、yukiです。

 

だから、vbaでマクロを組みます。

今回の内容は下記のとおりです。

ーーーーーーーーーーーーーー

  1. 結合する開始セルと選択
  2. 結合する終了セルを選択
  3. 結合の処理を任意のセル(行)まで繰り返す

ーーーーーーーーーーーーーー

 

まずは、処理の流れを画像で説明します。

1. マクロを設定したボタンをクリック

f:id:yuki_sasano:20190720233602p:plain

 

2. 結合する部分の開始セルを指定(繰り返し処理の開始セルにもあたる)

f:id:yuki_sasano:20190720233637p:plain



3. 結合する部分の終了セルを指定

f:id:yuki_sasano:20190720233708p:plain

 

4. 結合の処理を継続するセルを指定

f:id:yuki_sasano:20190720233757p:plain

 

5. セルに値があるため、結合の許可を確認

f:id:yuki_sasano:20190720233743p:plain

 

6. 許可した部分が結合され、次の部分の結合の許可を確認

f:id:yuki_sasano:20190720233855p:plain

 

7. 指定した全てのセルの結合が完了

f:id:yuki_sasano:20190720233957p:plain

 

 

 

さて、実際にVBAのコードを見てみましょう。

※すぐに使用したい方は、コードを全コピーしてください。


Sub セル結合()
'
' セル結合 Macro
'
' 任意のセルを選択し、任意のセルまでを結合する
' 結合の処理は、任意の選択したセルまでとする

' 変数を定義 Dim origin, endX, endY Dim originR, originC Dim endXR, endXC Dim endYR, endYC ' 開始セルを選択 On Error Resume Next Set origin = Application.InputBox( _ Prompt:="開始するセルを選択してください。", _ Type:=8) ' 選択したセルのアドレスを取得 origin = origin.Address(False, False) ' originのRowとColumnを取得 originR = Range(origin).Row originC = Range(origin).Column If Not IsEmpty(origin) Then ' 結合するセルを選択 On Error Resume Next Set endX = Application.InputBox( _ Prompt:="結合するセルを選択してください。", _ Type:=8) endX = endX.Address(False, False) endXR = Range(endX).Row endXC = Range(endX).Column If Not IsEmpty(endX) Then ' 繰り返しを終了するセルの選択 On Error Resume Next Set endY = Application.InputBox( _ Prompt:="処理を継続するセルを選択してください。", _ Type:=8) endY = endY.Address(False, False) endYR = Range(endY).Row endYC = Range(endY).Column ' 使用しない If Not IsEmpty(endY) Then ' 繰り返し処理 For i = originR To endYR ' 結合の処理 Range(origin & ":" & endX).Merge ' 開始セルと結合セルを下へ(行を)一つずつ移動 originR = originR + 1 endXR = endXR + 1 ' 変数を使用してセルを指定 origin = Cells(originR, originC).Address(False, False) endX = Cells(endXR, endXC).Address(False, False) Next Else MsgBox ("処理を中断します。") End If Else MsgBox ("処理を中断します。") End If Else MsgBox ("処理を中断します。") End If End Sub

 

 

 

それでは順番に見ていきましょう。

1. 変数の定義


    Dim origin, endX, endY ' 選択したセルのRange値を格納
    Dim originR, originC ' 変数originの行/列
    Dim endXR, endXC ' 変数endXの行/列
    Dim endYR, endYC ' 変数endYの行/列

originは開始セル、endXは結合の終了セル、endYは処理の継続終了セルです。

 

2. 開始セルの指定と、セルのアドレスを取得、RangeからCellsへ変換


    On Error Resume Next
    Set origin = Application.InputBox( _
        Prompt:="開始するセルを選択してください。", _
        Type:=8)
    
    ' 選択したセルのアドレスを取得
    origin = origin.Address(False, False)
    
    ' originのRowとColumnを取得
    originR = Range(origin).Row
    originC = Range(origin).Column

On Error Resume Nextで、エラー時にも処理を続行させています。

Application.InputBoxメソッドでは、Typeを8にし、参照したセル値を取得しています。

 ※参照: Application.InputBox メソッド (Excel) | Microsoft Docs

変数originには、Rangeオブジェクトが格納されます。

originRとoriginCは、後で使用するCellsオブジェクトの処理のため、行列値を格納。

 

3. 結合の終了セルの指定と、セルのアドレスを取得、RangeからCellsへ変換


    If Not IsEmpty(origin) Then
        ' 結合するセルを選択
        On Error Resume Next
        Set endX = Application.InputBox( _
            Prompt:="結合するセルを選択してください。", _
            Type:=8)
        
        endX = endX.Address(False, False)
        endXR = Range(endX).Row
        endXC = Range(endX).Column

If文を使用し、変数originの値が空でない場合、処理を継続させます。

変数endXは、結合セルの末を選択させるものとして用意します。

If文内の処理は項目2と同じです。

 

4. 繰り返し処理用セルの指定と、セルのアドレスを取得、RangeからCellsへ変換


    If Not IsEmpty(endX) Then
        ' 繰り返しを終了するセルの選択
        On Error Resume Next
        Set endY = Application.InputBox( _
            Prompt:="処理を継続するセルを選択してください。", _
            Type:=8)
   
        endY = endY.Address(False, False)
        endYR = Range(endY).Row
        endYC = Range(endY).Column ' 使用しない

変数endYは、継続した処理を終了させるセルを指定します。

なお、変数endYCは用意していますが、使用しません。継続の処理は、行ごとに実行されるためです。

 

5. セル結合、繰り返し処理


    If Not IsEmpty(endY) Then
        ' 繰り返し処理
        For i = originR To endYR
            ' 結合の処理
            Range(origin & ":" & endX).Merge

            ' 開始セルと結合セルを下へ(行を)一つずつ移動
            originR = originR + 1
            endXR = endXR + 1
                    
            ' 変数を使用してセルを指定
            origin = Cells(originR, originC).Address(False, False)
            endX = Cells(endXR, endXC).Address(False, False)
                
        Next

繰り返し処理は、開始セルの行から終了セルの行までを実行させます。
 ex.) 1行目から5行目までであれば、5回繰り返す

結合処理は、Range.Mergeメソッドを使用します(Rangeオブジェクトでのみ使用可)。

結合処理の後、繰り返しのため、直下のセルへ処理を移動させます。

ここで、Cellsオブジェクトで変換した変数xxxRが使用されます。

次の処理で結合させるセルを新たにAddressメソッドでRangeオブジェクトに置換。

ここで、Cellsオブジェクトで変換した変数xxxCが使用されます。

変数xxxC(列の値)はそのままにします。列は処理中に移動しません。

 

6. その他(変数の値を確認すること、ちょっと丁寧なIf文)


    Debug.Print (originR)

今回用意した変数は、セル参照ばかりですので、逐次どの部分を取得しているかを確認。

 


    Else
        MsgBox ("処理を中断します。")
    End If

セルが選択されなかった(ダイアログで[キャンセル]をクリックした)場合の処理です。

全ての処理を中断させます。

 

 

 

説明を終わります。

セル結合がRangeしかできないことと、RangeからCellsへの変換が少し面倒でした。

InputBoxを使用したのは、他者による運用を考慮し、丁寧にしたためです。

 

 

セル結合の繰り返しは出番が少ないかもしれませんが、GUI操作では骨が折れますね。

大量なGUI操作はあまり好きではないので、今回作ってみました。

継続の繰り返しはないが、結合したい部分がバラバラの時は、配列に格納が良いかも。

ちなみに、Mergeが使えるということは、Unmergeも使えるということです。

ぜひご活用ください。

 

 

以上。