it-swarm-pt.tech

Sobrecarga de função e UDF no Excel VBA

Estou usando o Excel VBA para escrever um UDF. Eu gostaria de sobrecarregar meu próprio UDF com algumas versões diferentes para que argumentos diferentes chamem funções diferentes.

Como o VBA não parece apoiar isso, alguém poderia sugerir uma maneira boa e não complicada de atingir o mesmo objetivo? Devo usar argumentos opcionais ou há uma maneira melhor?

28
Patrick

Declare seus argumentos como Optional Variants, Então você pode testar para ver se eles estão faltando usando IsMissing() ou verificar 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 (" string ").

51
Joel Spolsky

Se você puder distinguir por contagem de parâmetro, 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 é por tipos, então você efetivamente terá que fazer o que C++ e outras linguagens com funções substituídas fazem, que é chamar por assinatura. Eu sugiro fazer a chamada parecer algo 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 criando uma classe com uma série de métodos que correspondem às assinaturas que você espera. Você provavelmente precisará de algum tratamento de erros e será avisado de que os tipos que são reconhecíveis são limitados: as datas são TypeName Double, por exemplo.

5
Mike Woodhouse

VBA é uma bagunça. Não tenho certeza se existe uma maneira fácil de fazer sobrecargas falsas:

No passado, usei muitos opcionais ou várias funções. Por exemplo

Foo_DescriptiveName1()

Foo_DescriptiveName2()

Eu diria que vá com argumentos opcionais que têm padrões razoáveis, a menos que a lista de argumentos se torne estúpida e, em seguida, crie funções separadas para chamar seus casos.

0
theo

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 é ...

0
Jon Fournier