0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【VBA】ソートの比較関数を切り替える

Last updated at Posted at 2025-06-14

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

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?