VBA - Recherche Find avec retour multiple [Résolu/Fermé]

Signaler
Messages postés
213
Date d'inscription
vendredi 28 novembre 2008
Statut
Membre
Dernière intervention
8 octobre 2019
-
Patrice33740
Messages postés
7919
Date d'inscription
dimanche 13 juin 2010
Statut
Membre
Dernière intervention
24 janvier 2020
-
Bonjour,
j'ai vu avec grand intérêt votre article sur les retours multiples :
http://www.commentcamarche.net/faq/18696-vba-recherche-find-avec-retour-multiple
Cependant, je voudrais renvoyé l'information d'une cellule, plutôt que l'adresse de la cellule trouvée.
Je maitrise mal les tableaux virtuels ; comment traduire Tb(i) (soit une référence sous forme $Col$Lg) en cells(1,tb(i)).
Autrement dit comment récupérer les N° de ligne dans Tb(i).
Merci de votre aide

8 réponses

Messages postés
7919
Date d'inscription
dimanche 13 juin 2010
Statut
Membre
Dernière intervention
24 janvier 2020
1 270
Bonjour,

Sans regarder ton fichier, la fonction Split permet d'extraire la ligne ou la colonne d'une adresse absolue :
Split("$B$12", "$")(1) donne la colonne (B)
Split("$B$12", "$")(2) donne la ligne (12)
1
Merci

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

CCM 83331 internautes nous ont dit merci ce mois-ci

Messages postés
9411
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
26 janvier 2020
499
bonjour, je pense que ceci te donne le numéro de ligne:
Range(Tb(i)).Row
1
Merci

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

CCM 83331 internautes nous ont dit merci ce mois-ci

Messages postés
7919
Date d'inscription
dimanche 13 juin 2010
Statut
Membre
Dernière intervention
24 janvier 2020
1 270
Bonjour,

Comme ceci, en adaptant FindRech au besoin :
Sub RechMulti()
Dim R As Long, TB()
Dim i As Integer, Rch As String
Rch = 22   'par exemple
  With Sheets("Feuil1")
    .Columns(7).ClearContents ' pour les résultats
    R = RechFind(Rch, .Range("B1:E500"), 2, TB())
    If R > 0 Then
      .Range("G1") = R & " Occurences trouvées pour : " & Rch
      .Range("G2").Resize(R, 1) = Application.Transpose(TB)
    Else
      MsgBox "Non trouvé", , "Recherche"
    End If
  End With
End Sub

Function RechFind(ByVal Cle$, ByVal Plage As Range, _
                  ByVal Col&, ByRef TBval()) As Long
'Retourne toutes les valeurs trouvées dans la recherche
'Clé   = valeur cherchée
'Plage = plage à parcourir.
'Col   = colonne contenant les valeurs à retourner.
'TBval = Tableau retournant les valeurs de la colonne Col.
Dim Cherche, Ix As Long, Adr
  With Plage
    Set Cherche = .Find(Cle, , xlValues, xlWhole)
    If Not Cherche Is Nothing Then
      Adr = Cherche.Address
      Do
        ReDim Preserve TBval(Ix)
        TBval(Ix) = Plage.Parent.Cells(Cherche.Row, Col)
        Set Cherche = .FindNext(Cherche)
        Ix = Ix + 1
      Loop While Not Cherche Is Nothing And Cherche.Address <> Adr
    End If
  End With
  'nombre d'occurence(s) trouvée(s), Retour 0 si aucune occurence
  RechFind = Ix
  Set Cherche = Nothing 'Libére la mémoire occupée par l'objet.
End Function
1
Merci

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

CCM 83331 internautes nous ont dit merci ce mois-ci

Mouftie
Messages postés
213
Date d'inscription
vendredi 28 novembre 2008
Statut
Membre
Dernière intervention
8 octobre 2019
8
Merci beaucoup Patrice, c'est très bien.
Messages postés
213
Date d'inscription
vendredi 28 novembre 2008
Statut
Membre
Dernière intervention
8 octobre 2019
8
Merci à vous tous,
les réponses de Patrice (1ere réponse) et de yg_be correspondent exactement ce que je cherchais
La 2ème réponse de patrice ne fonctionne pas ; elle me renvoie la même réponse autant de fois qu'il y a d’occurrences, et en plus la réponse est fausse.
En effet, Tb(i) prend la valeur recherchée
Messages postés
213
Date d'inscription
vendredi 28 novembre 2008
Statut
Membre
Dernière intervention
8 octobre 2019
8
Bonjour Michel et merci pour tes tutos.
Je cherche à récupérer, pour chaque occurrence trouvée, les données de la colonne"X" correspondant à la ligne trouvée.
C'est pourquoi les réponses de Patrice et de Yg_be m'ont parfaitement satisfaite.
Voici le code complet :
Sub RechMulti()
Dim R As Long, TB()
Dim i As Integer, Rch As String
Rch = 22 'par exemple
Sheets("Feuil1").Columns(7).ClearContents 'Colonne(7) pour les résultats
R = RechFind(Rch, ThisWorkbook.Name, "Feuil1", "B1:E500", TB())
If R > 0 Then
For i = 0 To R - 1 ' ou ubound(TB)
Sheets("Feuil1").Range("G1") = "Occurences trouvées pour : " & Rch
Sheets("Feuil1").Cells(i + 2, 7) = Cells(Range(TB(i)).Row, 2)
Next i
Else
MsgBox "Non trouvé", , "Recherche"
End If
End Sub

