annyong
Messages postés38Date d'inscriptionlundi 23 avril 2007StatutMembreDernière intervention25 février 2015
-
23 avril 2007 à 22:27
outofbusiness -
25 avril 2007 à 10:43
Bnjour à tous !
je vous explique mon problème :
j'ai une boucle while, et dans cette boucle un find.
while ActiveCell<> Cells(NumLigne,4)
ActiveCell.select
Selection.FindNext(After:=ActiveCell).Activate
Wend
je souhaite en effet parcourir une colonne qui contient plusieurs fois la meme valeur (Cells(NumLigne,4)).
Le pbm c'est que, si Cells(NumLigne,4) n'est pas trouvée, une fois que la boucle a atteint la derniere valeur de la colonne, le findnext repasse a la premiere valeur deja testee.
en gros, je ne sors pas de la boucle.
Comment en sortir SVP une fois la derniere valeur de la colonne testée?
chaibat05
Messages postés1883Date d'inscriptionsamedi 1 avril 2006StatutMembreDernière intervention20 novembre 20072 23 avril 2007 à 23:44
Bonsoir mortalino,
je pense qu' il faut tester si on est arrivé au bout...
while ActiveCell.Address <> CellStart
Selection.FindNext(After:=ActiveCell).Activate
' > ici
Wend
ou alors commencer la boucle par ça
Do While ActiveCell.Address <> CellLeBout
Selection.FindNext(After:=ActiveCell).Activate
Loop
mortalino
Messages postés6786Date d'inscriptionvendredi 16 décembre 2005StatutMembreDernière intervention21 décembre 201118 23 avril 2007 à 23:52
Bonsoir Chaibat05,
J'arrive pas à m'imaginer ton "ICI"
Tu veux mettre quoi ?
pour mon code, la verif se fait avec le While
while ActiveCell.Address <> CellStart
Mais je crains que cette ligne fasse tout sauter, car précédamment beh c'est CellStart qui est sélectionnée.
@++
<hr width="100%" size="2" />
--Mortalino--
Le mystérieux chevalier, ~Provençal, le Gaulois~
mortalino
Messages postés6786Date d'inscriptionvendredi 16 décembre 2005StatutMembreDernière intervention21 décembre 201118 24 avril 2007 à 00:05
Ah Ok, mais comment faire pour savoir que tu es au bout ?
D'après mes tests (quand j'ai fait le snippet), je n'arrivais à savoir que si je revenais à la première cellule.
Par contre, je viens de tester un truc, et ça fonctionne :
If Range("A1").Address < Range("IV65535").Address Then MsgBox "ok"
on peut aussi s'en servir :
cs_MPi
Messages postés3877Date d'inscriptionmardi 19 mars 2002StatutMembreDernière intervention17 août 201823 24 avril 2007 à 00:11
Chaibat, je pense que tu as en partie raison à cause du (After:=ActiveCell).Activate Je n'ai pas testé, par contre.
De la façon dont je procède, je n'utilise pas ce After et donc la boucle (FindNext) revient au début et s'arrête sur la valeur de départ comme le spécifie Mortalino...
chaibat05
Messages postés1883Date d'inscriptionsamedi 1 avril 2006StatutMembreDernière intervention20 novembre 20072 24 avril 2007 à 00:11
il faut référencer CellBout comme tu l' as fait avec CellStart
Mais pour celà tu dois avoir au départ une idée de la dernière cellule
pour éviter d' aller jusqu' à IV65535
chaibat05
Messages postés1883Date d'inscriptionsamedi 1 avril 2006StatutMembreDernière intervention20 novembre 20072 24 avril 2007 à 01:07
petite explication,
'première recherche
Selection.FindNext(After:=ActiveCell).Activate
'>soit on a rien trouvé et qu' on s' est positionné de nouveau sur CellStart
'dans ce cas on entre pas dans la boucle
'>soit on a trouvé une première occurence et dans ce cas on est plus sur CellStart
'on entre donc dans la boucle.
' si on revient à CellStart, on quitte automatiquement
while ActiveCell.Address <> CellStart
Selection.FindNext(After:=ActiveCell).Activate
Wend
mortalino
Messages postés6786Date d'inscriptionvendredi 16 décembre 2005StatutMembreDernière intervention21 décembre 201118 24 avril 2007 à 01:13
Ok,
tu remarqueras que j'ai changé Selection par Cells. Sinon, on ne rentre jamais dans la condition (il recherche dans la cellule déjà active, donc inutile)
Idem dans la boucle, (me suis tapé une boucle infinie )
@++
<hr width="100%" size="2" />
--Mortalino--
Le mystérieux chevalier, ~Provençal, le Gaulois~
chaibat05
Messages postés1883Date d'inscriptionsamedi 1 avril 2006StatutMembreDernière intervention20 novembre 20072 24 avril 2007 à 01:23
je pense que la différence vient du fait que dans While tu fais appel à
FindNext alors que dans For Each il n' y a qu' une comparaison.
Constat: il faut éviter, tant qu' on peut , les appels à des fonctions
mortalino
Messages postés6786Date d'inscriptionvendredi 16 décembre 2005StatutMembreDernière intervention21 décembre 201118 24 avril 2007 à 01:30
Bah tu vas rire, c'est bon mais c'est pas bon
Dans le cas où il y a des centaines ou des milliers de valeurs correspondant avec le critère de recherche, c'est le For .. Each qui l'emporte (comme dans mon exemple).
A l'inverse, s'il n'y a qu'une valeur correspondant (pour vérifier j'ai mis aa en E1000)
C'est le .Find qui gagne (0.03 sec contre 0.14 ; toujours en partant de mon exemple).
@++
<hr width="100%" size="2" />
--Mortalino--
Le mystérieux chevalier, ~Provençal, le Gaulois~
cs_MPi
Messages postés3877Date d'inscriptionmardi 19 mars 2002StatutMembreDernière intervention17 août 201823 24 avril 2007 à 23:40
Mortalino, j'ai essayé tes 2 procédures et ton temps est plus lent que chez moi, probablement parce que tu visionnais la fenêtre "Exécution" pendant la macro
J'en ai ajouté une à la fin avec mes temps avec et sans visualisation
Et j'ai ajouté un Range("A1").select au début de chacune des routimes pour être certain que le départ se faisait au même endroit
Debug.Print CellStart
While ActiveCell.Address <> CellStart
Cells.FindNext(After:=ActiveCell).Activate
Debug.Print ActiveCell.Address
Wend
MsgBox Timer - Start
' 10.75 secondes mes temps sans visualisation 6.44 8.46 avec visualisation 13.09
End Sub
Sub test2()
Dim MyRange As Range, Start As Single
Range("A1").Select
Start = Timer
For Each MyRange In ActiveSheet.UsedRange
If MyRange.Value = "abc" Then Debug.Print MyRange.Address
Next MyRange
Set MyRange = Nothing
MsgBox Timer - Start
' 7.67 secondes mes temps sans visualisation 1.5 1.6 avec visualisation 6.99
End Sub
Sub test3()
Dim Recherche As Range, Adresse As String, Start As Single
Range("A1").Select
Start = Timer
Set Recherche = Cells.Find("abc")
If Not Recherche Is Nothing Then
Adresse = Recherche.Address
Do
Set Recherche = Cells.FindNext(Recherche)
Loop While Not Recherche Is Nothing And Recherche.Address <> Adresse
End If
MsgBox Timer - Start
' 1.2 sec 1.17 1.18 avec et sans visualisation de la fenêtre Exécution
End Sub
cs_MPi
Messages postés3877Date d'inscriptionmardi 19 mars 2002StatutMembreDernière intervention17 août 201823 24 avril 2007 à 23:44
whaaaaarffff, j'avais oublié de mettre le debug.print <= vilain garnement, tricheur !!!
Donc, mon temps est de plus ou moins 5 sec sans visualiser la fenêtre debug et autour de 10 en la visualisant....
mortalino
Messages postés6786Date d'inscriptionvendredi 16 décembre 2005StatutMembreDernière intervention21 décembre 201118 25 avril 2007 à 00:00
Haaa, tu m'a fais peur, j'ai cru que j'avais un trojan !
D'autant plus que je suis sous xp sp2, 2.6 GHz, office 03 / 07
D'ailleurs étonnament, c'est plus rapide sous Excel 2003 que 2007
Par contre avec un Application.ScreenUpdating = False, pour le premier test, je gagne 33 % de temps d'exécution
@++
<hr width="100%" size="2" />
--Mortalino--
Le mystérieux chevalier, ~Provençal, le Gaulois~