Sobrecarga de funções e UDF no Excel VBA
-
09-06-2019 - |
Pergunta
Estou usando o Excel VBA para escrever uma UDF.Gostaria de sobrecarregar minha própria UDF com algumas versões diferentes, para que argumentos diferentes chamem funções diferentes.
Como o VBA parece não suportar isso, alguém poderia sugerir uma maneira boa e não complicada de atingir o mesmo objetivo?Devo usar argumentos opcionais ou existe uma maneira melhor?
Solução
Declare seus argumentos como Optional Variants
, então você pode testar para ver se eles estão faltando usando IsMissing()
ou verifique seu tipo usando TypeName()
, conforme mostrado no exemplo a seguir:
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
Isso pode ser chamado de uma planilha como =FOO(), =FOO(número), ou =FOO("corda").
Outras dicas
Se você conseguir distinguir pela contagem de parâmetros, algo assim funcionaria:
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
Se a única maneira de distinguir a função for por tipos, você terá que fazer o que C++ e outras linguagens com funções substituídas fazem, que é chamar por assinatura.Eu sugiro que a chamada seja mais ou menos assim:
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
e criar uma classe com vários métodos que correspondam às assinaturas esperadas.Você provavelmente precisará de algum tratamento de erros e esteja avisado de que os tipos reconhecíveis são limitados:as datas são TypeName Double, por exemplo.
VBA é confuso.Não tenho certeza se existe uma maneira fácil de fazer sobrecargas falsas:
No passado, usei muitos opcionais ou funções variadas.Por exemplo
Foo_DescriptiveName1()
Foo_DescriptiveName2()
Eu diria que vá com argumentos opcionais que tenham padrões sensatos, a menos que a lista de argumentos fique estúpida e, em seguida, crie funções separadas para chamar seus casos.
Você também pode querer considerar o uso de um tipo de dados variante para sua lista de argumentos e, em seguida, descobrir qual é o tipo usando a instrução TypeOf e, em seguida, chamar as funções apropriadas quando descobrir o que é o quê ...