Menu

Organisation de procédure (recherche) [Résolu]

1Globule 43 Messages postés mercredi 4 mai 2016Date d'inscription 8 février 2018 Dernière intervention - 5 févr. 2018 à 13:47 - Dernière réponse : michel_m 15292 Messages postés lundi 12 septembre 2005Date d'inscriptionContributeurStatut 23 mai 2018 Dernière intervention
- 9 févr. 2018 à 07:57
Bonjour à tous,

J'ai du mal à organiser ma macro, qui n'est pourtant pas si compliquée.

Je recherche une valeur (stockée en variable) dans mon classeur actif qui contient trois feuilles.
Si je la trouve dans une des feuille, je récupère les informations qui se trouvent sur la même ligne, je les indique en msgbox et je termine ma macro.
Si je ne la trouve pas je vais chercher dans un autre classeur, qui contient un nombre indéterminé de feuilles.
Si je la trouve, idem, je récupère les données de la ligne, je les affiche et je termine.
Si je ne la trouve pas du tout, dans aucun des deux classeurs, j'indique dans un msgbox une info de type "Valeur non trouvée".

Simple non ?

J'ai essayé avec des boucles et des if multiples, au final ça fonctionne très bien mais c'est une véritable usine à gaz.
Pourriez-vous m'indiquer la structure la plus simple à adopter ?

Merci beaucoup !
Afficher la suite 

Votre réponse

18 réponses

yg_be 5607 Messages postés lundi 9 juin 2008Date d'inscriptionContributeurStatut 24 mai 2018 Dernière intervention - Modifié par yg_be le 5/02/2018 à 15:17
0
Utile
bonjour, cela me semble une bonne idée d'utiliser des boucles et des IF.
une moins bonne idée d'en faire une usine à gaz.
1Globule 43 Messages postés mercredi 4 mai 2016Date d'inscription 8 février 2018 Dernière intervention - 5 févr. 2018 à 15:30
J'ai pour l'instant une structure qui ressemble à ça, elle fonctionne mais elle ne me semble pas du tout optimale.

For p = 1 To 2 ' Boucler sur 2 classeurs
If p = 1 Then ' Savoir s'il y a 3 feuilles ou un nombre indéterminé
a = 3
Else
a = Sheets.Count
End If

For i = 1 To a ' Boucler sur les x feuilles
Sheets(i).Select
For j = 2 To Cells(Rows.Count, 1).End(xlUp).Row ' Boucler sur toutes les lignes
If Cells(j, 2).Value Like "*" & VAR Then ' Chercher la variable
r = 1 ' Mettre un indicateur si valeur est trouvée
' Récupérer toutes les infos
End If
Next
Next
If r = 1 Then ' Si la valeur est trouvée, sortir de la boucle
Exit For
Else
s = 1 ' Sinon mettre un indicateur quand le deuxième classeur s'ouvre
Workbooks.Open Filename:="Documents/Archives.xlsx", ReadOnly:=True' Ouvrir le deuxième classeur
End If
Next


If s = 1 Then ' Si le deuxième classeur est ouvert, le fermer
Windows("Archives.xlsx").Close
End If
yg_be 5607 Messages postés lundi 9 juin 2008Date d'inscriptionContributeurStatut 24 mai 2018 Dernière intervention > 1Globule 43 Messages postés mercredi 4 mai 2016Date d'inscription 8 février 2018 Dernière intervention - 5 févr. 2018 à 16:05
moi je ferais plutôt ainsi:
option explicit
Sub cherchepartout(quoi As String)
Dim wb As Workbook
If Not cherchedansunfichier(ThisWorkbook, quoi) Then
    Set wb = Workbooks.Open("Documents/Archives.xlsx", , True)
    If Not cherchedansunfichier(wb, quoi) Then
        'rien trouvé
    End If
    wb.Close
End If
End Sub
Private Function cherchedansunfichier(wb As Workbook, Var As String) As Boolean
Dim sh As Worksheet, lig As Range
For Each sh In wb.Sheets
    For Each lig In sh.Rows
        If lig.Cells(1, 2).Value Like "*" & Var Then
            'trouvé
            cherchedansunfichier = True
            Exit Function
        End If
    Next lig
Next sh
cherchedansunfichier = False
End Function
1Globule 43 Messages postés mercredi 4 mai 2016Date d'inscription 8 février 2018 Dernière intervention - 7 févr. 2018 à 12:28
Merci beaucoup.
Je vais tester et je te tiens informé.
C'est très gentil en tout cas.
1Globule 43 Messages postés mercredi 4 mai 2016Date d'inscription 8 février 2018 Dernière intervention - 7 févr. 2018 à 14:01
Hum. visiblement ça ne fonctionne pas très bien.

A première vue, il me semble qu'il faudrait boucler sur les lignes non vides pour gagner du temps, et ensuite j'aurais besoin de sélectionner la cellule concernée quand la valeur est trouvée.

Je vais essayer de chercher un peu ce qui pose problème.
Commenter la réponse de yg_be
michel_m 15292 Messages postés lundi 12 septembre 2005Date d'inscriptionContributeurStatut 23 mai 2018 Dernière intervention - Modifié par michel_m le 7/02/2018 à 14:23
0
Utile
Bonjour;
on peut certainement éviter la boucle dans les feuilles



 If Application.CountIf(Columns("B"), "*" & Var) = 1 Then
lig = Columns("B").Find(what:=Var, LookIn:=xlValues).Row
MsgBox Range(Cells(lig, "A"), Cells(lig, "G"))
End If


Exemple à adapter


1Globule 43 Messages postés mercredi 4 mai 2016Date d'inscription 8 février 2018 Dernière intervention - 7 févr. 2018 à 16:09
Merci à vous deux,

