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

Résolu/Fermé
saian-sugus Messages postés 34 Date d'inscription jeudi 24 juillet 2008 Statut Membre Dernière intervention 20 avril 2010 - 24 sept. 2008 à 08:55
eriiic Messages postés 24570 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 23 avril 2024 - 24 sept. 2008 à 20:20
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 ?

A voir également:

3 réponses

wilfried_42 Messages postés 907 Date d'inscription mardi 19 août 2008 Statut Contributeur Dernière intervention 8 décembre 2009 243
24 sept. 2008 à 09:15
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
saian-sugus Messages postés 34 Date d'inscription jeudi 24 juillet 2008 Statut Membre Dernière intervention 20 avril 2010
24 sept. 2008 à 14:47
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
0
wilfried_42 Messages postés 907 Date d'inscription mardi 19 août 2008 Statut Contributeur Dernière intervention 8 décembre 2009 243
24 sept. 2008 à 18:15
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
0
eriiic Messages postés 24570 Date d'inscription mardi 11 septembre 2007 Statut Contributeur Dernière intervention 23 avril 2024 7 213
24 sept. 2008 à 20:20
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
0