[VBA][HowTo][Dictionary][Sort]連想配列をソートするやり方

VBAのDictionaryオブジェクトにソート機能があったらさらに使い勝手のいいオブジェクトになるんだけどなぁ~…と考えたことが何度あったことか。

実はVBAのDictionaryオブジェクトはソート機能をサポートしていません。

その事実を踏まえた上で、如何にしてソートさせていくかの方法論のひとつを紹介していきたいと思います。

やり方はいくつか考えられるのですが、その中で比較的簡単なロジックで作成可能なソート方法の紹介です。

ご興味のある方は続きをお読み下さい。


Excelのソート機能を活用した連想配列のソート

Sub Sample()
Dim oDic As Dictionary
Dim oDic_Sort As Dictionary
Dim i As Integer

    Set oDic = New Dictionary
    Set oDic_Sort = New Dictionary
    
    oDic.Add "CCC", 100
    oDic.Add "EEE", 200
    oDic.Add "AAA", 300
    oDic.Add "DDD", 400
    oDic.Add "BBB", 500
       
    For i = 0 To oDic.Count - 1
        Debug.Print oDic.Keys(i) & ":::" & oDic.Items(i)
    Next
    
    Debug.Print "================================="
    
    Set oDic_Sort = Dictionary_Sort(oDic, "KEY", xlAscending)
        
    For i = 0 To oDic_Sort.Count - 1
        Debug.Print oDic_Sort.Keys(i) & ":::" & oDic_Sort.Items(i)
    Next
            
    Set oDic = Nothing
    Set oDic_Sort = Nothing
    
End Sub

Function Dictionary_Sort(oDic As Dictionary, Optional SortTarget As String = "KEY", Optional Order As XlSortOrder = xlAscending) As Dictionary
Dim oRange As Range
Dim arrSort As Variant
Dim i As Integer

    Set Dictionary_Sort = New Dictionary
       
    With Worksheets("Sheet1") 'Temporary Sheet
        
        .Cells.ClearContents
        
        .Range("A1").Resize(oDic.Count) = WorksheetFunction.Transpose(oDic.Keys)
        .Range("B1").Resize(oDic.Count) = WorksheetFunction.Transpose(oDic.Items)
        
        Set oRange = .Range("A1:B" & oDic.Count)
        
        Select Case UCase(SortTarget)
            Case "KEY"
                oRange.Sort oRange(1, 1), Order
            Case "ITEM"
                oRange.Sort oRange(1, 2), Order
        End Select
        
        arrSort = oRange.Value
        
        oRange.ClearContents
        
        Set oRange = Nothing
                
    End With
    
    For i = LBound(arrSort) To UBound(arrSort)
        Dictionary_Sort.Add arrSort(i, 1), oDic.Item(arrSort(i, 1))
    Next
    
End Function

今回の連想配列ソートのロジック解説

Excelを使っています。

簡単に処理の流れを紹介します。

まずソートする対象のDictionaryを作成。

内容をイミディエイトウィンドウへ出力。

Dictionary_Sort 関数の引数として作成したDictionaryとソート条件を渡す。

受け取ったDictionary_Sort 関数内で具体的にDictionaryの内容をソート。

並び変わったDictionaryを返り値として返す。

ソート後の内容をイミディエイトウィンドウへ出力。

処理の流れの紹介は以上です。

今回はFuctionとして作成したDictionary_Sort 関数がソートの処理を担っています。

Dictionary_Sort 関数の補足

Dictionaryとソート条件を渡してソート後のDictionaryを返す関数ですが、ソートのメインはExcelの機能を活用しています。

Excelのソート機能を使用するためにDictionaryのデータをシートへ流し込みます。

データの流し込みにはワークシート関数「Transpose」を使っています。

A列:キー
B列:値

        .Range("A1").Resize(oDic.Count) = WorksheetFunction.Transpose(oDic.Keys)
        .Range("B1").Resize(oDic.Count) = WorksheetFunction.Transpose(oDic.Items)

そして実際のソートの部分が以下の箇所。

        Select Case UCase(SortTarget)
            Case "KEY"
                oRange.Sort oRange(1, 1), Order
            Case "ITEM"
                oRange.Sort oRange(1, 2), Order
        End Select

Excelのソート機能はソートの基準列と昇順降順を設定することが出来るので、今回はDictionaryのキーを昇順ソートする処理としましたが、関数の引数でカスタマイズが可能です。

  • oDic(オブジェクト):Dictionary
  • SortTarget(ソート基準):KEY or ITEM
  • Order(並び替え):xlAscending or xlDescending

連想配列のソートのまとめ

さて、今回はVBAの連想配列であるDictionaryをソートする方法をご紹介させて頂きましたが、いかがでしたでしょうか。

ソートのロジックをごりごり書いたり、その他に別の方法もあるにはありますが、Excel機能の処理能力もかなり高速ですので、扱うデータ量と処理速度を基準に検討してみてもありかもしれません。

Dictionaryのソートの別のやり方についても今後取り上げてみたいと思います。