Par contre, je ne sais pas rechercher une valeur exacte, car dans cet exemple, cela me rapporte 122, 422, 220... j'ai essayé les "", mais cela ne change rien.

Enfin pour aller dans le sens de Patrice (2ème proposition) il fallait remplacer
TBadress(Ix) = Cherche.Address
par
TBadress(Ix) = Cherche.Row
J'ai bien compris vos propositions, je n'ai plus qu'à trouver le moyen de rechercher "exactement"
yg_be
Messages postés
9411
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
26 janvier 2020
499
suggestion:
Sheets("Feuil1").Range("G1") = "Occurences trouvées pour : " & Rch
For i = 0 To R - 1 ' ou ubound(TB)
            Sheets("Feuil1").Cells(i + 2, 7) = Cells(Range(TB(i)).Row, 2)
Next i
Messages postés
7919
Date d'inscription
dimanche 13 juin 2010
Statut
Membre
Dernière intervention
24 janvier 2020
1 270
Re,

Sinon, tu peux modifier le module pour qu'il renvoie la valeur au lieu de l'adrsse, il suffit de remplacer:
TBadress(Ix) = Cherche.Address
par
TBadress(Ix) = Cherche.Value 

Messages postés
16047
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
25 janvier 2020
2 856
Bonjour,

je comprend mal ce que tu cherche à faire puisque tu veux la valeur et non l'adresse
si dans la démo citée tu cherches toutes les valeurs 12 la réponse sera 12 !
à moins que 12 soit inclus dans d'autres caractères par ex "azerty12uiop"

le mieux serait que tu joignes ton classeur
Mettre le classeur sans données confidentielles en pièce jointe sur « mon-partage.fr »
et faire un clic droit-coller le raccourci dans votre message


et que tu expliques ce que tu veux obtenir


 Michel
yg_be
Messages postés
9411
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
26 janvier 2020
499 > Patrice33740
Messages postés
7919
Date d'inscription
dimanche 13 juin 2010
Statut
Membre
Dernière intervention
24 janvier 2020

sauf en lisant jusqu'à la fin, où tout s’éclaircit.
Patrice33740
Messages postés
7919
Date d'inscription
dimanche 13 juin 2010
Statut
Membre
Dernière intervention
24 janvier 2020
1 270 > yg_be
Messages postés
9411
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
26 janvier 2020

Non, pas vraiment, le n° de ligne c'est pour récupérer l'information de la cellule:
« comment traduire Tb(i) (soit une référence sous forme $Col$Lg) en cells(1,tb(i)).»
Et là je rejoins michel, je ne comprend pas ce qu'il cherche à faire puisque la valeur de la cellule c'est celle qu'il a cherché !
yg_be
Messages postés
9411
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
26 janvier 2020
499 > Patrice33740
Messages postés
7919
Date d'inscription
dimanche 13 juin 2010
Statut
Membre
Dernière intervention
24 janvier 2020

il me semble clair dans l'exemple qu'il souhaite faire quelque chose comme
cells(Range(Tb(i)).Row, 1).
Patrice33740
Messages postés
7919
Date d'inscription
dimanche 13 juin 2010
Statut
Membre
Dernière intervention
24 janvier 2020
1 270 > yg_be
Messages postés
9411
Date d'inscription
lundi 9 juin 2008
Statut
Contributeur
Dernière intervention
26 janvier 2020

Exactement, et dans la cellule, il y a la valeur cherchée !
Mouftie
Messages postés
213
Date d'inscription
vendredi 28 novembre 2008
Statut
Membre
Dernière intervention
8 octobre 2019
8
Pour l’instant, je n'ai pas commencé mon travail, je vais devoir utiliser la fonction recherche, donc je l'étudie. pour ce faire, j'ai utilisé le fichier joint avec le tuto (http://www.cjoint.com/c/FDwkAUCQ1rE)
Messages postés
16047
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
25 janvier 2020
2 856
recherchefind est une usine à gaz affreuse et compliquée

puisque mouftie veut les lignes dans la colone G où il y a la ref cherchée

Option Explicit
Const Ref As Integer = 12 'par ex
'------------
Sub rechercher_ref()
Dim Zone As Range, Cellule As Range
Dim Nbre As Integer
Dim T_out, Cptr As Integer
'Dim test
Application.ScreenUpdating = False
Columns("G").Clear
Set Zone = Range("B1:E500")

