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?
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").
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.
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.
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...