【问题标题】:Function Overloading and UDF in Excel VBAExcel VBA中的函数重载和UDF
【发布时间】:2010-09-09 00:43:51
【问题描述】:

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

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

【问题讨论】:

    标签: excel user-defined-functions vba


    【解决方案1】:

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

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

    Foo_DescriptiveName1()
    
    Foo_DescriptiveName2()
    

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        将您的参数声明为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( "字符串").

        【讨论】:

        • Joel,我们真的应该感谢您在 VB/VBA 中使用 Variant 吗? ;-)
        • 是的。这对 Excel 很重要,因为我们认为可以放入电子表格单元格的任何内容都应该可以放入 Basic 变量中,否则读取单元格的简单操作将需要几行代码。
        • 这会掩盖函数的有效签名。不幸的是,VBA 不允许具有不同参数类型的多个同名函数。
        • 非常好。我忘记了函数中的 Optional 。这意味着您可以在声明中组合强制变量和可选变量
        【解决方案4】:

        如果你可以通过参数计数来区分,那么这样的事情就可以了:

        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。

        【讨论】:

          猜你喜欢
          • 2012-11-22
          • 1970-01-01
          • 2011-01-08
          • 2018-06-22
          • 2014-05-26
          • 2017-05-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多