31

我正在使用 Excel VBA 来编写 UDF。我想用几个不同的版本重载我自己的 UDF,以便不同的参数调用不同的函数。

由于 VBA 似乎不支持这一点,任何人都可以提出一种实现相同目标的好方法吗?我应该使用可选参数还是有更好的方法?

4

4 回答 4

57

将您的参数声明为Optional Variants,然后您可以使用 来测试它们是否丢失IsMissing()或使用 来检查它们的类型TypeName(),如以下示例所示:

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 ")

于 2008-09-16T08:59:22.750 回答
7

如果您可以通过参数计数进行区分,那么这样的事情会起作用:

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++ 和其他具有重写函数的语言所做的事情,即通过签名调用。我建议让电话看起来像这样:

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。

于 2008-09-16T10:51:41.530 回答
0

VBA 很乱。我不确定是否有一种简单的方法可以进行假重载:

在过去,我要么使用了很多 Optionals,要么使用了不同的函数。例如

Foo_DescriptiveName1()

Foo_DescriptiveName2()

我会说使用具有合理默认值的可选参数,除非参数列表会变得愚蠢,然后创建单独的函数来调用您的案例。

于 2008-09-15T16:35:20.933 回答
0

您可能还想考虑为您的参数列表使用变体数据类型,然后使用 TypeOf 语句找出什么是什么类型,然后在您弄清楚什么是什么时调用适当的函数......

于 2008-09-15T17:42:17.807 回答