[VBA Excel] Problème de rapidité boucle for

Résolu
Bonjour,

J'ai créé ma boucle, mais elle dure beaucoup trop longtemps. C'est pourquoi je viens vous demander si vous voyez comment "raccourcir" le processus....

Petite explication :
Je travaille dans une table qui contient les données a (numéro de personne), b (chiffre)
Une table parallèle contient les donnée a (numéro de personne) et c (chiffre)

Pour chaque variable a, il existe plusieurs variables c. (table1)
Exemple:

col.a col.b
123 1
123 2
123 3
123 4
123 5

Et pour chaque variable a, il existe une variable b. (table2)
Exemple:
col.a col.b
123 5

Je veux que mon programme vérifie si la variable b est contenu dans les variables c pour la même variable a et me rajoute une valeur fixe "(2x)" à un endroit particulier...

Mon code marche très bien mais il met une éternité (et c'est peu dire) en sachant qu'il y a environ 25'000 lignes dans la table1 et 4000 dans la table2.

Pour améliorations, j'ai pensé à mettre un filtre qui me sort la variable c et ensuite avoir 20 lignes à tester à la place de 25'000, mais je me souviens avoir eu un problème avec les boucles for qui prennent même les lignes filtrées...

Ou alors allez directement à un ID sans devoir passer par toutes les lignes, mais je ne sais pas si c'est possible...

Avez-vous des idées ?

Mon code : 

        Worksheets(ClasseName).Activate
        Module = Cells(5, 6)
        Nb_Lignes6 = Range("A65536").End(xlUp).Row
        For f = 10 To Nb_Lignes6
            Worksheets(ClasseName).Activate
            ID = Cells(f, 7)
            For g = 2 To Nb_Lignes7
                Range("A" & g).Select
                Sheets("suivis").Activate
                If Cells(g, 1).Value = ID Then
                    If Cells(g, 2).Value = Module Then
                        Worksheets(ClasseName).Activate
                        Cel = Cells(f, 4).Value
                        If Cel = "" Then
                            Cells(f, 4) = "(2x)"
                        Else
                            Cells(f, 4) = Cel & " (2x)"
                        End If
                    End If
                End If
            Next g
        Next f
Configuration: Windows XP
Firefox 2.0.0.14

3 réponses

  1. Contributeur
    Bonsoir,

    Sinon le plus rapide (enfin peut-être pas là puisque tu es passé à 25 lignes mais ça te servira pê plus tard) c'est de travailler en mémoire et non pas sur les feuilles.
    Le plus simple est de nommer la(les) plage(s) où sont les données pour pouvoir la modifier sans modifier le code vba puis :
    dim datas 'pas de () et le laisser variant
    datas=range("maplage")
    et travailler de datas(1,1) à datas(nblignes,nbcolonnes)
    et s'il faut tout mettre à jour à la fin :
    range("ou tu veux mais la bonne taille") = datas
    Si c'est une mise à jour partielle se remplir un tableau de la bonne dimension et même technique.

    Là la gain est plus près de 100 que de 10. Considérable !!!
    eric
    1. Contributeur
      re:

      regarde ma procedure, je t'ai dit qu'il ne fallait pas travailler sur les lignes, car meme si elles sont masquées, elles sont toujours là et ca risque de poser des problemes
      pour travailler sur les filtres il faut travailler sur les cellules
      1 recuperer uniquement les lignes qui restent visibles, mais on ne va recuperer qu'une seule colonne à toi de choisir

      set maplage = sheets("Suivi").range("A1:A" &  _
           sheets("Suivi").range("A65536").end(xlup).row).cells.specialcells(Xlcelltypevisible)

      avec cette ligne je cree une plage "maplage" des cellules visible de la colonne A

      ensuite je travail avec une boucle sur cellule en gerant encore une fois un objet cellule
      For eac cel in maplage
      cel prend donc la place de la premiere cellule et evoluera au next cel est un objet Range ce qui implique que je puex l'utiliser des ces facons :
      If cel.value = "Taratata" then Cel.offset(0,4) = "Tutifruti"
      si la valeur de cel = taratata alors comme cel = cellule de la colonne a : mise à jour d'un offset(0,4) soiit colonne D

      ensuite je boucle avec next
      1. Contributeur
        bonjour

        deja en supprimant les Activate et select ca devrait aller plus vite, mais le mieux est tout de meme un filtre

                With Worksheets(ClasseName)
                Module = Cells(5, 6)
                Nb_Lignes6 = .Range("A65536").End(xlUp).Row
                For f = 10 To Nb_Lignes6
                    ID = .Cells(f, 7)
                    For g = 2 To Nb_Lignes7
                        Sheets("suivis").Activate
                        If Sheets("suivis").Cells(g, 1).Value = ID Then
                            If Sheets("suivis").Cells(g, 2).Value = Module Then
                                Cel = .Cells(f, 4).Value
                                If Cel = "" Then
                                    .Cells(f, 4) = "(2x)"
                                Else
                                    .Cells(f, 4) = Cel & " (2x)"
                                End If
                            End If
                        End If
                    Next g
                Next f
                end with


        pour utiliser les lignes d'un filtre il est preferable de travailler sur un objet range

        dim maplage as range
        dim cel as range
        sheets("Suivi").range("A1").filtered Field:=1 criteria1:=Sheets(Codename).cells(5,6).value
        set maplage = sheets("Suivi").range("A1:A" & sheets("Suivi").range("A65536").end(xlup).row).cells.specialcells(Xlcelltypevisible)
        for each cel in maplage
             if cel.offset(0,4) = "truc" then
             end if
        next


        procedure ecrite à main levée, non testée
        1. J'ai modifié quelque peu, mais le filtre donne juste.

          Je me retrouve donc avec un filtre qui marche, mais comment reprendre les valeurs sorties du filtres... avec une boucle for du type

          for a=2 to nb_lignes
          next a

          les nb_lignes vient le nombre total et non le nombre de lignes affichées...

          Y a-t'il une possibilité de trouver le nombre de lignes affichées ?

          Egalement y a-t'il une possibilité de créer une boucle sur les lignes affichées?

          Merci d'avance d'éclairer ma méconnaissance :s