24

由于 VBA 中的新项目,我从 VB.NET 迁移,老实说,我真的不知道如何处理这里的对象类。我想要达到的是比较不同类对象模块之间的对象。

例如

class Employee
     属性:NameAge
     点是:比较Name两个Employees之间的s

类:员工经理
点是:Name员工经理Name比较

我知道如何在 VB.NET 中使用,但是如何比较 VBA 中不同类模块对象的属性?

4

1 回答 1

81

VBA 不支持类多态,所以我建议改变你对EmployeeandManager类的思考方式。

您不能将一个Employee类作为基类,然后将一个单独的Manager. Employee它们可以是实现公共接口的2 个单独的类。

我稍后会详细讨论它。现在让我们来看几个例子......


↓ 简单的方法 ↓</h1>


一个base类 ( Person) 和从基类派生的子类。(适用于 C#、VB.NET 等

但在 VBA 中你必须这样想:

公开描述位置的枚举属性的基类。

就像是

在此处输入图像描述

在此处输入图像描述

这是让类公开一些属性的最简单方法。它允许您将对象添加到集合中并使用带有IntellisensePerson的简单循环进行迭代!for each

在此处输入图像描述

属性比较系统将非常容易

在此处输入图像描述

注意:同样适用于枚举,因为它隐式转换为数字


↓ 更复杂的方法 ↓</h1>

两个单独的类都公开公共属性。例如,您有一个EmployeeManager类,它们都实现了一个Person接口Comparer和一个公开Compare()方法的附加类

在此处输入图像描述

在您的 VBA 项目中,您需要 4 个类模块和一个标准模块

在此处输入图像描述

Person (这是你的界面)

Public Property Get Name() As String
End Property

Public Property Get Age() As Long
End Property

此类是两者都需要实现以共享一些通用功能(名称和年龄的getter)的Employee接口Manager。拥有接口允许您使用接口类型变量作为枚举器执行 for each 循环。你会在一分钟内看到

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类中的代码

在此处输入图像描述

我希望你现在明白为什么我把它分成一个类。它的目的只是照顾对象被比较的方式。您可以指定枚举顺序并修改Compare()方法本身以进行不同的比较。请注意 Optional 参数,它允许您在没有比较方法的情况下调用 Compare 方法。

在此处输入图像描述

现在您可以尝试将不同的参数传递给比较函数。看看结果如何。

尝试组合:

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

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

Comparer.Compare(emp, emp, References)

如果仍有不清楚的地方,请参阅这个关于ImplementsVBA 中关键字的答案

于 2013-11-11T14:09:37.323 回答