Nbre = Application.CountIf(Zone, Ref)
If Nbre = 0 Then GoTo vide
With Zone
Set Cellule = Zone.Find(what:=Ref, LookIn:=xlValues, lookat:=xlWhole)
For Cptr = 1 To Nbre
'test = Cellule.Address
Cells(Cptr, "G") = Cellule.Row
Set Cellule = .FindNext(Cellule)
Next
End With
'trie dans l'ordre croissant si la cellule B1 =ref (sinon la ligne 1 se trouve en bas
If Range("B1") = Ref Then
Range("G1:G" & Nbre + 1).Sort Key1:=Range("G1"), Order1:=xlAscending
End If
Exit Sub
'gestionnaire erreur
vide:
MsgBox Ref & " inconnu dans la zone"
End Sub


et la maquette:
https://mon-partage.fr/f/QCeLgCgv/
michel_m
Messages postés
16047
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
25 janvier 2020
2 856 > Patrice33740
Messages postés
7919
Date d'inscription
dimanche 13 juin 2010
Statut
Membre
Dernière intervention
24 janvier 2020

Bonjour Patrice,

et si il y a des REf(12 par ex) dans la colonne 2 du tableau (soit colonne C de la feuille) ?

j'ai l'impression que mouftie a mal défini ce qu'il voulait faire ??

toutefois, si on veut la valeur
Cells(Cptr, "G") = Cells(Cellule.Row,"C").value


D'ailleurs, pour utiliser la fonction "FIND", il vaut mieux utiliser
http://www.commentcamarche.net/faq/36886-vba-recherche-de-donnees-la-methode-find

que la solution proposée par Lhermite

enfin, compte tenu de la faible surface (B1:E500) soit 2000 cellules, il n'était pas nécessaire de passer par une variable - tableau plus difficile à comprendre (dixit Mouftie)

Bon WE
Patrice33740
Messages postés
7919
Date d'inscription
dimanche 13 juin 2010
Statut
Membre
Dernière intervention
24 janvier 2020
1 270
Bonjour Michel,
Bonjour le Forum,

Pour une recherche multiple dans une plage multi-colonnes, la méthode proposée par Lhermitte et le FindAll de Jordane sont identiques.
Et n'y a pas beaucoup de différence avec la méthode que tu proposes au post 17 ci-dessus, à part l’utilisation de « CountIf » à la place du « ...Address <> PrAddress » de Lhermitte, ce qui ne change rien en nombre de passage dans la boucle.

Par contre, ta méthode Find_Next ne fonctionne pas correctement avec une plage multi-colonnes, elle ne remplace le FindNext que dans le cas d'une colonne unique car elle ne trouve que la première occurrence sur la ligne.
Si effectivement, tu précises qu'elle « permet de lister les lignes d'une colonne », tu devrais cependant signaler qu'il ne faut pas l'utiliser pour une plage multi-colonnes.

Cdlt
Patrice
michel_m
Messages postés
16047
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
25 janvier 2020
2 856 > Patrice33740
Messages postés
7919
Date d'inscription
dimanche 13 juin 2010
Statut
Membre
Dernière intervention
24 janvier 2020

Par contre, ta méthode Find_Next ne fonctionne pas correctement avec une plage multi-colonnes

FAUX

avant d'affirmer, essaies plutôt la pièce jointe que j'ai remise qui parcours B1:E500
mais si yu veux avoir toujours raison, je te l'accorde: tu as raison

j'abandonne ce suivi

et c'est promis, je ne te dérangerai plus en intervenant dans tes discussions
Adieu
Patrice33740
Messages postés
7919
Date d'inscription
dimanche 13 juin 2010
Statut
Membre
Dernière intervention
24 janvier 2020
1 270 > michel_m
Messages postés
16047
Date d'inscription
lundi 12 septembre 2005
Statut
Contributeur
Dernière intervention
25 janvier 2020

Patrice33740
Messages postés
7919
Date d'inscription
dimanche 13 juin 2010
Statut
Membre
Dernière intervention
24 janvier 2020
1 270
Re,

Je comprend qu'accepter la critique est difficile même lorsque celle-ci est constructive, mais ta mauvaise foi est impressionnante !

Relis mon post, j'ai pas parlé de « la pièce jointe que j'ai remise qui parcours B1:E500 » (qui fonctionne bien parce qu'elle utilise la méthode FindNext) mais de la méthode Find_Next : http://www.commentcamarche.net/faq/36886-vba-recherche-de-donnees-la-methode-find#une-variante-find-next (qui n'utilises pas la méthode FindNext.)

Dans le fichier ci-joint, j'ai copié intégralement le code du chapitre « Une variante : Find_Next » et dans lequel j'ai uniquement remplacé A1:A20 par A1:E20 pour rechercher sur plusieurs colonnes :
https://mon-partage.fr/f/4ddACUI9/

Tu vois bien que ça ne fonctionne pas !

Patrice