mat*_*boy 11 oop vba properties class excel-vba
到目前为止,我对在类模块中使用Let属性的理解是你在类模块中设置它,如下所示:
Dim pName as String
Public Property Let Name(Value As String)
pName = Value
End Property
Run Code Online (Sandbox Code Playgroud)
然后,在您创建了此类的对象之后,您可以像这样设置此属性:
MyObject.Name = "Larry"
Run Code Online (Sandbox Code Playgroud)
问题:是否有可能以某种方式在类属性中输入多个参数?例如:
Dim pFirstName as String, pLastName as String
Public Property Let Name(FirstName As String, LastName As String)
pFirstName = FirstName
pLastName = LastName
End Property
Run Code Online (Sandbox Code Playgroud)
那你怎么去在课外设置这个属性呢?
MyObject.Name = ??
Run Code Online (Sandbox Code Playgroud)
或者这是不可能做到的?
小智 14
我意识到已经有2个解决方法,但我认为回答你原来的问题是值得的,因为这个问题收到了大量的意见.
答案
是否可以在VBA中的Let属性中包含多个参数?
是
首先让我们谈谈GET属性.考虑到这是Class1
Private firstName as String
Private lastName as String
Public Property Get Name() As String
Name = firstName & " " & lastName
End Property
Run Code Online (Sandbox Code Playgroud)
该Name属性将返回全名,这很好,但如何使用该Let属性分配firstName&lastName一次性?
旁注:你可以传递一个用特殊字符分隔的单个字符串,然后将其拆分到正文中,Let并分配first和last名称, 但忘记了,让我们正确地完成它...
好的,在VBA Let中,当前设置的默认属性将采用1个参数并将其分配给名字或姓氏......
就像是:
Public Property Let Name(value As String)
firstName = value
End Property
Run Code Online (Sandbox Code Playgroud)
规则:Get没有参数,Let需要一个参数.这是非常合乎逻辑的,因为Get返回基础值但Let需要从某处获取值以便将其分配给它所代表的数据.值得记住的是,该Let物业是通过=标志分配的.myObject.Name = "IdOnKnuu"
我们知道,如果我们留在上面的一致规律,从理论上我们应该能够一个参数添加到Get与一个多向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
Run Code Online (Sandbox Code Playgroud)
回到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
Run Code Online (Sandbox Code Playgroud)
让我们回到Module1并尝试使用该Let属性:
请记住,您以前如何使用该Let物业?你需要为它分配一个值
c.Name = "John"
Run Code Online (Sandbox Code Playgroud)
但是现在,你的Let财产正在期待一个额外的参数first as String.
我们为什么不这样做:
c.Name("John") = "Smith"
Run Code Online (Sandbox Code Playgroud)
嘿! 编译和运行(快速F5)
太好了,我们来看看结果吧!
Debug.print c.Name("John")
Run Code Online (Sandbox Code Playgroud)
嗯...只Smith在立即窗口显示(Ctrl+ G)......不完全是我们要找的......
回到Let财产我们注意到我们通过参数获取2个值,但我们只使用其中一个值?我们有两个不同的值进入函数,对吗?让我们将第一个视为firstName第二个,将第二个视为lastName
Public Property Let Name(first As String, last As String)
firstName = first
lastName = last
End Property
Run Code Online (Sandbox Code Playgroud)
回去吧 Module1
Sub Main()
Dim c As New Class1
c.Name("John") = "Smith"
Debug.Print c.Name("John")
End Sub
Run Code Online (Sandbox Code Playgroud)
并重新运行当前代码为我们提供了我们需要的东西......它打印出约翰史密斯,但等待!!! 为什么我们必须传递名字才能检索全名?
哈!这样做的诀窍是制作两个属性的第一个参数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
Run Code Online (Sandbox Code Playgroud)
Module1.bas
Sub Main()
Dim c As New Class1
c.Name("John") = "Smith"
Debug.Print c.Name ' prints John Smith
End Sub
Run Code Online (Sandbox Code Playgroud)
因此,基本上可以在VBA中通过属性分配两个(或更多)值Let.可能会让你失望的是它的语法,但我希望我在这个答案中的解释能帮助你理解事物的来源和原因.
该Get属性采用一个可选参数 - 它实际上只是一个虚拟参数 ......它不会在Get属性中的任何地方使用,但它允许我们获得所需的Let签名并允许我们将两个参数传递给它.它还提供易于记忆的c.Name语法.
电话
Debug.Print c.Name("first")
Run Code Online (Sandbox Code Playgroud)
仍然可能,但"first"参数只是像假的一样,对实际的底层数据没有影响.它是一个虚拟对实际数据没有影响 - 转储并使用:
Debug.print c.Name
Run Code Online (Sandbox Code Playgroud)
绝对更方便:)
根据您的评论,如果您希望封装此逻辑,那么您可以使用类似于下面的内容.
下面包括子和功能.该函数返回一个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
Run Code Online (Sandbox Code Playgroud)
人员类:
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
Run Code Online (Sandbox Code Playgroud)