[VBA Excel] Problème de rapidité boucle for
Résolu
saian-sugus
Messages postés
34
Date d'inscription
Statut
Membre
Dernière intervention
-
eriiic Messages postés 24603 Date d'inscription Statut Contributeur Dernière intervention -
eriiic Messages postés 24603 Date d'inscription Statut Contributeur Dernière intervention -
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 ?
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 ?
A voir également:
- [VBA Excel] Problème de rapidité boucle for
- Downloader for pc - Télécharger - Téléchargement & Transfert
- Liste déroulante excel - Guide
- Word et excel gratuit - Guide
- Déplacer colonne excel - Guide
- Si ou excel - Guide
3 réponses
bonjour
deja en supprimant les Activate et select ca devrait aller plus vite, mais le mieux est tout de meme un filtre
pour utiliser les lignes d'un filtre il est preferable de travailler sur un objet range
procedure ecrite à main levée, non testée
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
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
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
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
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
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
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