it-swarm-es.tech

Sobrecarga de funciones y UDF en Excel VBA

Estoy usando Excel VBA para escribir un UDF. Me gustaría sobrecargar mi propio UDF con un par de versiones diferentes para que diferentes argumentos invoquen diferentes funciones.

Como VBA no parece apoyar esto, ¿alguien podría sugerir una forma buena y no desordenada de lograr el mismo objetivo? ¿Debo estar usando argumentos opcionales o hay una mejor manera?

28
Patrick

Declare sus argumentos como Optional Variants, Luego puede probar para ver si faltan usando IsMissing() o verificar su tipo usando TypeName(), como se muestra en el siguiente ejemplo:

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

Esto se puede llamar desde una hoja de trabajo como = FOO (), = FOO ( número ) , o = FOO (" cadena ").

51
Joel Spolsky

Si puede distinguir por conteo de parámetros, entonces algo como esto funcionaría:

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

Si la única forma de distinguir la función es por tipos, entonces efectivamente tendrá que hacer lo que hacen C++ y otros lenguajes con funciones anuladas, que es llamar por firma. Sugeriría hacer que la llamada se vea así:

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

y crear una clase con varios métodos que coincidan con las firmas que espera. Sin embargo, es probable que necesite un tratamiento de errores, y tenga en cuenta que los tipos que son reconocibles son limitados: las fechas son TypeName Double, por ejemplo.

5
Mike Woodhouse

VBA es desordenado. No estoy seguro de que haya una manera fácil de hacer sobrecargas falsas:

En el pasado, utilicé muchas opciones o utilicé funciones variadas. Por ejemplo

Foo_DescriptiveName1()

Foo_DescriptiveName2()

Yo diría que vaya con argumentos opcionales que tienen valores predeterminados razonables a menos que la lista de argumentos se vuelva estúpida, luego cree funciones separadas para llamar a sus casos.

0
theo

También debe considerar usar un tipo de datos variante para su lista de argumentos y luego averiguar qué tipo usa la instrucción TypeOf, y luego llamar a las funciones apropiadas cuando descubra qué es qué ...

0
Jon Fournier