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 If

Lorsque 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 If

Cordialement,

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 toutes mes confuses !

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

Rechercher des sujets similaires à "optimisation boucle"