让 VBA 类模块的属性 - 是否可以有多个参数?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13823367/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 14:35:06  来源:igfitidea点击:

Let property of VBA class modules - is it possible to have multiple arguments?

vbaclassoopexcel-vbaproperties

提问by mattboy

My understanding of using the Let property in a class module so far is that you set it up in the class modules like this:

到目前为止,我对在类模块中使用 Let 属性的理解是,您可以像这样在类模块中设置它:

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

And then you after you've created an object of this class you can set this property like so:

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

MyObject.Name = "Larry"



Question: Is it possible to somehow enter multiple arguments into a class property? For instance:



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

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

How would you then go about setting this property outside the class?

那么你将如何在课堂之外设置这个属性?

MyObject.Name = ??

Or is this just plain not possible to do?

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

采纳答案by InContext

As per your comment if you would prefer to encapsulate this logic then you can use something similar to the below.

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

Below includes the sub and function. The function returns a Person object:

下面包括子和函数。该函数返回一个 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

Person Class:

人物等级:

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

回答by

I realise there already are 2 workarounds but I thought answering your original question was worth giving a shot due to the amount of views this question is receiving.

我意识到已经有 2 种解决方法,但我认为回答您最初的问题值得一试,因为这个问题收到的观看次数很多。

The answer to

的答案

Is it possible to have multiple arguments in the Let Property in VBA?

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

is

YES! It's possible.

是的!这是可能的。

First let's talk about the GET property. Consider this being the Class1

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

Private firstName as String
Private lastName as String

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

The Nameproperty will return the full name, that's great but how to use the Letproperty to assign firstName& lastNamein one go?

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

Side note: You could pass a single string separated with a special character and split it inside the body of the Letand assign the firstand lastnamesbut forget that, let's get it done properly...

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

OK, in VBA the default Letproperty for the current setup would take 1 parameter and assign it to either first or last name...

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

Something like:

就像是:

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

Rule: the Gettakes no parameters and the Lettakes one. That is very logical because the Getreturns the underlying value but the Letneeds to grab a value from somewherein order to assign it to the data it's representing. Worth remembering at this point that the Letproperty is assigned via the =sign ie. myObject.Name = "IdOnKnuu"

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

we know that if we stay consistent with the above rule, theoretically we should be able to add one parameter to the Getand one more to the Let.

我们知道,如果我们留在上面的一致规律,从理论上我们应该能够一个参数添加到Get更多的一到Let

Let's forget the Let- comment it out for now- and add a parameter to the Getproperty.

让我们忘记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

Going back to the Module1create an instance of Class1and type c.Name(

回到Module1创建Class1和类型的实例c.Name(

enter image description here

在此处输入图片说明

oh, intelli-sense expecting something? Awesome!

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

At this point it's worth understanding that our Getproperty returns first + lastwhich are both empty at the moment, so it doesn't matter what you are going to pass to the c.Name()it will return an empty string.

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

Ok, let's uncomment and tweak the Letproperty now...

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

Side node: if you jump back to Module1and type c.and don't get intelli-sense it pretty much means that something in Class1is broken... We already know - it's the Letproperty that's causing it

侧节点:如果你跳回Module1并输入c.并且没有获得智能感知,这几乎意味着里面的东西Class1坏了......我们已经知道 - 这Let是导致它的属性

We have added a parameter to the Getproperty, let's do the same with the Letproperty...

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

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

Let's go back to the Module1and try to use the Letproperty:

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

Remember, how you have used the Letproperty before? You needed to assign it a value

请记住,您Let之前是如何使用该物业的?你需要给它赋值

c.Name = "John"

But now, your Letproperty is expecting an extra parameter first as String.

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

Why don't we try this:

我们为什么不试试这个:

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

Hey! that compiles and runs (a quick F5)

嘿!编译和运行(快速F5

Great, let's check the results!

太好了,让我们看看结果!

Debug.print c.Name("John")

Uhm... that only shows Smithin the Immediate Window (Ctrl+G)... Not exactly what we were looking for....

嗯...只显示Smith在即时窗口 ( Ctrl+ G)... 不完全是我们要找的....

Going back to the Letproperty we notice that we are grabbing 2 values via arguments but we only make use of one of them? We have the 2 different values coming in to the function, right? Let's treat the first one as the firstNameand the second one as lastName

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

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

Going back to Module1

回到 Module1

Sub Main()

    Dim c As New Class1

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

    Debug.Print c.Name("John")

End Sub

and re-running out current code gives us what we need ... it prints John Smithbut wait!!! why do we have to pass the first name in order to retrieve the full name?

并重新运行当前代码为我们提供了我们需要的东西......它打印了约翰史密斯但是等等!!!为什么我们必须通过名字才能检索全名

Ha! The trick to this is to make the first parameters of both properties Optional

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

Summarising, the code:

总结一下,代码:

Class1.cls

类1.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

模块1.bas

Sub Main()

    Dim c As New Class1

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

    Debug.Print c.Name ' prints John Smith

End Sub

So basically the assignment of two (or more) values through the Letproperty is possible in VBA. The thing that may throw you off a bit is the Syntax for it but I hope my explanation in this answer has helped you understand where things come from and why.

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

The Getproperty takes an optional parameter- it's really just a dummy parameter... it's not used anywhere within the Getproperty but it's allowing us to get the desired Letsignature and allows us to pass two parameters to it. It also grants the easy to remember c.Namesyntax.

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

The call

电话

Debug.Print c.Name("first")

is still possible, however the "first"parameter just acts like a dummy and has no effect on the actual underlying data. It's a dummy and has no effect on the actual data - dump it and use:

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

Debug.print c.Name

definitely more convenient :)

绝对更方便:)

回答by KacireeSoftware

Use as Public Sub procedure within the class to perform this:

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

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

End Sub

Person Class:

人物等级:

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