Erreur lors de l'exécution d'une Macro Excel

jeps

Membre enregistré
16 Septembre 2005
6
0
39
Bonjour à tous!

Pour le boulot, je dois faire des moyennes horaires de données qu'on a toutes les 5min. Comme on a un grand nombre de données (plus de 50 000), et qu'il y a parfois des trous, j'ai fait une macro en VB.
Mais, lorsque je l'exécute, j'ai un message d'erreur qui dit "Incompatibilité de type". Et aucun lien vers le menu de bédogage... Donc je ne sais pas ce qu'il ne va pas... Je pense aux formats de cellules non compatibles, mais ça me parrait bizarre. Le plus bizarre, c'est qu'il fait les calculs pour un certain nombre de fois, mais ne va pas jusqu'au bout

Quelqu'un aurait il une idée d'ou vient le problème?

Pour info, voila ma macro:
Sub Total()

Dim N
Dim a
Dim L
Dim I
Dim Sum1
Dim Sum2
Dim Sum3
Dim Sum4
Dim Sum5
Dim Sum6
Dim Sum7
N = 5
a = 0
L = 4
I = 1

Sum1 = Cells(N - 1, 38).Value
Sum2 = Cells(N - 1, 39).Value
Sum3 = Cells(N - 1, 40).Value
Sum4 = Cells(N - 1, 41).Value
Sum5 = Cells(N - 1, 42).Value
Sum6 = Cells(N - 1, 43).Value
Sum7 = Cells(N - 1, 44).Value

While N < 2000
Boucle:
While Hour(Cells(N, 1).Value) = Hour(Cells(N - 1, 1).Value)
If Cells(N - 1, 10).Value > 90 Then
If Hour(Cells(N - 1, 1).Value) <> Hour(Cells(N + 3, 1).Value) Then
Cells(L, 59) = Cells(N - 1, 1).Value - (Minute(Cells(N - 1, 1)) / 1440)
Cells(L, 60).Value = Sum1 / I
Cells(L, 61).Value = Sum2 / I
Cells(L, 62).Value = Sum3 / I
Cells(L, 63).Value = Sum4 / I
Cells(L, 64).Value = Sum5 / I
Cells(L, 65).Value = Sum6 / I
Cells(L, 66).Value = Sum7 / I
L = L + 1
Sum1 = 0
Sum2 = 0
Sum3 = 0
Sum4 = 0
Sum5 = 0
Sum6 = 0
Sum7 = 0
N = N + 3
I = 1
GoTo Boucle
End If

N = N + 3
Sum1 = Sum1 + Cells(N, 38).Value
Sum2 = Sum2 + Cells(N, 39).Value
Sum3 = Sum3 + Cells(N, 40).Value
Sum4 = Sum4 + Cells(N, 41).Value
Sum5 = Sum5 + Cells(N, 42).Value
Sum6 = Sum6 + Cells(N, 43).Value
Sum7 = Sum7 + Cells(N, 44).Value
I = I + 1
N = N + 1
Else
Sum1 = Sum1 + Cells(N, 38).Value
Sum2 = Sum2 + Cells(N, 39).Value
Sum3 = Sum3 + Cells(N, 40).Value
Sum4 = Sum4 + Cells(N, 41).Value
Sum5 = Sum5 + Cells(N, 42).Value
Sum6 = Sum6 + Cells(N, 43).Value
Sum7 = Sum7 + Cells(N, 44).Value
N = N + 1
I = I + 1
End If
Wend

Cells(L, 59) = Cells(N - 1, 1).Value - (Minute(Cells(N - 1, 1)) / 1440)
Cells(L, 60).Value = Sum1 / I
Cells(L, 61).Value = Sum2 / I
Cells(L, 62).Value = Sum3 / I
Cells(L, 63).Value = Sum4 / I
Cells(L, 64).Value = Sum5 / I
Cells(L, 65).Value = Sum6 / I
Cells(L, 66).Value = Sum7 / I
L = L + 1
Sum1 = Cells(N, 38).Value
Sum2 = Cells(N, 39).Value
Sum3 = Cells(N, 40).Value
Sum4 = Cells(N, 41).Value
Sum5 = Cells(N, 42).Value
Sum6 = Cells(N, 43).Value
Sum7 = Cells(N, 44).Value
N = N + 1
I = 1

Wend

End Sub


P.S: pour les puristes, je sais que je ne devrais pas utiliser GoTo, mais je débute en VB! :-)
P.S2: je suis sous mac office 2011
 
Bonsoir,

