Windows 10 Pro_x64 + Excel2013_x86 VBA で Dictionary を辞書順にソートする
Windows 10 Pro_x64 + Excel2013_x86 VBA で Dictionary を辞書順にソートする
基本的に、AarrayList を参照後、keyを突っ込んで sort することが多いんだけど
参照に制限が付いた気がするので、Dictionaryで代用できるようにする
※.Net Library 3.5 まで参照可ってソースが見つからない
※ソートはMSのサイトにあった気がするんだが、消えているんだよなぁ・・・
参考にしたのは以下のサイト
VBAでDictionary(連想配列)を辞書順にソートする
・Option Explicit が通るコードに修正
・可変長配列の切り方を修正
・その他、自分なりのコメントを追加
・UserFormを1個追加する
・CommandButtonを1個追加する
・2次元の文字型の配列で動作することも確認する
※For Each key In dic -> Doc.Keys で取る必要はなかったのか・・・
Option Explicit Private Sub CommandButton1_Click() ' Dim key As Variant Dim dic As Object Dim output As String ' Set dic = CreateObject("Scripting.Dictionary") ' dic("g") = "gggg" dic("9") = "999" dic("を") = "をををを" dic("4") = "444" dic("あ") = "ああああ" dic("(") = "((((" dic("a") = "aaaa" ' output = "##before" & vbNewLine For Each key In dic output = output & key & ":" & dic(key) & vbNewLine Next key ' Call DicSort(dic) ' output = output + "##after" & vbNewLine For Each key In dic output = output & key & ":" & dic(key) & vbNewLine Next key ' MsgBox output ' ' 文字型の2次元配列のソート ' Dim typArry(3, 1) As String Dim i As Integer ' ' 配列の添え字の最小値は0 ' typArry(0, 0)~typArry(3, 1) ' typArry(0, 0) = "01" typArry(0, 1) = "北海道" typArry(1, 0) = "02" typArry(1, 1) = "青森県" typArry(2, 0) = "03" typArry(2, 1) = "岩手県" typArry(3, 0) = "01" typArry(3, 1) = "北海道" ' Call QuickSort(typArry, LBound(typArry), UBound(typArry)) ' For i = LBound(typArry) To UBound(typArry) Debug.Print typArry(i, 0), typArry(i, 1) Next ' End Sub '================================================================= ' 名 称 : DicSort ' 機 能 : 引数のDictionaryをソートする破壊的プロシージャ ' パラメータ : Dictionary '================================================================= Sub DicSort(ByRef dic As Scripting.Dictionary) ' Dim key As Variant Dim varTmp() As String Dim dicSize As Long Dim lngCnt As Long ' dicSize = dic.count ' ' QuickSort関数 で varTmp(Int(i + j / 2))との比較が発生する ' ため配列のサイズは dicSize * 2 とする ' ReDim varTmp(dicSize * 2, 2) ' ' Dictionaryが空か、サイズが1以下であればソート不要 ' If dic Is Nothing Or dicSize < 2 Then Exit Sub End If ' ' Dictionaryから二元配列に転写 ' lngCnt = 0 For Each key In dic varTmp(lngCnt, 0) = key varTmp(lngCnt, 1) = dic(key) lngCnt = lngCnt + 1 Next ' ' クイックソート ' Call QuickSort(varTmp, 0, dicSize - 1) ' dic.RemoveAll ' For lngCnt = 0 To dicSize - 1 dic(varTmp(lngCnt, 0)) = varTmp(lngCnt, 1) Next ' End Sub '================================================================= ' 名 称 : QuickSort ' 機 能 : String型の二次元配列を受け取り ' :これの一列目でクイックソートする ' パラメータ : targetVar() : 二次元配列 ' : min, max : ソート対象 '================================================================= Private Sub QuickSort(ByRef targetVar() As String, ByVal min As Long, ByVal max As Long) ' Dim i, j As Long Dim tmp As String Dim pivot As String If min < max Then i = min j = max pivot = Med3(targetVar(i, 0), targetVar(Int(i + j / 2), 0), targetVar(j, 0)) Do Do While StrComp(targetVar(i, 0), pivot) < 0 i = i + 1 Loop Do While StrComp(pivot, targetVar(j, 0)) < 0 j = j - 1 Loop If i >= j Then Exit Do tmp = targetVar(i, 0) targetVar(i, 0) = targetVar(j, 0) targetVar(j, 0) = tmp tmp = targetVar(i, 1) targetVar(i, 1) = targetVar(j, 1) targetVar(j, 1) = tmp i = i + 1 j = j - 1 Loop Call QuickSort(targetVar, min, i - 1) Call QuickSort(targetVar, j + 1, max) End If End Sub '================================================================= ' 名 称 : Med3 ' 機 能 : String型のx, y, z を辞書順比較し二番目のものを返す '================================================================= Private Function Med3(ByVal x As String, ByVal y As String, ByVal z As String) As String ' If StrComp(x, y) < 0 Then If StrComp(y, z) < 0 Then Med3 = y ElseIf StrComp(z, x) < 0 Then Med3 = x Else Med3 = z End If Else If StrComp(z, y) < 0 Then Med3 = y ElseIf StrComp(x, z) < 0 Then Med3 = x Else Med3 = z End If End If End Function