La surcharge de la fonction et UDF dans Excel VBA

J'utilise Excel VBA pour écrire un UDF. Je voudrais surcharger mon propre UDF avec quelques versions différentes de sorte que différents arguments appelleront différentes fonctions.

comme VBA ne semble pas soutenir cela, est-ce que quelqu'un pourrait suggérer une bonne façon, sans désordre d'atteindre le même objectif? Dois-je utiliser des arguments Optionnels ou est-il un meilleur moyen?

26
demandé sur Community 2008-09-15 20:28:28

4 réponses

Déclarez vos arguments comme Optional Variants, alors vous pouvez tester pour voir si elles sont manquantes en utilisant IsMissing() ou vérifiez leur type en utilisant TypeName(), comme illustré dans l'exemple suivant:

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

ceci peut être appelé à partir d'une feuille de travail comme =FOO (), = FOO (), ou = FOO ("chaîne").

48
répondu Joel Spolsky 2008-09-16 08:59:22

si vous pouvez distinguer par le nombre de paramètres, alors quelque chose comme ceci fonctionnerait:

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 seule façon de distinguer la fonction est par types, alors vous allez effectivement devoir faire ce que C++ et d'autres langages avec des fonctions surchargées font, qui est d'appeler par signature. Je suggère que l'appel ressemble à ceci:

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

et créer une classe avec un certain nombre de méthodes qui correspondent aux signatures que vous attendez. Vous aurez probablement besoin de quelques la gestion des erreurs cependant, et soyez averti que les types qui sont reconnaissables sont limités: les dates sont dactylographiées en Double, par exemple.

5
répondu Mike Woodhouse 2011-03-09 20:34:31

VBA est bordélique. Je ne suis pas sûr qu'il y ait un moyen facile de faire de fausses surcharges:

dans le passé, j'ai soit utilisé beaucoup D'options, soit utilisé des fonctions variées. Par exemple,

Foo_DescriptiveName1()

Foo_DescriptiveName2()

je dirais d'aller avec des arguments optionnels qui ont des valeurs par défaut sensées à moins que la liste d'arguments ne devienne stupide, puis de créer des fonctions séparées pour appeler pour vos cas.

0
répondu theo 2008-09-15 16:35:20

vous pouvez également envisager d'utiliser un type de données variant pour votre liste d'arguments et ensuite comprendre ce qui est quel type en utilisant la déclaration TypeOf, et ensuite appeler les fonctions appropriées quand vous comprenez ce qui est quoi...

0
répondu Jon Fournier 2008-09-15 17:42:17