Excel VBA 中的函数重载和 UDF
-
09-06-2019 - |
题
我正在使用 Excel VBA 编写 UDF。我想用几个不同的版本重载我自己的 UDF,以便不同的参数调用不同的函数。
由于 VBA 似乎不支持这一点,任何人都可以建议一种好的、不混乱的方法来实现相同的目标吗?我应该使用可选参数还是有更好的方法?
解决方案
将你的论点声明为 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(数字), , 或者 =FOO(“细绳").
其他提示
如果你可以通过参数计数来区分,那么这样的事情就可以工作:
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。
VBA 很混乱。我不确定是否有一种简单的方法可以进行假重载:
过去我要么使用了很多Optional,要么使用了不同的函数。例如
Foo_DescriptiveName1()
Foo_DescriptiveName2()
我会说使用具有合理默认值的可选参数,除非参数列表变得愚蠢,然后创建单独的函数来调用您的案例。
您可能还想考虑对参数列表使用变体数据类型,然后使用 TypeOf 语句找出什么类型,然后在找出什么是什么时调用适当的函数...
不隶属于 StackOverflow