我正在使用Excel VBA编写UDF。 我想用两个不同的版本重载我自己的UDF,以便不同的参数将调用不同的函数。
由于VBA似乎不支持此功能,因此有人可以建议一种实现同一目标的好方法,而不是杂乱无章吗? 我应该使用可选参数还是有更好的方法?
将参数声明为Optional Variants,然后可以使用IsMissing()进行测试以查看是否缺少参数,或者使用TypeName()检查其类型,如以下示例所示:
1 2 3 4 5 6 7 8 9 10 11
   | Public Function Foo(Optional v As Variant) As Variant 
 
    If IsMissing(v) Then 
        Foo ="Missing argument" 
    ElseIf TypeName(v) ="String" Then 
        Foo = v &" plus one" 
    Else 
        Foo = v + 1 
    End If 
 
End Function  | 
 
可以从工作表中将其称为= FOO(),= FOO(number)或= FOO(" string")。
如果您可以通过参数计数来区分,则可以执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
   | Public Function Morph(ParamArray Args()) 
 
    Select Case UBound(Args) 
    Case -1 '' nothing supplied 
        Morph = Morph_NoParams() 
    Case 0 
        Morph = Morph_One_Param(Args(0)) 
    Case 1 
        Morph = Two_Param_Morph(Args(0), Args(1)) 
    Case Else 
        Morph = CVErr(xlErrRef) 
    End Select 
 
End Function 
 
Private Function Morph_NoParams() 
    Morph_NoParams ="I'm parameterless" 
End Function 
 
Private Function Morph_One_Param(arg) 
    Morph_One_Param ="I has a parameter, it's" & arg 
End Function 
 
Private Function Two_Param_Morph(arg0, arg1) 
    Two_Param_Morph ="I is in 2-params and they is" & arg0 &"," & arg1 
End Function  | 
 
如果区分功能的唯一方法是按类型,那么您实际上将必须执行C ++和其他具有被覆盖功能的语言所执行的操作,即按签名进行调用。我建议使通话看起来像这样:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
   | Public Function MorphBySig(ParamArray args()) 
 
Dim sig As String 
Dim idx As Long 
Dim MorphInstance As MorphClass 
 
    For idx = LBound(args) To UBound(args) 
        sig = sig & TypeName(args(idx)) 
    Next 
 
    Set MorphInstance = New MorphClass 
 
    MorphBySig = CallByName(MorphInstance,"Morph_" & sig, VbMethod, args) 
 
End Function  | 
 
并创建一个具有许多与您期望的签名相匹配的方法的类。但是,您可能需要进行一些错误处理,并警告您可以识别的类型是有限的:例如,日期是TypeName Double。
 
您可能还想考虑对参数列表使用变量数据类型,然后使用TypeOf语句找出什么类型,然后在找出什么内容时调用适当的函数...
VBA杂乱无章。我不确定是否有简单的方法来进行假重载:
过去,我要么使用了大量的Optionals,要么使用了多种功能。例如
1 2 3
   | Foo_DescriptiveName1() 
 
Foo_DescriptiveName2()  | 
 
我想说说带有可选默认值的可选参数,除非参数列表变得愚蠢,然后创建单独的函数来调用您的案例。