Surcharge de fonctions et UDF dans Excel VBA
-
09-06-2019 - |
Question
J'utilise Excel VBA pour écrire un fichier UDF. Je voudrais surcharger mon propre fichier UDF avec plusieurs versions différentes afin que différents arguments appellent différentes fonctions.
Comme VBA ne semble pas soutenir cela, est-ce que quelqu'un pourrait suggérer un moyen efficace et non chaotique d'atteindre le même objectif? Devrais-je utiliser des arguments optionnels ou existe-t-il un meilleur moyen?
La solution
Déclarez vos arguments en tant que variantes optionnelles
, puis vous pourrez vérifier s'ils manquent à l'aide de IsMissing ()
ou vérifier leur type à l'aide de 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é depuis une feuille de travail sous la forme = FOO () , = FOO ( numéro ) ou = FOO ( " chaîne ") .
Autres conseils
Si vous parvenez à distinguer par le nombre de paramètres, cela ressemblerait à ceci:
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 le seul moyen de distinguer la fonction est par types, vous devrez alors faire ce que font C ++ et les autres langages avec des fonctions remplacées, à savoir appeler par signature. Je suggèrerais 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 en créant une classe avec un nombre de méthodes correspondant aux signatures que vous attendez. Vous aurez probablement besoin de quelques erreurs de traitement et soyez averti que les types reconnaissables sont limités: les dates sont TypeName Double, par exemple.
VBA est en désordre. Je ne suis pas sûr qu'il existe un moyen facile de faire de fausses surcharges:
Dans le passé, j’utilisais beaucoup d’options ou des fonctions variées. Par exemple
Foo_DescriptiveName1()
Foo_DescriptiveName2()
Je dirais qu'il faut utiliser des arguments facultatifs qui ont des valeurs par défaut raisonnables, à moins que la liste des arguments ne devienne stupide, puis créez des fonctions distinctes à appeler pour vos cas.
Vous pouvez également envisager d’utiliser un type de données variant pour votre liste d’arguments, puis de déterminer quel type utilise ce type à l’aide de l’instruction TypeOf, puis d’appeler les fonctions appropriées lorsque vous déterminez ce qui est ...