简体   繁体   English

Excel VBA中的函数重载和UDF

[英]Function Overloading and UDF in Excel VBA

I'm using Excel VBA to a write a UDF. 我正在使用Excel VBA来编写UDF。 I would like to overload my own UDF with a couple of different versions so that different arguments will call different functions. 我想用几个不同的版本重载我自己的UDF,以便不同的参数将调用不同的函数。

As VBA doesn't seem to support this, could anyone suggest a good, non-messy way of achieving the same goal? 由于VBA似乎不支持这一点,任何人都可以建议一种实现同一目标的良好,非凌乱的方式吗? Should I be using Optional arguments or is there a better way? 我应该使用可选参数还是有更好的方法?

Declare your arguments as Optional Variants , then you can test to see if they're missing using IsMissing() or check their type using TypeName() , as shown in the following example: 将您的参数声明为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

This can be called from a worksheet as =FOO() , =FOO( number ) , or =FOO(" string ") . 这可以从工作表中调用为= FOO()= FOO( 数字= FOO(“ 字符串 ”)

If you can distinguish by parameter count, then something like this would work: 如果你可以通过参数计数来区分,那么像这样的东西可以工作:

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

If the only way to distinguish the function is by types, then you're effectively going to have to do what C++ and other languages with overridden functions do, which is to call by signature. 如果区分函数的唯一方法是按类型划分,那么你实际上必须要做C ++和其他被覆盖函数的语言,即通过签名调用。 I'd suggest making the call look something like this: 我建议打电话看起来像这样:

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

and creating a class with a number of methods that match the signatures you expect. 并创建一个具有许多方法的类,这些方法与您期望的签名相匹配。 You'll probably need some error-handling though, and be warned that the types that are recognizable are limited: dates are TypeName Double, for example. 您可能需要进行一些错误处理,并警告可识别的类型是有限的:例如,日期是TypeName Double。

VBA is messy. VBA很乱。 I'm not sure there is an easy way to do fake overloads: 我不确定是否有一种简单的方法来做假超载:

In the past I've either used lots of Optionals, or used varied functions. 在过去,我要么使用了很多Optionals,要么使用了各种各样的功能。 For instance 例如

Foo_DescriptiveName1()

Foo_DescriptiveName2()

I'd say go with Optional arguments that have sensible defaults unless the argument list is going to get stupid, then create separate functions to call for your cases. 我会说使用具有合理默认值的可选参数,除非参数列表将变得愚蠢,然后创建单独的函数来调用您的案例。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM