Optimisation de boucle
Bonjour le forum,
Je cherche à optimiser ma boucle VBA car comme vous le verrez dans le code, la boucle parcourt toute la plage de cellules à chaque modification.
Explication du code : j'ai une plage de données Excel de 12 colonnes :
- si la cellule a un fond vert, c'est une formule
- si la cellule a un fond rouge, c'est une valeur rentrée à la main, et qui dépend d'un certain %
- si la cellule a un fond blanc, c'est une valeur rentrée à la main (qui dépend elle aussi d'un %)
Voici mon code (je ne peux pas joindre de fichier car dépasse la taille autorisée !) :
'******************************************************************************************
' Bout de code permettant de mettre en vert les cellules pour le CA (colonnes CC à CO)
'******************************************************************************************
'Si on ne modifie pas la plage de cellules CC6:CO(nbaffaires) alors on fait rien, sinon traitement
If Not (Intersect(Range("CC6:CO" & nb_aff), Target) Is Nothing) Then
' Partie CA
With f
Set Plage = .Range("CC6:CN" & nb_aff)
For Each Cell In Plage
If lire(Cell) = True And Not Cell.Interior.Color = xlNone And Not Cell.Interior.ColorIndex = 3 Then
' Si cest une formule (que ce n'est pas rentré à la main) : on met en vert
Cell.Interior.Color = RGB(135, 233, 144) 'vert
ElseIf Cell.Interior.ColorIndex = 3 Then 'rouge
' Sinon si c'est en rouge, on laisse en rouge
Cell.Interior.ColorIndex = 3
ElseIf Cell.Interior.Color = xlNone Then
' Sinon si c'est blanc, on laisse en blanc
Cell.Interior.Color = xlNone
Else
' Sinon on met en blanc
Cell.Interior.Color = xlNone
End If
Next
End With
End IfLorsque j'ai 50 lignes, ca peut aller, mais quand j'en ai 300, il parcourt à chaque fois la plage et ca devient trop lourd pour l'utilisateur. J'aimerais avoir vos conseils svp...
Cordialement,
Excellium
Salut Excellium,
Tu peux utiliser "GoTo" qui te permet de raccourcir ta boucle for si une condition est remplie. Je t'ai fait un exemple dans le fichier joint, voici le code avec des explications. En gros tu mets une étiquette avant le Next, et cette étiquette permet ensuite de sauter jusque là grace au Goto:
Comme ça dès qu'une condition est remplie, le code ne continue pas à checker les autres conditions et passe directement à la cellule suivante.
Sub test()
For v = 1 To 10
If Cells(v, 1) = "a" Then
Cells(v, 1).Interior.ColorIndex = 33
GoTo Suivant ' ICI TU FAIS REFERENCE A TON ETIQUETTE (une fois la condition remplie, saute le code jusqu'à l'étiquette "Suivant")
ElseIf Cells(v, 1) = "b" Then
Cells(v, 1).Interior.ColorIndex = 43
GoTo Suivant
ElseIf Cells(v, 1) = "c" Then
Cells(v, 1).Interior.ColorIndex = 44
GoTo Suivant
Else
Cells(v, 1).Interior.ColorIndex = 22
GoTo Suivant
End If
Suivant: 'ICI TU METS UNE ETIQUETTE (un mot avec le signe ":" au bout) POUR QUE LE CODE SAUTE JUSQU'ICI
Next
End Sub
Bonjour,
Une optimisation rapide en passant :
'Si on ne modifie pas la plage de cellules CC6:CO(nbaffaires) alors on fait rien, sinon traitement
If Not (Intersect(Range("CC6:CO" & nb_aff), Target) Is Nothing) Then
Application.ScreenUpdating = False 'A laisser si tu ne l'as pas déjà mis plus haut dans ta procédure
' Partie CA
With f
Set Plage = .Range("CC6:CN" & nb_aff)
For Each Cell In Plage
If lire(Cell) = True And Not Cell.Interior.Color = xlNone And Not Cell.Interior.ColorIndex = 3 Then ' Si cest une formule (que ce n'est pas rentré à la main) : on met en vert
Cell.Interior.Color = RGB(135, 233, 144) 'vert
ElseIf Cell.Interior.ColorIndex <> 3 Then ' Si pas rouge
Cell.Interior.ColorIndex = xlNone
End If
Next
End With
End IfCordialement,
Bonjour Gaz0line,
Gaz0line a écrit :Sub test() For v = 1 To 10 If Cells(v, 1) = "a" Then Cells(v, 1).Interior.ColorIndex = 33 GoTo Suivant ' ICI TU FAIS REFERENCE A TON ETIQUETTE (une fois la condition remplie, saute le code jusqu'à l'étiquette "Suivant") ElseIf Cells(v, 1) = "b" Then Cells(v, 1).Interior.ColorIndex = 43 GoTo Suivant ElseIf Cells(v, 1) = "c" Then Cells(v, 1).Interior.ColorIndex = 44 GoTo Suivant Else Cells(v, 1).Interior.ColorIndex = 22 GoTo Suivant End If Suivant: 'ICI TU METS UNE ETIQUETTE (un mot avec le signe ":" au bout) POUR QUE LE CODE SAUTE JUSQU'ICI Next End Sub
C'est une idée intéressante mais dans ton exemple (et celui de Excellium) ça n'accélère pas la boucle puisque toutes les instructions sont dans la condition IF (autrement dit, si l'une des conditions est validée, ça ne va de toute façon pas tester les autres et aller directement là où tu as placé ton "Suivant").
Cordialement,
Bonjour Sébastien et Gaz0line,
Je vais essayer vos 2 solutions, et je reviens vers vous. Merci de votre aide !!!
Sébastien a écrit :Bonjour Gaz0line,
C'est une idée intéressante mais dans ton exemple (et celui de Excellium) ça n'accélère pas la boucle puisque toutes les instructions sont dans la condition IF (autrement dit, si l'une des conditions est validée, ça ne va de toute façon pas tester les autres et aller directement là où tu as placé ton "Suivant").
Cordialement,
En effet
Re,
Voici mon retour : j'ai opté pour la solution de Sébastien ! En effet, c'est plus rapide !
Merci beaucoup Sébastien et Gaz0line pour votre aide