配列のソート
配列のソート方法にはいろいろあります。
アルゴリズムとしてのソートにはクイックソートなどがあります。当サイトでも以下を紹介しています。
ただ、アルゴリズムとかの実装は面倒で、単にソートすればOKという場合もあります。
そういう場合の方法の1つに.NET FrameworkのArrayListクラスのSortメソッドがあります。
以下でSortメソッドの使い方を紹介します。Sortメソッドは昇順ソートのためReverseメソッドを使って降順にする方法も紹介しています。
ArrayListについては以下のMicrosoftのヘルプに各プロパティやメソッドが記載されています。
https://msdn.microsoft.com/ja-jp/library/system.collections.arraylist(v=vs.110).aspx
事前設定
.NET FrameworkのArrayListクラスを利用するために場合によっては参照設定が必要な場合があります。
VBA画面のツールメニュー→参照設定で以下の選択もしくは参照してください。
C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.tlb(dllではありません)
Microsoft Common Language Runtime Class Library
参照してもチェックが付かない場合がありますが、その場合は参照設定が不要ですので気にせず未設定で構いません。
ArrayListのSortメソッドによるソート関数
引数の配列をArrayListクラスのSortメソッドで昇順に並べ替えて、再度ToArrayメソッドで配列に戻す関数です。
条件として引数の配列は呼び出し元もVariant型の配列であることです。
型変換が必要な場合はソート後に呼び出し元で行うようにしてください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Sub ArrayListSort(ary() As Variant) Dim aryList As Object '// ArrayList Dim s '// 文字列 '// .NET FrameworkのArrayListクラスを利用する Set aryList = CreateObject("System.Collections.ArrayList") '// 配列をArrayListにコピー For Each s In ary Call aryList.Add(s) Next '// 並べ替え Call aryList.Sort '// 配列に再格納 ary = aryList.ToArray End Sub |
ArrayListのReverseメソッドによる反転関数
Sortメソッドは昇順です。
昇順ではなく降順にしたい場合は一度Sortメソッドで昇順に並べ替えたあとに、Reverse関数で反転させることで可能になります。
以下はその反転を行う関数です。SortだったのがReverseになっているだけです。
引数はSort時と同じでVariant型の配列になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Sub ArrayListReverse(ary() As Variant) Dim aryList As Object '// ArrayList Dim s '// 文字列 '// .NET FrameworkのArrayListクラスを利用する Set aryList = CreateObject("System.Collections.ArrayList") '// 配列をArrayListにコピー For Each s In ary Call aryList.Add(s) Next '// 並べ替え Call aryList.Reverse '// 配列に再格納 ary = aryList.ToArray End Sub |
使い方
上記のArrayListSort関数の使い方です。
Variant型の配列を用意し、各要素にデータを格納します。
あとはArrayListSort関数に渡すだけです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
Sub ArrayListSortTest() Dim ary() As Variant '// 文字列配列 Dim i Dim s ReDim ary(9) ary(0) = "444" ary(1) = "333" ary(2) = "000" ary(3) = "111" ary(4) = "555" ary(5) = "222" ary(6) = "666" ary(7) = "999" ary(8) = "888" ary(9) = "777" '// 昇順ソート Call ArrayListSort(ary) '// 反転 Call ArrayListReverse(ary) End Sub |
実行結果
20行目のSort直後の配列の並び
“000”
“111”
“222”
“333”
“444”
“555”
“666”
“777”
“888”
“999”
22行目のReverse直後の配列の並び
“999”
“888”
“777”
“666”
“555”
“444”
“333”
“222”
“111”
“000”
高速化
上記のSort用とReverse用の関数はそれぞれでCreateObject関数を実行しているため、何度も呼び出される場合にはそれが処理速度の低下になります。
何度も呼び出す場合はCreateObject関数を呼び出し元で1度だけ行うようにして、aryList変数を引数で渡すようにすると処理速度は向上します。
その際に注意点があります。
aryList変数を使いまわす場合に前回利用時の値をクリアする必要があります。
そのため、利用する直前に「Call aryList.Clear」と書いてデータクリアを行うようにしてください。
以下はCreateObject関数を呼び出し元で行うようにしたコードです。
処理は上のコードと同じですがCreateObject関数の呼び出しが1回になったこととArrayListクラスのaryList変数のクリアがSortとReverseを呼び出す度に行うようになっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
Sub ArrayListSortTestEx() Dim ary() As Variant '// 文字列配列 Dim aryList As Object '// ArrayList Dim i Dim s ReDim ary(9) ary(0) = "444" ary(1) = "333" ary(2) = "000" ary(3) = "111" ary(4) = "555" ary(5) = "222" ary(6) = "666" ary(7) = "999" ary(8) = "888" ary(9) = "777" '// .NET FrameworkのArrayListクラスを利用する Set aryList = CreateObject("System.Collections.ArrayList") '// 昇順ソート Call ArrayListSortEx(aryList, ary) '// 反転 Call ArrayListReverseEx(aryList, ary) End Sub Sub ArrayListSortEx(aryList As Object, ary() As Variant) Dim s '// 文字列 '// ArrayListをクリア Call aryList.Clear '// 配列をArrayListにコピー For Each s In ary Call aryList.Add(s) Next '// 並べ替え Call aryList.Sort '// 配列に再格納 ary = aryList.ToArray End Sub Sub ArrayListReverseEx(aryList As Object, ary() As Variant) Dim s '// 文字列 '// ArrayListをクリア Call aryList.Clear '// 配列をArrayListにコピー For Each s In ary Call aryList.Add(s) Next '// 並べ替え Call aryList.Reverse '// 配列に再格納 ary = aryList.ToArray End Sub |