8/06/2021

Excel。VBA。結合セルのあるデータを結合セルで並べ替えるにはどうしたいい。【Merged cell】

Excel。VBA。結合セルのあるデータを結合セルで並べ替えるにはどうしたいい。

<Excel VBA>

Excelを、帳票のように使うのと、データベースのルールに基づいて使うのでは、Excelの機能を有効に使える使えないということがあります。

特にやりがちなのが、「セルの結合」。


例えば次の表で説明していきます。


A列は、A2:A5までセルの結合をされています。

このように、A列は、複数のデータをまとめてある状態です。


このようなセルの結合の帳票はよく見かけます。

見た目はいいのですが、店舗名を五十音順で並べ替えを行いたいとすると、メッセージが表示されて実行することができません。


店舗名で並べ替えをおこなうには、セルの結合を解除します。


解除すると空白セルになっているので、並べ替えを実行できないので、該当する店舗名を入力あるいは、コピーする作業をおこない、その後、店舗名を五十音順で並べ替えをしたあとに、再度、セルの結合を行うという、ハッキリいって、「やりたくない」作業ですね。


ただただ面倒。


そこで、Excel VBAでプログラムを作って処理をさせるのがいいかと思います。


そのExcel VBAのプログラム文です。

Sub セル結合解除()

    Dim i As Long

    Dim j As Long

    Dim start As Long

    Dim lastrow As Long

    

    Application.ScreenUpdating = False  '画面がひんぱんに切り替わるのを止める

    Application.DisplayAlerts = False   '確認メッセージを非表示にする

    

    lastrow = Cells(Rows.Count, "a").End(xlUp).Row

    

    For i = 2 To lastrow

        Cells(i, "a").UnMerge

    Next


    For i = 2 To lastrow

        If Cells(i + 1, "a") = "" Then

            If lastrow <= i + 1 Then

                Exit For

            Else

                Cells(i + 1, "a").Value = Cells(i, "a")

                Cells(i + 1, "a").SetPhonetic

            End If

        End If

    Next

    

    With Range("a1").CurrentRegion

        .Sort key1:="店舗名", order1:=xlAscending, Header:=xlYes

    End With

    

    lastrow = Cells(Rows.Count, "a").End(xlUp).Row

    j = 0

    start = 2

    

    For i = 2 To lastrow

        If Cells(i + 1, "a") = Cells(i, "a") Then

            j = j + 1

        Else

            Range(Cells(start, "a"), Cells(start + j, "a")).Merge

            start = i + 1

            j = 0

        End If

    Next

    

    Application.ScreenUpdating = True

    Application.DisplayAlerts = True

    

End Sub


ちょっと長いですが、実行してみましょう。


このように、店舗名はセルの結合をしてある状態で、五十音順で並べ替えが実行されています。


結合するセルの数が異なっていても、対応しています。


では、プログラム文を説明していきます。


お馴染みの変数宣言からです。使うところで、何に使用しているのか説明します。

Dim i As Long

Dim j As Long

Dim start As Long

Dim lastrow As Long


次の2行は、入れておくと便利な2行です。

Application.ScreenUpdating = False  '画面がひんぱんに切り替わるのを止める

Application.DisplayAlerts = False   '確認メッセージを非表示にする


Application.ScreenUpdating = False は、画面がひんぱんに切り替わるのを止めるとめもしてありますが、並べ替えを実行したり、空白のセルにデータをコピーしたりするので、この行を入れておきます。

Falseにすることで、作業が画面表示されないので、処理が早くなります。


Application.DisplayAlerts = False は、確認メッセージを非表示にする とメモをいれていますが、セルの結合を解除したり、セルの結合を再度行う時に、いちいちメッセージが表示され、ボタンを押さないと実行しないというのは、面倒なので、Falseを設定することで、メッセージを非表示にすることができます。


データの最終行番号を取得するのが次の行。

lastrow = Cells(Rows.Count, "a").End(xlUp).Row


この行番号まで繰り返し処理をさせます。


このFor To Next文は、セルの結合を解除させています。

For i = 2 To lastrow

    Cells(i, "a").UnMerge

Next

「UnMergeメソッド」でセルの結合を解除することができます。


2つ目のFor To Next文は、セルの結合を解除したあとの処理です。

For i = 2 To lastrow

    If Cells(i + 1, "a") = "" Then

        If lastrow <= i + 1 Then

            Exit For

        Else

           Cells(i + 1, "a").Value = Cells(i, "a")

            Cells(i + 1, "a").SetPhonetic

        End If

    End If

Next


やっている処理は、なんなのかというと、セルの結合を解除したので、セルの結合されていた一番上のセルにしかデータ(店舗名)がありません。


空白のセルに店舗名を入力(コピー)しています。

このあとに、五十音順に並べ替えをするのですが、入力文字情報が欠落しているので、フリガナ情報もいれています。


また、最終行ならば、For文を抜ける作業をさせています。


ちょっと細かく見ていきます。

次のセルの値が空白だったら、次の処理をします。


さらに、If文で条件分岐させています。

If Cells(i + 1, "a") = "" Then 

この文は、次のセルが空白かどうか、確認するための文です。


If lastrow <= i + 1 Then

    Exit For

Else

最終行ならば、「Exit For」。For文を抜けるという命令をしています。


Cells(i + 1, "a").Value = Cells(i, "a")

この文は、空白セルに、店舗名を入力する作業を行っています。


Cells(i + 1, "a").SetPhonetic

入力した店舗名には、フリガナ情報がないので、「SetPhoneticメソッド」で入力文字情報を追加しています。

この情報をいれないと、綺麗に五十音順で並べ替えを行うことができません。


With文は、店舗名を五十音順で並べ替えを行っています。

With Range("a1").CurrentRegion

    .Sort key1:="店舗名", order1:=xlAscending, Header:=xlYes

End With


A1から連続(CurrentRegion)している範囲を、店舗名を基準(key1)で、五十音順(昇順: xlAscending)とします。また、一行目を見出し行(Header:=xlYes)とするので、それを除き、並べ替える(Sort)ということをしています。


並べ替えが終わったので、再度、セルの結合を行います。


For i = 2 To lastrow

    If Cells(i + 1, "a") = Cells(i, "a") Then

        j = j + 1

    Else

        Range(Cells(start, "a"), Cells(start + j, "a")).Merge

        start = i + 1

        j = 0

    End If

Next


If文の真の処理は、次のセルのデータも同じだったら、結合するセル数をカウントしています。


偽の処理は、セルの接合の処理をしています。


startという変数は、セル結合の先頭の行番号をいれています。

その行番号に同じ店舗名の件数が代入している、変数Jを足したものを範囲として、セルの結合をしています。


このような流れで処理をすることで、セルの結合してあるデータの並べ替えを行ってみました。


本来は、データベースの考え方で、セルの結合は行わず、レコードとしてすべてのセルにデータを入力してほしいところですね。