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 :

filtrer une table excel avant de remplir un combobox


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 94
    Billets dans le blog
    1
    Par défaut filtrer une table excel avant de remplir un combobox
    Bonjour

    J'ai une appli dont j'affiche un formulaire. Pour remplir un combobox de ce formulaire, j'utilise une "table" dans une feuille excel.
    Mon problème est que je souhaiterais modifier le contenu de mon combobox selon des critères préalablement renseignés.
    exemple :
    Imaginons que ma table soit une liste de personne et que je veuille remplir un combobox de toutes les femmes, ou alors tous les hommes (par exemple en utilisant un control option pour choisir le sexe). Toutes les personnes (femmes ou hommes) sont saisis dans un même tableau.

    Bien entendu je pourrais me contenter d'un filtre sur ce tableau avant de remplir l'ascenseur, mais c'est pour récupérer des données associées à la personne choisie que ca coince .

    Est-ce que quelqu'un me comprend et aurait une piste à me proposer ?

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 567
    Détails du profil
    Informations personnelles :
    Âge : 62
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 567
    Par défaut
    salut
    a la question comment remplir mon combobox, je répond
    filtre élaboré
    extraction dans une colonne voisine
    extraction sans doublon
    combobox additem
    effacement de la liste
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Columns("A:B").Select
    Columns("A:B").AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=Columns( _
    "A:A"), CopyToRange:=Columns("M:N"), Unique:=True ' il s'agit d'un filtre elaboré sans doublon
    tri = Range("M1").CurrentRegion.Rows.Count 'determine le nombre de ligne de la zone
    For i = 1 To tri
    If Cells(i, 13).Value = matiere.Value Then
    designation.AddItem Cells(i, 14) 'rerempli la combobox designation
    End If
    Next i
    Columns("M:N").Delete
    ici il s'agit de deux colonnes, la premiere contient les matieres, la deuxiemes diffrent types dans une matiere
    genre acier ...dur
    acier mou
    métal...doré
    métal ...argenté
    la selection dans la combo matiere entraine dans la seconde combo le choix en fonction de cette selection. si je choisi métal dans la premiere combo, je n'aurais que doré et argenté dans la seconde
    je pense que c'est ça que tu cherche

  3. #3
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Sans utiliser de liste intermédiaire dans le tableur, avec l'objet Dictionary et List (très rapide si beaucoup d'éléments):

    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
     
    Private Sub OptionButton1_Click()
     RemplitCombo "H"
    End Sub
     
    Private Sub OptionButton2_Click()
     RemplitCombo "F"
    End Sub
     
    Private Sub OptionButton3_Click()
      RemplitCombo "*"
    End Sub
     
    Private Sub UserForm_Initialize()
      RemplitCombo "*"
    End Sub
     
    Sub RemplitCombo(Sexe)
      Set MonDico = CreateObject("Scripting.Dictionary")
      For Each c In Range([A2], [A65000].End(xlUp))
        If c.Offset(0, 1) Like Sexe Then
         If Not MonDico.Exists(c.Value) Then MonDico.Add c.Value, c.Value
        End If
      Next c
      Me.ComboBox1.List = MonDico.items
      Me.ComboBox1.ListIndex = 0
    End Sub
    Pour une version triée:

    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
     
    Private Sub OptionButton1_Click()
     RemplitCombo "H"
    End Sub
     
    Private Sub OptionButton2_Click()
     RemplitCombo "F"
    End Sub
     
    Private Sub OptionButton3_Click()
      RemplitCombo "*"
    End Sub
     
    Private Sub UserForm_Initialize()
      RemplitCombo "*"
    End Sub
     
    Sub RemplitCombo(Sexe)
      Set MonDico = CreateObject("Scripting.Dictionary")
      For Each c In Range([A2], [A65000].End(xlUp))
        If c.Offset(0, 1) Like Sexe Then
         If Not MonDico.Exists(c.Value) Then MonDico.Add c.Value, c.Value
        End If
      Next c
      temp = MonDico.items       ' le tableau temp() reçoit les éléments de MonDico
      Call Tri(temp, LBound(temp), UBound(temp))     ' tri
      Me.ComboBox1.List = temp
      Me.ComboBox1.ListIndex = 0
    End Sub
     
    Sub Tri(a, gauc, droi) ' Quick sort
      ref = a((gauc + droi) \ 2)
      g = gauc: d = droi
      Do
         Do While a(g) < ref: g = g + 1: Loop
         Do While ref < a(d): d = d - 1: Loop
         If g <= d Then
            temp = a(g): a(g) = a(d): a(d) = temp
            g = g + 1: d = d - 1
         End If
       Loop While g <= d
       If g < droi Then Call Tri(a, g, droi)
       If gauc < d Then Call Tri(a, gauc, d)
    End Sub
    JB
    Dernière modification par Invité ; 14/07/2008 à 11h50.

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 567
    Détails du profil
    Informations personnelles :
    Âge : 62
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 567
    Par défaut
    moi, je dis bravo. très fort ton truc. je garde.

  5. #5
    Membre confirmé

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 94
    Billets dans le blog
    1
    Par défaut
    Salut et merci.
    Même si par hasard ca ne s'adaptait pas tout à fait à mon cas, ca peut être super utile !

    Je suis donc en train de l'adapter à mon cas mais avant de continuer, j'aurais une question :
    Actuellement, je récupère l'index de l'item sélectionné et je m'en sers pour pointer la ligne dans mon tableau pour obtenir les autres informations.
    Avec ton astuce, je ne pourrais plus me servir de l'index comme pointeur de ma table ? Si non, comment dois-je procéder ?

    Merci d'avance

  6. #6
    Membre confirmé

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 94
    Billets dans le blog
    1
    Par défaut
    Bon, j'ai implémenté tout ca, et j'obtient une erreur 70 : permission refusée sur la ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Me.ComboBox1.List = MonDico.items
    J'ai bien entendu tout adapté à mes besoins et ton exemple .xls fonctionnait aux petits oignons.

    J'ai également la même erreur si je prend la version triée...

    Pour info, le combo à remplir se situe dans un control page différent du control qui servira de conditions au filtrage.

    EDIT :
    J'ai trouvé l'erreur en cherchant !
    Voici la réponse : http://www.developpez.net/forums/sho...47&postcount=7
    j'avais spéciifié un row range à ma combobox et j'avais oublié de l'enlever. ceci empêchait l'affectation par additems

  7. #7
    Membre confirmé

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 94
    Billets dans le blog
    1
    Par défaut la suite des évènements
    OK le filtrage fonctionne parfaitement.

    Maintenant, ce que je craignais dans mon post précédent, je ne peux plus me servir de l'index d'item sélectionné dans le combo pour en déduire les informations liées à ce choix

    Dans ton exemple on pourrait imaginer afficher l'age de la personne sélectionnée. On ajouterais donc une 3ieme colonne et le fit de choisir 'untel' renverrai son age.

    Comment pourrais-je contourner cet obstacle ?

  8. #8
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Voir PJ

    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
     
    Private Sub OptionButton1_Click()
     RemplitCombo "H"
    End Sub
     
    Private Sub OptionButton2_Click()
     RemplitCombo "F"
    End Sub
     
    Private Sub OptionButton3_Click()
      RemplitCombo "*"
    End Sub
     
    Private Sub UserForm_Initialize()
      RemplitCombo "*"
    End Sub
     
    Sub RemplitCombo(Sexe)
      Me.ComboBox1.Clear
      i = 0
      For Each c In Range([A2], [A65000].End(xlUp))
        If c.Offset(0, 1) Like Sexe Then
           Me.ComboBox1.AddItem
           Me.ComboBox1.List(i, 0) = c.Value
           Me.ComboBox1.List(i, 1) = c.Offset(0, 2).Value
           i = i + 1
        End If
      Next c
      Me.ComboBox1.ListIndex = 0
    End Sub
    JB
    Dernière modification par Invité ; 14/07/2008 à 11h50.

  9. #9
    Membre confirmé

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 94
    Billets dans le blog
    1
    Par défaut
    Merci
    Mais à regarder ton exemple (encore toutes mes félicitations pour la présentation ca a le mérite d'être très clair !) mais ce n'est pas (sauf erreur de ma part) ce que je voulais

    En fait ma base est une liste de personnes, avec les numéros de téléphone, les bureaux, le service etc.... Mon premier choix est celui d'une personne dans cette base. Puis selon son service, je pioche dans une autre base pour proposer les actions possibles uniquement pour ce service.

    Donc ton idée générale me correspond pour filtrer dans la base "actions", mais lorsque je choisis une action pour ce service, je n'obtient pas les informations de la base action...

    Mouais je sais pas si c'est plus clair.. ?

    En fait , j'ai 2 bases :
    - base 1 : je choisi un élément
    ==> le choix filtre dans une base 2
    - base 2 filtrée : je choisis un élément et j'obtient les autres champs pour cet élément.

    EDIT:
    J'ai mis ton xls modifié pour présenter grosso modo ce à quoi je veux aboutir.
    CA NE FONCTIONNE PAS ! Juste pour présenter un peu mieux les choses. Un choix dans le premier combobox me filtre une autre base pour remplir le second combobox. Le choix d'un élément dans le second combobox me donne les autres champs associés. J'ai ajouté un petit tableau sur la feuille pour illustrer le contenu du 2ieme combo. Merci
    Fichiers attachés Fichiers attachés

  10. #10
    Membre confirmé

    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    94
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 94
    Billets dans le blog
    1
    Par défaut Solution trouvée, qu'en pensez vous ?
    Re-Bonjour

    Bon j'ai trouvé une solution. J'ai recopié la boucle qui permet de remplir le dictionnaire uniquement avec les éléments qui vont bien dans mon évènement combobox_change à la différence que je rempli la valeur du dictionnaire avec le numéro de rangée... Pas simple à expliquer...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
      For Each c In Range([A2], [A65000].End(xlUp))
        If c.Offset(0, 1) Like Sexe Then
         If Not MonDico.Exists(c.Value) Then MonDico.Add c.Value, c.Row
        End If
      Next c
    ainsi j'obtient un dictionnaire dont les clés sont les éléments de choix de mon second combobox, et en valeurs j'ai le numéro de ligne de mon tableau excel où ce trouve cette clé. Ainsi j'obtient facilement la rangée qui me va et j'en déduit toutes les autres infos de ma table.

    Je reste ouvert à toute idée plus propre ou différente, histoire de partager un peu.

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

Discussions similaires

  1. Remplir table sql server depuis une table excel
    Par silifana dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 14/02/2009, 15h23
  2. Importation d'une table excel avec nom paramétrable
    Par mastasushi dans le forum Access
    Réponses: 4
    Dernier message: 13/02/2007, 19h20
  3. Réponses: 5
    Dernier message: 06/06/2006, 14h12
  4. [C#] Filtrer une table
    Par diaboloche dans le forum ASP.NET
    Réponses: 8
    Dernier message: 05/12/2005, 15h17
  5. comment filtrer une table avec deux criteres càd 2 colonnes
    Par athmane2dz dans le forum Bases de données
    Réponses: 7
    Dernier message: 28/07/2004, 15h25

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