オートフィルターで2項目の並び替え

中級VBA

はじめに

 オートフィルターでは、各項目のソートが可能ですが、2つ以上を組み合わせた並べ替え(ソート)は、そのままではできません。
 2項目以上のシートを行いたい場合は、メニューから「メニュー」->「並べ替え」を選択し、レベル追加して並べ替えの項目を追加していく必要があります。

 ここでは、最初にExcel上の操作を解説し、次にVBAコードを紹介します。

Excel操作で2項目の並び替え

 以下のような表を、”メーカー名” でソートし、”メーカー名” ごとに “カテゴリー” でソートしてみます。

 まずは、表を選択して「データ」->「フィルター」で表をオートフィルターを適用します。

 ドロップダウンボタンが付いたので、最初に ”メーカー名” を昇順にします。

 次に、再度表を選択して、メニューの「データ」->「並べ替え」をクリックします。

 以下のダイアログが出るので、「レベルの追加」をクリックして2番目に優先されるキー項目を指定します。

 ここでは、2番目のキーを ”カテゴリー” にしました。

 OKボタンを押すと、以下のように “メーカー” から, “カテゴリー” のキーで並べ替えができました。

 ちなみに並べ替え自体は、オートフィルターを使用しなくても上記の「並べ替え」で実現可能です。
また、一項目のソートも「並べ替え」で設定できます。

ExcelVBAで2項目の並び替え

 次は、VBAで2項目の並び替えを書いてみましょう。といってもイチから覚えるより「マクロの記録」を使った方が簡単です。

Sub Macro1()
'
' Macro1 Macro
'

'   選択範囲にオートフィルターをセット
    Selection.AutoFilter
    'ソート情報をクリア
    ActiveWorkbook.Worksheets("Sheet3").AutoFilter.Sort.SortFields.Clear
    'C列を昇順にソート
    ActiveWorkbook.Worksheets("Sheet3").AutoFilter.Sort.SortFields.Add2 Key:= _
        Range("C2:C13"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
        xlSortNormal
    'D列を昇順にソート
    ActiveWorkbook.Worksheets("Sheet3").AutoFilter.Sort.SortFields.Add2 Key:= _
        Range("D2:D13"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:= _
        xlSortNormal
    'ソート情報をセットして実行
    With ActiveWorkbook.Worksheets("Sheet3").AutoFilter.Sort
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
End Sub

 上記のようなコードが出力されました。(注釈は筆者が記入しました。)ソートは以下のような手順で行われます。

・表の範囲指定
・ソート情報のクリア
・最初のソート情報を設定
・次のソート情報を設定
・ソート情報をセットして実行

汎用性のあるコード

 上記のコードでは、シートやRange指定、ソート・キーの指定などが固定されているので、別の表では利用できません。別のシートやソート・キーの指定が出来るように書き換えてみましょう。

Sub myFilter()
    Dim sh As Worksheet
    Dim rng As Range
    Dim startRow As Long, endRow As Long
    Dim sort1 As String, sort2 As String
    
    Set sh = ActiveWorkbook.Worksheets("Sheet3") '※

'   選択範囲にオートフィルターをセット
    Set rng = Range("A1").CurrentRegion '※
    
    '設定されている場合は解除する
    If ActiveSheet.AutoFilterMode = True Then
        Selection.AutoFilter
    End If
    
    rng.Select
    Selection.AutoFilter
    
    startRow = rng.Item(1).Row          '開始行
    endRow = rng.Item(rng.Count).Row    '最終行
    
    'ソート・キー(列)※
    sort1 = "C"
    sort2 = "D"
    
    'ソート情報をクリア
    sh.AutoFilter.Sort.SortFields.Clear
    
    'C列を昇順にソート
    sh.AutoFilter.Sort.SortFields.Add2 _
        Key:=Range(sort1 & startRow & ":" & sort1 & endRow), _
        SortOn:=xlSortOnValues, _
        Order:=xlAscending, _
        DataOption:=xlSortNormal
    'D列を昇順にソート
    sh.AutoFilter.Sort.SortFields.Add2 _
        Key:=Range(sort1 & startRow & ":" & sort1 & endRow), _
        SortOn:=xlSortOnValues, _
        Order:=xlAscending, _
        DataOption:=xlSortNormal
        
    'ソート情報をセットして実行
    With sh.AutoFilter.Sort
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
End Sub

 だいぶ長くなってしまいましたが、黄色の下線部分を変更すれば汎用的に利用できると思います。
青い下線部分は、オートフィルターが既に設定されている場合に解除します。これが無いとエラーとなる事があるためです。

 オートフィルターに関しては以下のページも参照してみてください。
オートフィルターの使い方

コメント

タイトルとURLをコピーしました