J'ai adapté le code mais comme il ne fonctionnait pas j'ai essayé de reprendre déjà tel quel celqui de yg_be.
Je ne parviens pas à lancer la macro, à moins d'enlever l'argument ("quoi", dans l'exemple).

Est-ce que je fais quelque chose de travers ?
Pour l'instant je suis dans un module simple...
1Globule 43 Messages postés mercredi 4 mai 2016Date d'inscription 8 février 2018 Dernière intervention - 7 févr. 2018 à 16:18
En enlevant l'argument, j'arrive à trouver ma variable quand elle se trouve sur la première page uniquement. Si elle est sur la deuxième ou sur une autre, la macro ne la détecte pas.

De plus, si elle se trouve en première page jj'ai une erreur d'exécution 91 sur la ligne suivante :
lig = Columns("B").Find(what:=Var, LookIn:=xlValues).Row
1Globule 43 Messages postés mercredi 4 mai 2016Date d'inscription 8 février 2018 Dernière intervention - 7 févr. 2018 à 16:23
Je commente, je commente... :o)

En modifiant le type de variable lig en integer, c'est ok pour le deuxième problème.

Par contre le premier reste entier : Si ma valeur se trouve sur une autre page que la première, on ne la détecte pas.

Je cherche encore, et je commente si nécessaire...
1Globule 43 Messages postés mercredi 4 mai 2016Date d'inscription 8 février 2018 Dernière intervention - 7 févr. 2018 à 16:46
J'ai réussi à contourner le problème avec la méthode de Michel pour éviter la bouche !

Bon, il faut sélectionner chaque page parcourue avec un sh.Select,
C'est vrai qu'avec un ScreenUpdating à False on ne remarque rien, mais je trouve que c'est moins propre.

Vous auriez une solution ?
yg_be 5607 Messages postés lundi 9 juin 2008Date d'inscriptionContributeurStatut 24 mai 2018 Dernière intervention > 1Globule 43 Messages postés mercredi 4 mai 2016Date d'inscription 8 février 2018 Dernière intervention - 7 févr. 2018 à 17:41
peut-être ainsi:
Private Function cherchedansunfichier(wb As Workbook, Var As String) As Boolean
Dim sh As Worksheet, lig As Range
For Each sh In wb.Sheets
    If Application.CountIf(sh.Columns("B"), "*" & Var) = 1 Then
        Set lig = sh.Columns("B").Find(what:=Var, LookIn:=xlValues).EntireRow
        'trouvé
        MsgBox lig.Cells(1, 2).Value
        cherchedansunfichier = True
        Exit Function
    End If
Next sh
cherchedansunfichier = False
End Function
Commenter la réponse de michel_m
michel_m 15292 Messages postés lundi 12 septembre 2005Date d'inscriptionContributeurStatut 23 mai 2018 Dernière intervention - 8 févr. 2018 à 07:21
0
Utile
Bonjour
une proposition à adapter à ton contexte
https://mon-partage.fr/f/wh79n738/

Tu dis...


Commenter la réponse de michel_m
1Globule 43 Messages postés mercredi 4 mai 2016Date d'inscription 8 février 2018 Dernière intervention - 8 févr. 2018 à 12:32
0
Utile
Bonjour à vous deux, et merci encore pour votre aide.

Je crains que la solution de yg_be (set lig) ne soit pas efficace : Si la valeur se trouve en deuxième feuille on ne la détecte toujours pas.

Quant à la proposition de Michel, malheureusement je ne peux pas y accéder : Le lien est bloqué depuis mon bureau, je pense pour des raisons de sécurité.
yg_be 5607 Messages postés lundi 9 juin 2008Date d'inscriptionContributeurStatut 24 mai 2018 Dernière intervention - 8 févr. 2018 à 14:43
avec ceci, je trouve en deuxième feuille:
Private Function cherchedansunfichier(wb As Workbook, Var As String) As Boolean
Dim sh As Worksheet, lig As Range
For Each sh In wb.Sheets
    If Application.CountIf(sh.Columns("B"), "*" & Var) = 1 Then
        Set lig = sh.Columns("B").Find(what:=Var, LookIn:=xlValues).EntireRow
        'trouvé
        MsgBox lig.Cells(1, 2).Value
        cherchedansunfichier = True
        Exit Function
    End If
Next sh
cherchedansunfichier = False
End Function
1Globule 43 Messages postés mercredi 4 mai 2016Date d'inscription 8 février 2018 Dernière intervention - 8 févr. 2018 à 16:34
Au temps pour moi, en adaptant j'ai oublié de modifier ma variable.
Je crois bien que c'est tout bon !

Un grand merci à toi et à Michel pour le temps consacré à aider les autres.
Je clôture le sujet.
michel_m 15292 Messages postés lundi 12 septembre 2005Date d'inscriptionContributeurStatut 23 mai 2018 Dernière intervention - 8 févr. 2018 à 17:15
Bon, j'ai encore perdu plusieurs heures à vouloir aider!!!

Dans le cas de blocage de pièces jointes, tu passes en message personnel et tu donnes à ton interlocuteur une adresse où tu peux les recevoir

Adieu Globule
yg_be 5607 Messages postés lundi 9 juin 2008Date d'inscriptionContributeurStatut 24 mai 2018 Dernière intervention > michel_m 15292 Messages postés lundi 12 septembre 2005Date d'inscriptionContributeurStatut 23 mai 2018 Dernière intervention - 8 févr. 2018 à 17:44
michel_m, ta suggestion #6 a été très utile.
michel_m 15292 Messages postés lundi 12 septembre 2005Date d'inscriptionContributeurStatut 23 mai 2018 Dernière intervention - 9 févr. 2018 à 07:57
je m'adressais à globule et uniquement à lui, donc...
Commenter la réponse de 1Globule