vba variant array bug

Je suis assez nouveau pour Excel vba et je ne peux pas résoudre ce problème avec vbArrays. J'ai créé la fonction cumsum in vba pour faciliter ma vie. Cependant, je souhaite que le code soit flexible de sorte que je puisse passer dans les deux variantes d'une fonction et aussi d'une gamme. Dans mon code, lorsque j'ai ajouté la ligne vec = vec.value si je passe dans une plage, ça marche parfaitement, mais ça ne marche pas si je veux que ça fonctionne si j'appelle la fonction et je passe un type de gamme . Ce que j'ai remarqué était si je n'avais pas la ligne vec = vec.value dans mon code et je passe dans une gamme, il a la dimension 0 et j'ai vérifié en écrivant ma propre fonction. Quelqu'un peut-il m'expliquer comment je peux régler ce problème? Merci.

Public Function cumsum(vec As Variant) As Variant Dim temp() As Variant MsgBox (getDimension(vec)) 'works if i use vec=vec.value if vec is a range but has 0 if i do not vec = vec.values ReDim temp(LBound(vec, 1) To UBound(vec, 1), 1 To 1) As Variant Dim intCounter As Integer For intCounter = LBound(vec) To UBound(vec) If intCounter = LBound(vec) Then temp(intCounter, 1) = vec(intCounter, 1) Else temp(intCounter, 1) = temp(intCounter - 1, 1) + vec(intCounter, 1) End If Next cumsum = temp() End Function Function getDimension(var As Variant) As Integer On Error GoTo Err: Dim i As Integer Dim tmp As Integer i = 0 Do While True: i = i + 1 tmp = UBound(var, i) Loop Err: getDimension = i - 1 End Function 

Les réponses de @Jake et @chris sont des indications dans la bonne direction, mais je ne pense pas qu'elles vont assez loin.

Si vous êtes absolument sûr que vous n'appelerez que cette routine comme UDF (c'est-à-dire à partir de formules dans vos feuilles de travail), alors tout ce que vous devez vraiment faire est d'append ceci:

 If IsObject(vec) Then Debug.Assert TypeOf vec Is Range vec = vec.Value2 End If 

au début de votre fonction. Appelé comme un UDF, le seul type d'object qu'il devrait jamais passer est Range . En outre, appelé UDF, vous pouvez countr sur le fait que tous les arrays qu'il passe sont indexés à partir de 1.

Je pourrais choisir d'autres problèmes avec votre routine, mais ils seraient à côté de votre question initiale. En bref: cela ne fonctionnera que sur les vectors de colonne, il échouera pour les plages de cellules uniques, etc.

Notez que la raison pour laquelle votre fonction getDimension renvoie zéro pour la Range s parce que UBound étouffe la gamme. Votre gestionnaire d'erreur attire heureusement une erreur (tapez non correspondance), vous ne vous attendiez pas vraiment à get et à revenir zéro. (Cette méthode de search de "dimension" suppose que l'erreur sera une erreur de scope de l'indice.)

J'ai écrit une réponse tout en décrivant pourquoi, lorsque je travaille avec Excel, je ne pense pas que l'approche getDimension soit bonne:

https://stackoverflow.com/a/6904433/58845

Enfin, le problème avec VarType est que, lorsqu'il est passé un object ayant une propriété par défaut, il renverra le type de propriété. Donc, VarType(<range>) vous indiquera le type de choses dans la gamme, et non le code de l'object, car Range possède une propriété par défaut, Range.Value .

Pourquoi ne vérifiez-vous pas le type de données de vec en utilisant VarType et TypeName, puis effectuez la manipulation nécessaire sur vec

 Public Function cumsum2(vec As Variant) As Variant MsgBox TypeName(vec) MsgBox VarType(vec) cumsum2 = 0 End Function 

Modifiez votre getDimension pour inclure

 If TypeName(var) = "Range" Then var = var.Value End If