Anomalie de fonctionnement de la méthode Find de VBA/Excel

Résolu
ucfoutu
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
- 16 oct. 2013 à 14:01
ucfoutu
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
- 17 oct. 2013 à 11:35
Bonjour,
L'ouverture de cette discussion fait suite à une observation que j'ai signalée aujourd'hui dans cette autre discussion :
http://codes-sources.commentcamarche.net/forum/affich-10008955-trouver-les-cellules-contenant-un-mot?page=2#29

J'y promettais une démonstration, que voici :

Ouvrons un classeur vierge.
Sur sa feuille Feuil1, insérons deux boutons de commande CommandButton1 et CommandButton2 et ce code :


Private Sub CommandButton1_Click()
  Range("A1:A2").NumberFormat = "dd/mm/yyyy hh:mm:ss;@ "
  Range("A1").Value = DateAdd("s", 3, Now)
  Range("A2").Value = Now
End Sub

Private Sub CommandButton2_Click()
  Dim q As Range, Z As Date
  Z = CDate(WorksheetFunction.Min(Range("A1:A2")))
  Set q = Range("A1:A2").Find(Z)
  If Not q Is Nothing Then MsgBox q.Address Else MsgBox "pas trouvé"
End Sub


Bien ! cliquons sur CommandButton1 === On obtient deux dates dans la plage A1:A2. La plus petite ayant été mise en A2, n'est-ce pas ?

Cliquons maintenant sur CommanButton2 ===>> la ligne 2 est bien trouvée (celle de la plus petite date) ==>> parfait parfait !
Recommençons à cliquer autant que l'on veut sur commandbutton2 ===>> impeccable !

Amusons-nous maintenant à modifier ainsi l'évènement click de Commandbutton2

Private Sub CommandButton2_Click()
   Dim q As Range, Z As Date
  Z = CDate(WorksheetFunction.Min(Range("A1:A2")))
  Set q = Range("A1:A2").Find(Z, LookIn:=xlValues)
  If Not q Is Nothing Then MsgBox q.Address Else MsgBox "pas trouvé"
End Sub

Comme nous le voyons, nous n'avons que spécifié la constante à attribuer à lookin, n'est pas ?

Cliquons donc maintenant sur CommanButton2 ===>> message "pas trouvé" !

Mais le plus fort, maintenant :
enlevons notre petite modif précédente et réécrivons ce qui fonctionnait avant, à savoir, donc :

Private Sub CommandButton2_Click()
  Dim q As Range, Z As Date
  Z = CDate(WorksheetFunction.Min(Range("A1:A2")))
  Set q = Range("A1:A2").Find(Z)
  If Not q Is Nothing Then MsgBox q.Address Else MsgBox "pas trouvé"
End Sub


On se dit que rien ne devrait s'opposer à ce que cela "marche", maintenant, puisque remis comme avant ?
===>> Ben non ! Pas du tout ===>> message "pas trouvé"
Et ce sera ainsi sans cesse dorénavant pour ce classeur !
Pour retrouver la première situation, pas d'autre solution que de le quitter et tout recommencer !
Voilà voilà ! C'est là une démo du comportement dénoncé et non son explication, que j'ignore !

1 réponse

jordane45
Messages postés
36030
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
7 août 2022
358
Modifié par jordane45 le 16/10/2013 à 14:04
Je pense que ta réponse est dans le second lien.

Concernant la recherche de Dates, je vous invite à lire ceci :
/>Using Excel Find Method to Search for a Date

et un autre petit article qui peut aussi vous interesser :
Pourquoi utiliser XlFormulas ou XlValues ?

Cordialement,
Jordane
0
ucfoutu
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
235
Modifié par ucfoutu le 16/10/2013 à 14:12
Rien n'explique ce que je dénonce en priorité : l'impossibilité de revenir en arrière !
Car c'est là, le plus étonnant de l'affaire, Jordane45

