web-dev-qa-db-fra.com

Excel VBA: Variantes dans les variables de tableau

Une question sur les variantes. Je suis conscient que les variantes d'Excel vba sont à la fois le type de données par défaut et également inefficaces (du point de vue de la surutilisation dans les grandes applications). Cependant, je les utilise régulièrement pour stocker des données dans des tableaux qui ont plusieurs types de données. Un projet en cours sur lequel je travaille est essentiellement une tâche qui nécessite une optimisation massive d'un code très pauvre (environ 7 000 lignes) - et cela m'a fait réfléchir; Y a-t-il un moyen de contourner ceci?

Expliquer; le code stocke fréquemment des données dans des variables de tableau. Considérez donc un ensemble de données de 10 colonnes par 10000. Les colonnes sont plusieurs types de données différents (chaîne, double, entiers, dates, etc.). En supposant que je veux les stocker dans un tableau, je le ferais habituellement;

dim myDataSet(10,10000) as variant

Mais, ma connaissance dit que cela sera vraiment inefficace avec le code évaluant chaque élément pour déterminer de quel type de données il s'agit (alors qu'en pratique je sais ce que j'attends). De plus, je perds le contrôle que me donne le dimensionnement des types de données individuels. Donc, (en supposant que les 6 premiers sont des cordes, les 4 doubles suivants pour faciliter l'explication du point), je pourrais;

dim myDSstrings(6,10000) as string
dim myDSdoubles(4,10000) as double

Cela me redonne le contrôle et l'efficacité - mais c'est aussi un peu maladroit (en pratique, les types sont mélangés et différents - et je finis par avoir un nombre impair d'éléments dans chacun, et finalement je dois les assigner individuellement dans le code - plutôt qu'en masse). Donc, c'est un cas de;

myDSstrings(1,r) = cells(r,1)
myDSdoubles(2,r) = cells(r,2)
myDSstrings(2,r) = cells(r,3)
myDSstrings(3,r) = cells(r,4)
myDSdoubles(3,r) = cells(r,5)
..etc...

Ce qui est beaucoup plus moche que;

myDataSet(c,r) = cells(r,c)

Donc, ça m'a fait réfléchir, je dois manquer quelque chose ici. Quelle est la meilleure façon de stocker un tableau de différents types de données? Ou, en supposant qu'il n'y ait aucun moyen de le faire - quelle serait la meilleure pratique de codage pour stocker un tableau de types de données mixtes?

14
Surferosa

N'optimisez jamais votre code sans mesurer d'abord. Vous serez peut-être surpris de savoir où le code est le plus lent. J'utilise l'utilitaire PerfMon de Professional Excel Development, mais vous pouvez également lancer le vôtre.

La lecture et l'écriture vers et depuis les plages Excel est un gros puits de temps. Même si les variantes peuvent gaspiller beaucoup de mémoire, cela

Dim vaRange as Variant
vaRange = Sheet1.Range("A1:E10000").Value
'do something to the array
Sheet1.Range("A1:E10000").Value = vaRange

est généralement plus rapide que de parcourir des lignes et des cellules.

Ma méthode préférée pour utiliser des tableaux avec plusieurs types de données est de ne pas utiliser de tableaux du tout. Je vais plutôt utiliser un module de classe personnalisé et créer des propriétés pour les éléments. Ce n'est pas nécessairement une amélioration des performances, mais cela rend le code beaucoup plus facile à écrire et à lire.

11
Dick Kusleika

Je ne suis pas sûr que votre goulot d'étranglement provienne du typage Variant de votre tableau.

Par ailleurs, pour définir des valeurs d'un tableau vers une plage Excel , vous devez utiliser (dans Excel 8 ou supérieur):

Range("A1:B2") = myArray

Sur les versions précédentes, vous devez utiliser le code suivant:

Sub SuperBlastArrayToSheet(TheArray As Variant, TheRange As Range)
  With TheRange.Parent.Parent 'the workbook the range is in
    .Names.Add Name:="wstempdata", RefersToR1C1:=TheArray
    With TheRange
      .FormulaArray = "=wstempdata"
      .Copy
      .PasteSpecial Paste:=xlValues
    End With
    .Names("wstempdata").Delete
  End With
End Sub

de cette source que vous devriez lire pour l'optimisation VBA.

Pourtant, vous devez profiler votre application pour voir où se trouvent vos goulots d'étranglement. Voir cette question d'Issun pour vous aider à comparer votre code.

4
JMax