12

到目前为止,我对在类模块中使用 Let 属性的理解是您在类模块中设置它,如下所示:

Dim pName as String
Public Property Let Name(Value As String)
    pName = Value
End Property

然后你在你创建了这个类的一个对象之后,你可以像这样设置这个属性:

MyObject.Name = "Larry"



问题:是否有可能以某种方式将多个参数输入到类属性中?例如:

Dim pFirstName as String, pLastName as String
Public Property Let Name(FirstName As String, LastName As String)
    pFirstName = FirstName
    pLastName = LastName
End Property

然后,您将如何在课堂外设置此属性?

MyObject.Name = ??

或者这只是不可能做到的?

4

3 回答 3

19

我意识到已经有 2 种解决方法,但我认为回答你原来的问题值得一试,因为这个问题收到的浏览量很大。

答案

VBA 的 Let 属性中是否可以有多个参数?

是的!这是可能的。

首先让我们谈谈 GET 属性。考虑这是Class1

Private firstName as String
Private lastName as String

Public Property Get Name() As String
    Name = firstName & " " & lastName
End Property

Name属性将返回全名,这很好,但是如何使用该Let属性一次性分配firstName&lastName呢?

旁注:您可以传递一个用特殊字符分隔的单个字符串,并将其拆分在主体内Let并分配firstlast名称 ,但忘记了,让我们正确完成它......

好的,在 VBA 中Let,当前设置的默认属性将采用 1 个参数并将其分配给名字或姓氏......

就像是:

Public Property Let Name(value As String)
    firstName = value
End Property

规则:Get不带参数,Let只带一个。这是非常合乎逻辑的,因为它Get返回基础值,但Let需要从某个地方获取一个值以便将其分配给它所代表的数据。此时值得记住的是,该Let属性是通过=符号分配的,即。myObject.Name = "IdOnKnuu"

我们知道,如果我们与上述规则保持一致,理论上我们应该能够为the 添加一个参数,GetLet. 添加一个参数。

让我们忘记Let-现在将其注释掉- 并为属性添加一个参数Get

Private firstName As String
Private lastName As String

Public Property Get Name(first As String) As String
    Name = firstName & " " & lastName
End Property

'Public Property Let Name(value As String)
'    firstName = value
'End Property

回到Module1创建实例Class1并键入c.Name(

在此处输入图像描述

哦,智能感知期待什么?惊人的!

在这一点上,值得理解的是,我们的Get属性返回first + last 的都是空的,所以无论你要传递什么,c.Name()它都会返回一个空字符串。

好的,让我们现在取消注释并调整Let属性...

侧节点:如果您跳回Module1并键入c.并且没有得到智能感知,这几乎意味着其中的某些东西Class1被破坏了......我们已经知道 - 这Let是导致它的属性

我们已经为属性添加了一个参数Get,让我们对属性做同样的事情Let......

Public Property Let Name(first As String, value As String)
    firstName = value
End Property

让我们回到Module1并尝试使用该Let属性:

请记住,您之前是如何使用该Let物业的?您需要为其分配一个值

c.Name = "John"

但是现在,您的Let属性需要一个额外的参数first as String

我们为什么不试试这个:

c.Name("John") = "Smith"

嘿!编译并运行(快速F5

太好了,让我们检查一下结果!

Debug.print c.Name("John")

嗯...仅显示Smith在即时窗口(Ctrl+ G)中...不完全是我们想要的...。

回到Let属性,我们注意到我们通过参数获取了 2 个值,但我们只使用了其中一个?我们有两个不同的值进入函数,对吧?让我们将第一个视为 the firstName,将第二个视为lastName

Public Property Let Name(first As String, last As String)
    firstName = first
    lastName = last
End Property

回到Module1

Sub Main()

    Dim c As New Class1
    
    c.Name("John") = "Smith"

    Debug.Print c.Name("John")
    
End Sub

并重新运行当前代码为我们提供了我们需要的东西......它会打印John Smith请稍等!!!为什么我们必须通过名字才能检索全名

哈!诀窍是使两个属性的第一个参数Optional

总结一下,代码:

Class1.cls

Private firstName As String
Private lastName As String

Public Property Get Name(Optional first As String) As String
    Name = firstName & " " & lastName
End Property

Public Property Let Name(Optional first As String, last As String)
    firstName = first
    lastName = last
End Property

模块1.bas

Sub Main()

    Dim c As New Class1
    
    c.Name("John") = "Smith"

    Debug.Print c.Name ' prints John Smith
    
End Sub

所以基本上在 VBA 中可以通过属性分配两个(或更多)值。Let可能会让你有点失望的是它的语法,但我希望我在这个答案中的解释能帮助你理解事情的来源和原因。

Get属性有一个可选参数——它实际上只是一个虚拟参数……它没有在Get属性中的任何地方使用,但它允许我们获得所需的Let签名并允许我们将两个参数传递给它。它还授予易于记忆的c.Name语法。

通话

Debug.Print c.Name("first")

仍然是可能的,但是该"first"参数就像一个假人,对实际的基础数据没有影响。它是一个虚拟对象,对实际数据没有影响 - 转储它并使用:

Debug.print c.Name

绝对更方便:)

于 2014-10-21T13:40:51.073 回答
9

根据您的评论,如果您希望封装此逻辑,那么您可以使用类似于下面的内容。

下面包括子和功能。该函数返回一个 Person 对象:

Public Sub testing()

    Dim t As Person

    Set t = PersonData("John", "Smith")

End Sub


Public Function PersonData(firstName As String, lastName As String) As Person

    Dim p As New Person

    p.firstName = firstName
    p.lastName = lastName

    Set PersonData = p

End Function

人物类:

Dim pFirstName As String, pLastName As String

Public Property Let FirstName(FirstName As String)
    pFirstName = FirstName
End Property

Public Property Get FirstName() As String
    FirstName = pFirstName
End Property

Public Property Let LastName(LastName As String)
    pLastName = LastName
End Property

Public Property Get LastName() As String
    LastName = pLastName
End Property
于 2012-12-11T16:07:29.953 回答
3

在类中用作 Public Sub 过程来执行此操作:

Public Sub testing()
Dim myPerson As New Person
myPerson.SetName "KaciRee", "Software"

End Sub

人物类:

Dim pFirstName As String, pLastName As String

Public Property Let FirstName(FirstName As String)
    pFirstName = FirstName
End Property

Public Property Get FirstName() As String
    FirstName = pFirstName
End Property

Public Property Let LastName(LastName As String)
    pLastName = LastName
End Property

Public Property Get LastName() As String
    LastName = pLastName
End Property

Public Sub SetName(FirstName As String, LastName As String)
pFirstName = FirstName
pLastName = LastName
End Sub
于 2013-04-18T01:18:37.207 回答