TL;DR:
Есть ли способ передать коллекцию/список классов алгоритму сортировки библиотеки и заставить его возвращать отсортированный список (предпочтительно с помощью именованного свойства класса/класса по умолчанию)?
Недавно я немного изучил Python и был впечатлен функцией Sorted()
, которая может сортировать любой итерируемый объект. Для чисел это просто, однако для классов можно назначить метод сравнения подобно этому. Метод сообщает операторам сравнения, как сравнивать 2 экземпляра класса. Помимо прочего, он позволяет использовать встроенные алгоритмы сортировки для сортировки коллекции класса.
В VBA мне наполовину удалось имитировать это. Установив для класса член по умолчанию Attribute
, вы можете использовать операторы сравнения (<
,=
,>=
и т. д.) непосредственно на занятиях. Возьмите пример класса:
VERSION 1.0 CLASS
BEGIN
MultiUse = -1 'True
END
Attribute VB_Name = "defaultProp"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Private randVal As Single
Public Property Get DefaultValue() As Single
Attribute Value.VB_UserMemId = 0
DefaultValue = randVal
End Property
Private Property Let DefaultValue(ByVal value As Single)
randVal = value
End Property
Private Sub Class_Initialize()
DefaultValue = Rnd()
End Sub
Можно сравнить два экземпляра этого класса:
Dim instance1 As New defaultProp
Dim instance2 As New defaultProp
Debug.Print instance1.DefaultValue > instance2.DefaultValue
Debug.Print instance1 > instance2 'exactly equivalent, as the DefaultValue has the correct Attribute
И если бы я реализовал алгоритм сортировки VBA, который может сортировать значения, не должно быть проблем с сортировкой классов по значению по умолчанию*. Однако я бы предпочел использовать встроенный/библиотечный алгоритм сортировки (по тем же причинам, что и любой: ясность, эффективность, правильная обработка ошибок и т. д.).
*Один из этих алгоритмов работать для этого, хотя его необходимо изменить, чтобы переключить весь раунд класса, а не его значение (путем добавления Set
s)
Поскольку у операторов сравнения VBA нет проблем, я предположил, что то же самое будет верно для всего, что использует библиотека. Однако, когда я попытался использовать ArrayList :
Sub testArrayList()
Dim arr As Object
Set arr = CreateObject("System.Collections.ArrayList")
' Initialise the ArrayList, for instance by generating random values
Dim i As Long
Dim v As defaultProp
For i = 1 To 5
Set v = New defaultProp
arr.Add v 'no problem here
Next i
arr.Sort 'raises an error
End Sub
я получаю сообщение об ошибке
Не удалось сравнить два элемента в массиве
Так что же происходит? Является ли это недостатком моего подхода — атрибут по умолчанию не попадает в ArrayList
? Или, может быть, оператор сравнения на любом языке, на котором написана библиотека, не такой тупой, как те, которые используют VBA и Python? Любые предложения по использованию дополнительных встроенных алгоритмов сортировки также будут полезны!