Из-за нового проекта в VBA я перешел с VB.NET, честно говоря, не знаю, как справляться между классами объектов здесь. То, что я хочу достичь, - это сравнение объектов между различными объектными модулями класса.
например
Сотрудник класса
свойства: Name
, Age
точка: сравнить Name
между двумя сотрудниками
классы: Сотрудник и Менеджер
точка: сравнить Name
с Сотрудник с Name
Менеджера
Я знаю, как это сделать в VB.NET, но как сравнить свойства разных объектов модуля класса в VBA?
VBA не поддерживает классовый полиморфизм, поэтому я рекомендую изменить то, как вы думаете о классах Employee
и Manager
.
Вы не можете иметь класс Employee
в качестве базового класса, а затем отдельный класс Manager
, который выводит из Employee
. Они могут быть 2 отдельными классами, реализующими общий интерфейс.
Я расскажу об этом подробно. Теперь давайте рассмотрим несколько примеров...
base
class (Person
) и дочерние классы, которые происходят из базового класса. (относится к С#, VB.NET и т.д.)
но в VBA вы должны думать об этом так:
Базовый класс, который предоставляет свойство enum, описывающее позицию.
Что-то вроде
Это самый простой способ иметь класс, отображающий некоторые свойства. Он позволяет добавлять объекты Person
в коллекцию и перебирать их с помощью простого цикла for each
с Intellisense!
Система сравнения свойств будет очень проста
note: то же самое относится к перечислению как его неявно преобразованное в число
Два отдельных класса, которые отображают публичные свойства. Например, у вас есть классы Employee
и Manager
, которые реализуют Person
Интерфейс и дополнительный класс Comparer
, подвергая метод Compare()
В вашем проекте VBA вам нужны 4 модуля классов и стандартный модуль
Person
(это ваш интерфейс)
Public Property Get Name() As String
End Property
Public Property Get Age() As Long
End Property
этот класс является интерфейсом, который оба типа Employee
и Manager
должны реализовать, чтобы совместно использовать некоторые общие функции (геттеры для имен и возрастов). Наличие интерфейса позволяет вам выполнять для каждого цикла использование переменной типа интерфейса в качестве счетчика. Вы увидите через минуту.
Employee
и Manager
идентичны. Очевидно, вы можете изменить их в соответствии с вашим решением в реальной жизни.
Implements Person
Private name_ As String
Private age_ As Long
Public Property Get Name() As String
Name = name_
End Property
Public Property Let Name(ByVal Value As String)
name_ = Value
End Property
Public Property Get Age() As Long
Age = age_
End Property
Public Property Let Age(ByVal Value As Long)
age_ = Value
End Property
Private Property Get Person_Name() As String
Person_Name = Name
End Property
Private Property Get Person_Age() As Long
Person_Age = Age
End Property
ComparerCls
вы будете использовать экземпляр этого класса для сравнения двух свойств или ссылок объектов. Для этого вам необязательно иметь класс, но я предпочитаю его таким образом.
Public Enum ComparisonMethod
Names = 0 ' default
Ages = 1
References = 2
End Enum
' makes names the default comparison method
Public Function Compare(ByRef obj1 As Person, _
ByRef obj2 As Person, _
Optional method As ComparisonMethod = 0) _
As Boolean
Select Case method
Case Ages
Compare = IIf(obj1.Age = obj2.Age, True, False)
Case References
Compare = IIf(obj1 Is obj2, True, False)
Case Else
Compare = IIf(obj1.Name = obj2.Name, True, False)
End Select
End Function
И ваш Module1
код
Option Explicit
Sub Main()
Dim emp As New Employee
emp.Name = "person"
emp.Age = 25
Dim man As New Manager
man.Name = "manager"
man.Age = 25
Dim People As New Collection
People.Add emp
People.Add man
Dim individual As Person
For Each individual In People
Debug.Print TypeName(individual), individual.Name, individual.Age
Next
End Sub
запустите подкомпоновку Main()
и проверьте результаты в окне немедленного просмотра
Лучшая часть приведенного выше кода заключается в том, что вы создаете ссылочную переменную интерфейса Person
. Он позволяет прокручивать все элементы коллекции, которые реализуют интерфейс. Кроме того, вы можете использовать Intellisense, что отлично, если у вас было много других свойств и функций.
Сравнение
Посмотрите еще раз на код класса ComparerCls
Надеюсь, теперь вы видите, почему я разделил это как класс. Его цель - просто позаботиться о том, как сравниваются объекты. Вы можете указать порядок Enum и изменить метод Compare()
для сравнения по-разному. Обратите внимание на необязательный параметр, который позволяет вам вызвать метод сравнения без метода сравнения.
Теперь вы можете играть вокруг передачи различных параметров функции сравнения. Посмотрите, как выглядят результаты.
Попробуйте комбинации:
emp.Name = "name"
man.Name = "name"
Comparer.Compare(emp, name, Names)
Comparer.Compare(emp, name, References)
Comparer.Compare(emp, emp, References)
Если что-то еще неясно, обратитесь к этому ответу о ключевом слове Implements
в VBA