VBAで配列のソート用のプログラムを書いた場合、比較関数をソート内に含めてしまうと、ソートの方法を変えるたびにソート用の関数を書き直す必要が出てきます。
クラスモジュールを使うと、CallByName関数を使って文字列による関数の呼び出しが行えるため、呼び出し側から比較関数の切り替えを行うことができます。
まず、以下のようなソート用のクラスモジュールを準備します。
ClassQuickSort.cls
Option Explicit
'比較関数(昇順)
Function CompareFunc1(Item1 As String, Item2 As String) As Long
CompareFunc1 = StrComp(Item1, Item2)
End Function
'比較関数(降順)
Function CompareFunc2(Item1 As String, Item2 As String) As Long
CompareFunc2 = -StrComp(Item1, Item2)
End Function
'クイックソート実行用関数
'第4引数として比較関数を文字列で受け取る
Sub QuickSort(SortList() As String, ByVal L As Long, ByVal R As Long, SortCompareFunc As String)
Dim I As Long, J As Long
Dim P As String, T As String
Do
I = L
J = R
P = SortList((L + R) \ 2)
Do
'CallByName関数を使用し比較関数を文字列として指定
Do While CallByName(Me, SortCompareFunc, VbMethod, SortList(I), P) < 0
I = I + 1
Loop
Do While CallByName(Me, SortCompareFunc, VbMethod, SortList(J), P) > 0
J = J - 1
Loop
If I <= J Then
T = SortList(I)
SortList(I) = SortList(J)
SortList(J) = T
I = I + 1
J = J - 1
End If
Loop Until I > J
If L < J Then
QuickSort SortList, L, J, SortCompareFunc
End If
L = I
Loop Until I >= R
End Sub
'呼び出し用関数
Sub Sort(SortList() As String, SortCompareFunc As String)
QuickSort SortList, LBound(SortList), UBound(SortList), SortCompareFunc
End Sub
ソートを実行する場合は、Sort関数を呼び出しますが、実際のソート処理はQuickSort関数で行っています。
最初にある、 CompareFunc1関数と CompareFunc2関数が比較関数になります。
以下のような形で呼び出します。
Module1.bas
Option Explicit
Sub Sample1()
Dim cqs As New ClassQuickSort 'クイックソート用クラス
Dim List(4) As String '文字列リスト
Dim Index As Long
List(0) = "DOG"
List(1) = "CAT"
List(2) = "FISH"
List(3) = "MOUSE"
List(4) = "BIRD"
'Sort関数の呼び出し時に、比較関数を文字列で指定
cqs.Sort List, "CompareFunc1"
For Index = LBound(List) To UBound(List)
Debug.Print Index, List(Index)
Next
End Sub
実行結果
0 BIRD
1 CAT
2 DOG
3 FISH
4 MOUSE
Sort関数の引数を以下のように変更すると、比較関数が切り替わるため実行結果が変わります。
cqs.Sort List, "CompareFunc1"
↓
cqs.Sort List, "CompareFunc2"
実行結果
0 MOUSE
1 FISH
2 DOG
3 CAT
4 BIRD