让 VBA 类模块的属性 - 是不是可以有多个参数? [复制]
Posted
技术标签:
【中文标题】让 VBA 类模块的属性 - 是不是可以有多个参数? [复制]【英文标题】:Let property of VBA class modules - is it possible to have multiple arguments? [duplicate]让 VBA 类模块的属性 - 是否可以有多个参数? [复制] 【发布时间】:2012-11-29 04:33:00 【问题描述】:到目前为止,我对在类模块中使用 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 = ??
或者这根本不可能做到?
【问题讨论】:
单个属性不能有两个参数,但可以使用数组。在这种情况下,最好使用像SetName(first,last)
这样的常规 Sub
谢谢。您确定可以使用数组吗?尝试时,我不断收到“无法分配给数组”错误。
@mattboy - 我已经添加到我的答案中,向您展示如何使用您需要的数据返回或更复杂的对象。
@TimWilliams take your comment back ;)
@vba4all - 总是乐于学习新事物...
【参考方案1】:
根据您的评论,如果您希望封装此逻辑,则可以使用类似于以下内容的内容。
下面包括子和函数。该函数返回一个 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
【讨论】:
谢谢,但我希望有一种方法可以在创建对象时将所有内容设置在一行中,而不是将一行用于名字,一行用于姓氏,其他行用于可能需要的任何其他内容。但我想你只需要创建一个 Sub 而不是 Property 就可以做到这一点。 查看我的编辑。我认为调用返回 Person 类而不是子类的函数更好。您对字段及其强类型具有智能感知。【参考方案2】:在类中用作 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
【讨论】:
【参考方案3】:我意识到已经有 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
的正文中,并分配 first
和 last
名称 但是忘记那个,让我们把它做好......
好的,在 VBA 中,当前设置的默认 Let
属性将采用 1 个参数并将其分配给名字或姓氏...
类似:
Public Property Let Name(value As String)
firstName = value
End Property
规则:Get
不带参数,Let
带一个。这是非常合乎逻辑的,因为 Get
返回基础值,但 Let
需要从 somewhere 获取一个值,以便将其分配给它所代表的数据。此时值得记住的是,Let
属性是通过=
符号分配的,即。 myObject.Name = "IdOnKnuu"
我们知道,如果我们与上述规则保持一致,理论上我们应该可以add one parameter to the Get
和one more to the Let
。
让我们忘记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
此时它们都是空的,所以你将传递给 @987654353 并不重要@ 它会返回一个空字符串。
好的,我们现在取消注释并调整 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 个值,但我们只使用了其中一个?我们有两个不同的值进入函数,对吧?让我们将第一个视为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
Module1.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
肯定更方便:)
【讨论】:
对于暴露数组也很有用。以上是关于让 VBA 类模块的属性 - 是不是可以有多个参数? [复制]的主要内容,如果未能解决你的问题,请参考以下文章