IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Aide pour réaliser un moteur de recherche en Vba Excel


Sujet :

Macros et VBA Excel

  1. #1
    Membre éprouvé
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Septembre 2007
    Messages
    1 896
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Assistant aux utilisateurs
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 896
    Points : 984
    Points
    984
    Par défaut Aide pour réaliser un moteur de recherche en Vba Excel
    Bonjour,

    Je cherche à réaliser un moteur de recherche avec Vba sous Excel.
    Faire l'UserForm ça je sais.
    Là où ça se complique c'est dans le résultat que je dois obtenir.
    Mon fichier comportent 52 feuilles (S1 à S52).
    Dans l'UserForm lorsque je choisi un nom dans une Combo (Nom rapatrié de la colonne E de chaque feuille), il faut que dans les ListBox je puisse rechercher tous les achats de cet utilisateurs en fait rapatriées les données lui correspondant qui sont dans les colonnes (F, G, H, I, J, K, L, M, N) de chaque feuille.
    Est-ce possible de réaliser ça et comment, avez-vous un modèle à me proposer ? je vous en remercie par avance.

  2. #2
    Inactif  
    Avatar de ouskel'n'or
    Profil pro
    Inscrit en
    Février 2005
    Messages
    12 464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 12 464
    Points : 15 546
    Points
    15 546
    Par défaut
    Le message (effacé ) d'aalex pose la bonne question : Où se situe ton problèmes ? Lister les feuilles du classeur ? (regarde For Each Next dans l'aide en ligne) Rechercher dans une feuille ? (regarde Find dans l'aide en ligne)
    Si tu as un code avec lequel tu as toujours un pb, tu viens nous le dire
    Bon courage

  3. #3
    Membre éprouvé
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Septembre 2007
    Messages
    1 896
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Assistant aux utilisateurs
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 896
    Points : 984
    Points
    984
    Par défaut
    Bonjour,

    En fait, je ne sais pas comment lister les 52 feuilles en même temps.
    Je sais faire la recherche sur une feuille, mais sur les 52 ???? je ne sais pas faire.
    Par exemple : Je recherche tous les achats fait par l'utilisateur n°12.
    Dans une Combo, je choisi 12 (j'ai aussi la possibilité de faire l'inverse, recherche par Nom, mais plus risqué en cas de doublon dans les Noms de famille)
    Dans une listBox s'affiche son nom
    Dans une autre qui comporte 8 colonnes, doit s'afficher la liste de tous ses achats c'est à dire
    - l'intitulé des achats
    - le nombre
    - le prix unitaire etc
    La recherche doit se faire sur les 52 semaines, soit sur les 52 feuilles.
    Dans une, j'y arrive, mais dans les 52 simultanément, je plante.
    Merci par avance

    Voici à quoi devrait ressembler le code bien que le non de fichier soit différent.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
     
    Private Sub CmbRecherche_Click()
    Dim Cell As Range
    Dim TAB1(0 To 50, 0 To 6) As String
    Dim I As Byte
    Dim L As Byte
        If CmbDate.Value = "" And CmbNum.Value = "" And CmbTiers = "" And CmbEngagt = "" Then
            MsgBox "Veuillez faire un choix de recherche", vbInformation + vbOKOnly, "Avertissement..."
            LstResult.Clear
            Exit Sub
        End If
        If CmbDate.Value <> "" Then
            L = Len(CmbDate)
            For Each Cell In Sheets("Facture").Range("IntituDate")
                If UCase(Left(Cell.Text, L)) = UCase(CmbDate.Text) Then
                    TAB1(I, 0) = Cell.Offset(0, -1).Text
                    TAB1(I, 1) = Cell.Text
                    TAB1(I, 2) = Cell.Offset(0, -7).Text
                    TAB1(I, 3) = Cell.Offset(0, -14).Text
                    TAB1(I, 4) = Cell.Offset(0, 2).Text
                    TAB1(I, 5) = Cell.Offset(0, 5).Text
                    I = I + 1
                End If
            Next
            LstResult.ColumnCount = 6
            LstResult.ColumnWidths = "1,5cm" & ";" & "2cm" & ";" & "6cm" & ";" & "3cm" & ";" & "3cm" & ";" & "3cm"
            LstResult.List = TAB1()
        ElseIf CmbNum.Value <> "" Then
            L = Len(CmbNum)
            For Each Cell In Sheets("Facture").Range("IntituFact")
                If UCase(Left(Cell.Text, L)) = UCase(CmbNum.Text) Then
                    TAB1(I, 0) = Cell.Text
                    TAB1(I, 1) = Cell.Offset(0, 1).Text
                    TAB1(I, 2) = Cell.Offset(0, -6).Text
                    TAB1(I, 3) = Cell.Offset(0, -13).Text
                    TAB1(I, 4) = Cell.Offset(0, 3).Text
                    TAB1(I, 5) = Cell.Offset(0, 6).Text
                    I = I + 1
                End If
            Next
        ElseIf CmbTiers.Value <> "" Then
            L = Len(CmbTiers)
            For Each Cell In Sheets("Facture").Range("IntituEnt")
                If UCase(Left(Cell.Text, L)) = UCase(CmbTiers.Text) Then
                    TAB1(I, 0) = Cell.Offset(0, 6).Text
                    TAB1(I, 1) = Cell.Offset(0, 7).Text
                    TAB1(I, 2) = Cell.Text
                    TAB1(I, 3) = Cell.Offset(0, -7).Text
                    TAB1(I, 4) = Cell.Offset(0, 9).Text
                    TAB1(I, 5) = Cell.Offset(0, 12).Text
                    I = I + 1
                End If
            Next
            LstResult.ColumnCount = 6
            LstResult.ColumnWidths = "1,5cm" & ";" & "2cm" & ";" & "6cm" & ";" & "3cm" & ";" & "3cm" & ";" & "3cm"
            LstResult.List = TAB1()
        ElseIf CmbEngagt.Value <> "" Then
            L = Len(CmbEngagt)
            For Each Cell In Sheets("Facture").Range("IntituEngt")
                If UCase(Left(Cell.Text, L)) = UCase(CmbEngagt.Text) Then
                    TAB1(I, 0) = Cell.Offset(0, 13).Text
                    TAB1(I, 1) = Cell.Offset(0, 14).Text
                    TAB1(I, 2) = Cell.Offset(0, 7).Text
                    TAB1(I, 3) = Cell.Text
                    TAB1(I, 4) = Cell.Offset(0, 16).Text
                    TAB1(I, 5) = Cell.Offset(0, 19).Text
                    I = I + 1
                End If
            Next
            LstResult.ColumnCount = 6
            LstResult.ColumnWidths = "1,5cm" & ";" & "2cm" & ";" & "6cm" & ";" & "3cm" & ";" & "3cm" & ";" & "3cm"
            LstResult.List = TAB1()
        End If
        LstResult.ColumnCount = 6
        LstResult.ColumnWidths = "1,5cm" & ";" & "2cm" & ";" & "6cm" & ";" & "3cm" & ";" & "3cm" & ";" & "3cm"
        LstResult.List = TAB1()
    End Sub

  4. #4
    Inactif  
    Avatar de ouskel'n'or
    Profil pro
    Inscrit en
    Février 2005
    Messages
    12 464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 12 464
    Points : 15 546
    Points
    15 546
    Par défaut
    Si le code est dans le classeur qui contient les 52 feuilles tu utilises Thisworkbook pour désigner le classeur. Et pour les feuilles du classeur... je verrais bien un truc comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    Dim unefeuille as worksheet, cell as range, addDeb as string
    For each UneFeuille In Thisworkbook.worksheets
         With UneFeuille.Range("IntituDate")
               Set cell = .find(CmbDate, Lookin:=xlvalues, lookat:=xlpart)
               If not cell is nothing then
                   addDeb= cell.Address
                   Do
                        If instr(Ucase(cell), ucase(CmbDate))=1 then
                             TAB1(I, 0) = Cell.Offset(0, -1)
                             TAB1(I, 1) = Cell
                             TAB1(I, 2) = Cell.Offset(0, -7)
                             TAB1(I, 3) = Cell.Offset(0, -14)
                             TAB1(I, 4) = Cell.Offset(0, 2)
                             TAB1(I, 5) = Cell.Offset(0, 5)
                        endif
                        Set cell = .FindNext(cell)
                    Loop While Not cell Is Nothing And cell.Address <> addDeb
                End If
           End with
    Next UneFeuille
    Inspiré de l'aide en ligne à Find

    Edit
    Comme je ne sais pas ce qu'est "I" dans TAB1(I, 0) je ne m'en suis pas occupé... Je te laisse l'incrémenter là oùcékifo...

  5. #5
    Membre éprouvé
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Septembre 2007
    Messages
    1 896
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Assistant aux utilisateurs
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 896
    Points : 984
    Points
    984
    Par défaut
    Bonjour,

    Dans mon code, I fait référence au texte à trouver dans ma feuille.
    C'est un code que j'ai trouvé il y a longtemps, la personne qui l'a mis en place me l'a expliqué ainsi, je l'ai donc copier bêtement.
    Mais merci pour ton aide, je vais le mettre en place et je te tiens informé.
    A+

  6. #6
    Inactif  
    Avatar de ouskel'n'or
    Profil pro
    Inscrit en
    Février 2005
    Messages
    12 464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 12 464
    Points : 15 546
    Points
    15 546
    Par défaut
    Ok. Je n'ai voulu te donner que le principe de la recherche dans plusieurs feuilles.
    Ajoute I = I + 1 dans la boucle
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
                        If instr(Ucase(cell), ucase(CmbDate))=1 then
                             TAB1(I, 0) = Cell.Offset(0, -1)
                             '....
                             '....
                             '....
                             I = I + 1
                        Endif
    Il est évident que dans mon code je n'ai traité qu'une condition. Pour essayer de comprendre j'ai dû l'indenter.
    Pas facile de comprendre dans un code, rendu illisible par l'absence d'indentation, que la répétition (4 fois) des lignes suivantes est inutile.
    LstResult.ColumnCount = 6
    LstResult.ColumnWidths = "1,5cm" & ";" & "2cm" & ";" & "6cm" & ";" & "3cm" & ";" & "3cm" & ";" & "3cm"
    LstResult.List = TAB1()
    Placées une seule fois au début ou à la fin ou même dans Userform_Activate ou Initialize, ça simplifierait la relecture.
    En outre, puisque ces dimensions ne changent pas, elles pourraient être déterminées "en dur" dans les propriétés de la listbox en mode création.

    Pour continuer à t'aider, j'ai besoin d'un ou deux "détails"
    Peux-tu détailler d'avantage cette phrase ?
    il faut que dans les ListBox je puisse rechercher tous les achats de cet utilisateurs en fait rapatriées les données lui correspondant qui sont dans les colonnes (F, G, H, I, J, K, L, M, N) de chaque feuille.
    Dans le code tu parcoures chaque feuille pour seulement 4 conditions alors qu'il y a 9 colonnes à "visiter".
    Peux-tu en dire plus sur l'organisation des données ?
    Existe-t-il un critère commun qui puisse permettre d'identifier le client dans les données de chaque feuille ? Lequel ?

    Ce que je ne comprends pas est l'apparente nécessité de parcourir 4 fois chaque feuille.
    Je soupçonne bien quelque chose mais comme je ne connais pas la structure de ta base de données, j'attendrai que tu précises ce fameux "critère commun" (nom du client, Identifiant... etc.)
    A+

  7. #7
    Membre éprouvé
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Septembre 2007
    Messages
    1 896
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Assistant aux utilisateurs
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 896
    Points : 984
    Points
    984
    Par défaut
    Le critère commun est le N° de l'utilisateur, c'est le seul critère fiable.
    Pour le code tu as certainement raison, mais j'ai fait comme je sais, je ne suis pas un pro mais grâce à vos conseils avisés, je m'améliore.

    A partir de ce numéro, la recherche se fait dans chacune des 52 feuilles et dans mon formulaire, doit apparaître en colonne :
    - le Nom
    - le Prénom
    - Liste des produits achetés
    - Leur nombre
    - Le n° de l'objet vendu
    - Le mode de paiement
    - Le prix unitaire pour chaque produits
    - Le nombre total d'achats (à calculer selon le Nbre de ligne dans la liste)
    - Le coût total des achats (somme à calculer selon la liste)

    Au départ, je voulais le faire en TCD, mais je ne crois pas que cela soit possible sur 52 feuilles en même temps.

    Mais le code que je t'ai proposé, je dois l'adapter à mon appli, c'est uniquement un exemple que j'ai déjà fait, que je dois modifier, pour l'appliquer à mon programme. Mais il devrait être très ressemblant, à part tous les noms qui vont changer.
    Merci

  8. #8
    Inactif  
    Avatar de ouskel'n'or
    Profil pro
    Inscrit en
    Février 2005
    Messages
    12 464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 12 464
    Points : 15 546
    Points
    15 546
    Par défaut
    Je comprends tout ça mais... Et pour ce qui est l'organisation de tes données ?

    La recherche devant commencer par là, dans quelle colonne se trouve le N° de Client ou "utilisateur" ?

    Une fois que tu as une ligne pour "cet" utilisateur, les autres données sont bien sur la même ligne ?
    Si oui, la suite va de soit avec Cell.Offset(0, ...) Inutile de recommencer la recherche "d'autre chose" sur une autre colonne.
    Et dans la même boucle, une fois les données de la ligne récupérées, on passe à la ligne suivante du même client. C'est le principe du code que je t'ai mis.

    Que veux-tu dans la listbox ? Doit-il y avoir autant de colonnes dans la liste que dans les feuilles ? Sinon combien ? Et lesquelles.

    Pour que je ne me les pose plus, essaie de répondre aux questions que je te pose.
    A+

  9. #9
    Membre éprouvé
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Septembre 2007
    Messages
    1 896
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Assistant aux utilisateurs
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 896
    Points : 984
    Points
    984
    Par défaut
    Le n° de l'utilisateur se trouve en colonne F de chaque feuille
    Le nom en E, l'objet en H, le mode de paiement en J, le Nbre en K, le prix unitaire en L, le prix de vente en M, le total de la vente en N.

    Formulaire (FrmCherch)
    Un bouton (CmbCherch) un autre (CmbFerm)

    Dans une Combo (CmbNum), je choisi le N°.
    Ensuite dans une listbox (LstNom) apparaît le nom
    dans une autre (LstPnom) le prénom
    Dans une dernière comprenant 6 colonnes (Objet, Nbre, Mode de paiement, etc..) reprenat la liste des achats de cet utilisateur pour les 52 feuilles,
    Par contre, cet utilisateur peut se trouver n'importe où dans chacune des feuilles et plusieurs fois dans la même feuille, puisque les enregistrement se font au hazard des demandes.

  10. #10
    Inactif  
    Avatar de ouskel'n'or
    Profil pro
    Inscrit en
    Février 2005
    Messages
    12 464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2005
    Messages : 12 464
    Points : 15 546
    Points
    15 546
    Par défaut
    Ok ! Voilà des réponses claires (il semble d'ailleurs que tu aies complété ta réponse précédente pendant que je rédigeais mon message).

    Le code que je t'ai passé (si je n'ai pas commis d'erreur d'écriture...) est parfaitement adapté à ce que tu veux faire : Une boucle sur les feuilles et, imbriquée dans cette boucle, une boucle de recherche du seul N° d'utilisateur.
    Le fait que tu aies 3 listes ne pose pas de problème
    Si je reprends mon code, en récupérant le N° d'utilisateur dans le combo CmbNum, ça devrait être quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    Sub CmbNumClick() 'Sélection d'un N° dans le combo CmbNum
    Dim unefeuille As Worksheet, cell As Range, addDeb As String
    Dim Tablo() As Variant
        i = 0
        For Each unefeuille In ThisWorkbook.Worksheets
             With unefeuille.Range("F1:F" & Split(unefeuille.UsedRange.Address, "$")(4))
                Set cell = .Find(CmbNum, LookIn:=xlValues, lookat:=xlWhole)
                If Not cell Is Nothing Then
                    addDeb = cell.Address
                    Do
                         LstNom.AddItem cell.Offset(0, -1) 'colonne E -> Le nom
                         'LstPnom.additem Cell.Offset(0, ??) 'Le prénom. Où ?? = décalage avec F
                         ReDim Preserve Tablo(5, i)
                         Tablo(0, i) = cell.Offset(0, 2) 'Objet
                         Tablo(1, i) = cell.Offset(0, 4) 'Mode de paiement
                         Tablo(2, i) = cell.Offset(0, 5) 'Nombre
                         Tablo(3, i) = cell.Offset(0, 6) 'Prix unitaire
                         Tablo(4, i) = cell.Offset(0, 7) 'Prix de vente
                         Tablo(5, i) = cell.Offset(0, 8) 'Total de la vente
                         i = i + 1
                         Set cell = .FindNext(cell)
                     Loop While Not cell Is Nothing And cell.Address <> addDeb
                 End If
            End With
        Next unefeuille
        LstResult.List = Application.Transpose(Tablo)
    End Sub
    Tu adaptes les offsets et ça devrait aller.
    Dans ton code, le tablo dimensionné empiriquement à 50 n'est pas une méthode à utiliser. Tu dois toujours imaginer le pire, ici que je client est venu plus de 50 fois
    Application.Transpose inverse les termes du tableau afin que tu puisses utiliser Redim Preserve

    Si tu as des questions, c'est le moment

  11. #11
    Membre éprouvé
    Homme Profil pro
    Assistant aux utilisateurs
    Inscrit en
    Septembre 2007
    Messages
    1 896
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France

    Informations professionnelles :
    Activité : Assistant aux utilisateurs
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 896
    Points : 984
    Points
    984
    Par défaut
    Eh bien pour le moment je n'ai pas de question, je reste admiratif comme d'habitude, je mets cela en place et je te tiens au courant.
    Merci beaucoup, surtout pour ta patience

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 14
    Dernier message: 30/10/2011, 21h08
  2. [XL-2003] Créer un moteur de recherche sou VBA excel
    Par punkisnotdead dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 03/08/2009, 13h52
  3. Réponses: 7
    Dernier message: 16/02/2008, 14h10
  4. Réponses: 2
    Dernier message: 02/03/2006, 11h57
  5. Réponses: 8
    Dernier message: 03/11/2005, 08h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo