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

Résolu/Fermé
Signaler
Messages postés
34
Date d'inscription
jeudi 24 juillet 2008
Statut
Membre
Dernière intervention
20 avril 2010
-
Messages postés
24221
Date d'inscription
mardi 11 septembre 2007
Statut
Contributeur
Dernière intervention
22 novembre 2021
-
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 ?

3 réponses

Messages postés
907
Date d'inscription
mardi 19 août 2008
Statut
Contributeur
Dernière intervention
8 décembre 2009
242
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
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 41989 internautes nous ont dit merci ce mois-ci

Messages postés
34
Date d'inscription
jeudi 24 juillet 2008
Statut
Membre
Dernière intervention
20 avril 2010

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
Messages postés
907
Date d'inscription
mardi 19 août 2008
Statut
Contributeur
Dernière intervention
8 décembre 2009
242
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
Messages postés
24221
Date d'inscription
mardi 11 septembre 2007
Statut
Contributeur
Dernière intervention
22 novembre 2021
6 974
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