How do optional Parameters in Let/Get Properties work?
I am using vba with Excel 2007, and am writing code for a class module.
1) Is the following code even possible?...
Essentially I have two enums, call themeDATASET
and eDATATSUBSET
. A particular value from eDATASET
should trigger an assignment from the optionally passed parameter in a Let
property. Something like this:
Public Property Let foo(Optional ByVal lngSubSet as eDATASUBSET, _
ByVal lngSuperSet as eDATASET)
Select Case lngSuperSet
Case eDATASET.abc, eDATASET.def
mlngBar = lngSuperSet
Case eDATASET.xyz
'// if lngSubSet not passed, trigger error code...
mlngBar = lngSubSet
End Select
End Property
2) How do I even pass an optional parameter to a writable property when calling the object...
Aside from the seemingly backwards placement of theOption开发者_如何学Cal
parameters (compared with optional parameters in functions and subs), I am having trouble finding any documentation on this feature. The vba help says this:
Optional. Indicates that an argument is not required. If used, all subsequent arguments in arglist must also be optional and declared using the Optional keyword. Note that it is not possible for the right side of a Property Let expression to be Optional.
and the following from vbusers.com. Neither explain much in the way of usage. So how would i pass the optional parameter when calling the object from a code module... oObj.foo = ???
3) Is there a better way to do this?...
I have a basic understanding of oop (at least in how it is implemented in vba). Is there a better way to conditionally accept a parameter into an object?1) Yes your code is possible.
2) This is how you pass an argument:
Assuming myObject
is an object of your class:
myObject.foo(lngSubSet) = lngSuperSet
The placement of arguments in the arglist does indeed look weird, but that's VBA for you. Say you have 4 arguments, two of which are optional, plus your right hand side. You would place them like this:
Public Property Let foo(arg1, arg2, Optional arg3, Optional arg4, _
RHS)
and use them like this (assuming you're opting out of arg4
):
myObject.foo(arg1,arg2,arg3) = RHS
3) Is there a better way to do this? There always is, depending who you ask. You could have your lngSubSet
argument as a separate property entirely. That's how I tend to do it. But in your case, your way of doing things may work well for you. I don't know, it's largely a question of taste and dependent on your specific application.
This question is marked as the answer to a completely different question, "Let property of VBA class modules - is it possible to have multiple arguments? [duplicate]", so it's possible that people wanting an answer to that question might follow the link and wind up here.
That question is closed, so I'll give the answer to it here: Yes, it is possible to use multiple arguments, as described in the documentation: https://learn.microsoft.com/en-us/office/vba/language/reference/user-interface-help/property-let-statement
You use a ParamArray declaration.
I am using Excel 2016.
Using a ParamArray can be unnecessarily complicated for a lot of cases...
You need to make sure the Let & Get declarations have the same number of arguments AND argument names. If Get & Let properties use different arguments then the ParamArray is required.
'********************************************
'********************************************
Public Property Let col(ByVal j As Integer, _
Optional normalize_IO_vector As Boolean = False, _
row_vals() As Double)
'
' do stuff
'
End Property
'---------------
Public Property Get col(ByVal j As Integer, _
Optional normalize_IO_vector As Boolean = False) As Double()
'
' do stuff
'
End Property
'********************************************
'********************************************
The property declarations below throws an error...
' !! this DOES NOT WORK...
'
' "normalize_input_vector" VS "normalize_output_vector"
'
'********************************************
'********************************************
Public Property Let col(ByVal j As Integer, _
Optional normalize_input_vector As Boolean = False, _
row_vals() As Double)
'
' do stuff
'
End Property
'---------------
Public Property Get col(ByVal j As Integer, _
Optional normalize_output_vector As Boolean = False) As Double()
'
' do stuff
'
End Property
'********************************************
'********************************************
精彩评论