Sorting collections is something you might need to do. In this example, we’ll use the cMyClass object we created in Get Started Snippets to demonstrate sorting a collection of objects and how to use recursion to sort the object’s children, and entire family tree. As usual you can download this in the getting started workbook.
Creating a needSwap function.
If you want to sort a custom object, you should create two public functions. toString() which will return the value to use for sorting on, and needSwap() which will tell the sort function whether or not the current object is in the wrong position relative to the object it is being compared against. Here are these functions for our cMyClass object. These can be copied directly in to your class with only minor amendments. Public Function needSwap(cc As cMyClass, e As eSort) As Boolean
' this can be used from a sorting alogirthm
Select Case e
Case eSortAscending
needSwap = LCase(toString) > LCase(cc.toString)
Case eSortDescending
needSwap = LCase(toString) < LCase(cc.toString)
Case Else
needSwap = False
End Select
End Function
Public Function toString() As String
toString = pName
End Function
The sort Collection procedure
This is a very simple kind of bubble sort. Note that it calls the needSwap() function and the toString() function that you will have created in your class.
Option Explicit ' sort a collection Public Enum eSort eSortNone eSortAscending eSortDescending End Enum Function SortColl(ByRef coll As Collection, Optional eorder As Long = eSortAscending) As Long Dim ita As Long, itb As Long Dim va As Object, vb As Object, bSwap As Boolean Dim x As Object, y As Object For ita = 1 To coll.Count - 1 For itb = ita + 1 To coll.Count Set x = coll(ita) Set y = coll(itb) bSwap = x.needSwap(y, eorder) If bSwap Then With coll Set va = coll(ita) Set vb = coll(itb) .add va, x.toString , itb .add vb, y.toString , ita .Remove ita + 1 .Remove itb + 1 End With End If Next Next
Sorting the hierarchy
As discussed in Getting started with recursion , cycling through parents and children is straightforward. With this technique so is sorting the children within each parent. In this case we will sort in descending order. Here is the updated test to print out the tree structure, but also to sort it first.
Sub sortMe(mr As cMyClass) Dim mc As cMyClass SortColl mr.Children, eSortDescending For Each mc In mr.Children If mc.Children.Count > 0 Then sortMe mc Next mc End Sub Sub testChildrenRecurse() Dim mroot As cMyClass, mc As cMyClass Set mroot = New cMyClass With mroot .init 100, "bill" Set mc = New cMyClass .Children.add mc.init(202, "mary") Set mc = New cMyClass .Children.add mc.init(200, "janet") Set mc = New cMyClass .Children.add mc.init(201, "john") Set mc = New cMyClass .Children(2).Children.add mc.init(300, "tom") Set mc = New cMyClass .Children(2).Children.add mc.init(301, "fred") End With sortMe mroot printChildren mroot End Sub
Summary
There we have it. 2 normally rather complex concepts, recursion and sorting, made simple through the use of classes and collections. Comments and questions are welcome on our forum.