Une fois tenté une seule fois (le code avec xlValues) , on est "fichu" et on ne peut plus revenir, quoi que l'on fasse, au bon fonctionnement du code sans xvalues !
Sauf à quitter et tout reprendre à zéro !
Tu as l'explication à ce phénomène, toi ? Pas moi ...
0
ucfoutu
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
235
Modifié par ucfoutu le 16/10/2013 à 14:29
La seule hypothèse (car ce ne peut être qu'une malheureuse hypothèse, que seuls les développeurs de OFFICE/EXCEL ont la possibilité de vérifier ou infirmer) c'est qu'une espèce d'indexation (laquelle et comment et où ?????) a été faite et que personne n'a prévu sa réversibilité !!! Une espèce de "tare" devenue "indélébile", quoi (par analogie) ...
C'est tout simplement surprenant !
0
ucfoutu
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
235
16 oct. 2013 à 17:57
Bon..
Je ne parviens pas à trouver une explication certaine au phénomène exposé plus haut.
Je viens par contre de trouver une parade.
Elle est tortueuse, mais sans faille, au moins :
Private Sub CommandButton2_Click()
  Dim q As Range, Z As String
  Z = CStr(CDate(WorksheetFunction.Min(Range("A1:A2"))))
  Set q = Range("A1:A2").Find(Z, LookIn:=xlValues)
  If Not q Is Nothing Then MsgBox q.Address Else MsgBox "pas trouvé"
End Sub


Je répète : il s'agit là d'une parade. Et rien d'autre qu'une parade.
Le mystère reste entier en ce qui concerne la non possibilité décrite plus haut de faire "revivre" le code qui marchait avant l'emploi de xlValues ...
0
ucfoutu
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
235
16 oct. 2013 à 18:04
Le mystère (la vraie raison de cette discussion) restant entier, je ne peux cliquer sur le tag "Résolu" pour clore.
Une parade a certes été ainsi mise en place, mais elle n'est pas l'explication du phénomène (la seule pouvant faire que je clique sur "résolu").
0
ucfoutu
Messages postés
18038
Date d'inscription
lundi 7 décembre 2009
Statut
Modérateur
Dernière intervention
11 avril 2018
235
Modifié par ucfoutu le 17/10/2013 à 11:16
Coucou,
La découverte de ce phénomène m'empêche de bien dormir...
J'ai donc passé beaucoup de temps à faire des essais dans tous les sens et en suis arrivé aux conclusions suivantes :
VBA/Excel mémorise la dernière valeur affectée à l'argument Lookin et s'en sert comme valeur par défaut (lorsque, donc, cet argument n'est pas spécifié) pour toutes les utilisations ultérieures de la méthode Find
Reprenons maintenant la démonstration (mon tout premier message) de l'existence du phénomène.
1) La toute première utilisation de la méthode Find n'utilisait pas l'argument Lookin ===>> VBA, qui n'avait donc encore rien mémorisé pour Lookin, lui à spontanément (programmé par l'équipe microsoft ?) attribué une valeur par défaut (inconnue de nous) qui a permis le succès du Find
2) la seconde utilisation (en spécifiant Lookin = xlValues) a abpouti à un échec, mais a également entraîné la mise en mémoire de xlValues comme valeur par défaut de Lookin.
3) lorsque nous avons "rétabli" le code qui marchait (le 1er), donc sans spécifier l'argument Lookin ===>> VBA lui a d'office attribué la valeur par défaut (xlValues) qu'il avait mémorisée.

Que nous dit maintenant l'aide VBA pour ce qui est des valeurs possibles pour l'argument Lookin ? ===>>
xlComments -4144 Commentaires.
xlFormulas -4123 Formules.
xlValues -4163 Valeurs.


Il y en a pourtant une autre, qui nous est cachée puisque le tout premier code fonctionnait alors que l'argument lookin n'avait aucune de ces 3 valeurs, ni ne devrait logiquement pouvoir fonctionner, d'ailleurs, avec aucune de ces 3 valeurs (puisque les données traitées ne sont ni des formules, ni des commentaires.. et que, comme nous l'avons vu, xlValues provoque l'échec !

Chercher quelle est cette valeur "cachée" ne va pas être une partie de plaisir, mais je vais malgré tout essayer de la trouver
0