Là j'ai pas le courage de regarder en profondeur, par contre si je peux te donner un conseil, donne un type à tes variables au moment de l'initialisation, de un ça va accélérer les traitements et de deux ça t'évitera ce genre d'erreur car le compilateur va criser au lieu de te laisser la surprise à l'execution

par exemple;
Dim cellule as range
Dim i as Integer

:zen:
 
Est-ce que tu peux donner quelques indications sur le type de données concernés, qu'on puisse reconstruire le tableau ? Il semble qu'il y ait des données d'heures dans certaines (colonne A) et d'autres données dans d'autres (colonnes AL et suivantes). Pas sûr d'avoir tout bien vu tout de même...

Ceci dit, il semble que tu additionnes les valeurs dans des cellules de la feuille. Je ne sais pas si ça présente un intérêt pour la suite mais le traitement serait certainement bien plus rapide si tu faisais les opération dans une matrice (une feuille virtuelle, en quelque sorte)
 
Alors, en A, il s'agit bien d'une date et d'une heure "dd/mm/yy hh/mm". Toutes les autres colonnes contiennent des valeurs numériques.
J'ai des 7 mesures qui sont effectuées toutes les 5 min (colonnes 38 à 44), et je veux faire les moyennes horaires. La petite complication est que par moment (lorsque la colonne 10 est supérieur a 90), il y a des trous dans les données (généralement 15 min, soit 3*5min); d'ou l'incrémentation un peu spéciale (N=N+3)
Pour simplifier, je remet la macro, mais avec le calcul pour une mesure (et non les 7)

Sub Total()

Dim N
Dim a
Dim L
Dim I
Dim Sum1
N = 5
a = 0
L = 4
I = 1

Sum1 = Cells(N - 1, 38).Value

While N < 2000
Boucle:
While Hour(Cells(N, 1).Value) = Hour(Cells(N - 1, 1).Value) 'repérage des valeurs pour la même heure'
If Cells(N - 1, 10).Value > 90 Then 'détection du "trou" de 15 min'
If Hour(Cells(N - 1, 1).Value) <> Hour(Cells(N + 3, 1).Value) Then 'si on a un changement d'heure pendant le trou'
Cells(L, 59) = Cells(N - 1, 1).Value - (Minute(Cells(N - 1, 1)) / 1440) 'RESULTAT: donne l'heure tronquée'
Cells(L, 60).Value = Sum1 / I 'RESULTAT: donne la valeur de la moyenne horaire'
L = L + 1
Sum1 = 0
N = N + 3
I = 1
GoTo Boucle
End If

N = N + 3 ''s'il n'y a pas de changement d'heure, on saute le trou'
Sum1 = Sum1 + Cells(N, 38).Value
I = I + 1
N = N + 1

Else 'quand il n'y a pas de trou'
Sum1 = Sum1 + Cells(N, 38).Value ''on incrémente normalement'
N = N + 1
I = I + 1
End If
Wend

Cells(L, 59) = Cells(N - 1, 1).Value - (Minute(Cells(N - 1, 1)) / 1440) 'calcul de l'heure tronquée'
L = L + 1
Sum1 = Cells(N, 38).Value 'réinitialisation de la moyenne'

N = N + 1
I = 1

Wend

End Sub
 
Bon, on y voit un peu plus clair, et la deuxième macro est sensiblement plus rapide à l'exécution (puisqu'elle n'inscrit plus grand chose dans la feuille).

Les deux souffrent du même problème : une fois lancées, elles traitent toute la feuille et butent après la dernière ligne, quand N prend la valeur 65537 (!) Il faut que tu bornes les valeurs de façon plus efficace : dans ton exemple, ton "While N < 2000" n'empêche pas la "Boucle" de s'exécuter jusqu'au bout de le feuille, puisque elle ne repasse pas sur la ligne qui la limiterait. D'autant plus que ton "GoTo Boucle" est positionné avant les "End If", ce qui rajoute certainement à la confusion, toutes ces instructions étant entrecroisées...

Essaye plutôt de modifier ta macro en essayant de bien voir pas à pas comment elle va s'exécuter. Mets des points d'arrêt, exécute pas à pas, tu verras à partir d'où elle remonte et tu comprendras pourquoi elle exécute telle instruction et pas telle autre.


Note : au lieu de la limiter "en dur", tu peux limiter la valeur max de N en testant les lignes utilisées, par exemple en déterminant la dernière ligne via une instruction du type :
DerniereLigne = Sheets("MaFeuille").Range("A1").End(xlDown).Row

Pour le reste, oui, tu as intérêt à définir tes variables