Как использовать методы сравнения между объектными модулями класса в VBA аналогично VB.NET? - программирование
Подтвердить что ты не робот

Как использовать методы сравнения между объектными модулями класса в VBA аналогично VB.NET?

Из-за нового проекта в VBA я перешел с VB.NET, честно говоря, не знаю, как справляться между классами объектов здесь. То, что я хочу достичь, - это сравнение объектов между различными объектными модулями класса.

например

Сотрудник класса
      свойства: Name, Age
      точка: сравнить Name между двумя сотрудниками

классы: Сотрудник и Менеджер
точка: сравнить Name с Сотрудник с Name Менеджера

Я знаю, как это сделать в VB.NET, но как сравнить свойства разных объектов модуля класса в VBA?

4b9b3361

Ответ 1

VBA не поддерживает классовый полиморфизм, поэтому я рекомендую изменить то, как вы думаете о классах Employee и Manager.

Вы не можете иметь класс Employee в качестве базового класса, а затем отдельный класс Manager, который выводит из Employee. Они могут быть 2 отдельными классами, реализующими общий интерфейс.

Я расскажу об этом подробно. Теперь давайте рассмотрим несколько примеров...


↓ Простой подход ↓


A base class (Person) и дочерние классы, которые происходят из базового класса. (относится к С#, VB.NET и т.д.)

но в VBA вы должны думать об этом так:

Базовый класс, который предоставляет свойство enum, описывающее позицию.

Что-то вроде

enter image description here

enter image description here

Это самый простой способ иметь класс, отображающий некоторые свойства. Он позволяет добавлять объекты Person в коллекцию и перебирать их с помощью простого цикла for each с Intellisense!

enter image description here

Система сравнения свойств будет очень проста

enter image description here

note: то же самое относится к перечислению как его неявно преобразованное в число


↓ Более сложный подход ↓


Два отдельных класса, которые отображают публичные свойства. Например, у вас есть классы Employee и Manager, которые реализуют Person Интерфейс и дополнительный класс Comparer, подвергая метод Compare()

enter image description here

В вашем проекте VBA вам нужны 4 модуля классов и стандартный модуль

enter image description here

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() и проверьте результаты в окне немедленного просмотра

enter image description here

Лучшая часть приведенного выше кода заключается в том, что вы создаете ссылочную переменную интерфейса Person. Он позволяет прокручивать все элементы коллекции, которые реализуют интерфейс. Кроме того, вы можете использовать Intellisense, что отлично, если у вас было много других свойств и функций.


Сравнение


Посмотрите еще раз на код класса ComparerCls

enter image description here

Надеюсь, теперь вы видите, почему я разделил это как класс. Его цель - просто позаботиться о том, как сравниваются объекты. Вы можете указать порядок Enum и изменить метод Compare() для сравнения по-разному. Обратите внимание на необязательный параметр, который позволяет вам вызвать метод сравнения без метода сравнения.

enter image description here

Теперь вы можете играть вокруг передачи различных параметров функции сравнения. Посмотрите, как выглядят результаты.

Попробуйте комбинации:

emp.Name = "name"
man.Name = "name"

Comparer.Compare(emp, name, Names)
Comparer.Compare(emp, name, References)

Comparer.Compare(emp, emp, References)

Если что-то еще неясно, обратитесь к этому ответу о ключевом слове Implements в VBA