Recherche multicritères (listbox et filtre élaboré)
Bonjour à tous,
Grande débutante en VBA, je suis quand même assez fière d'avoir réussi ce qui suit (extrait de mon fichier en PJ) avec l'aide notamment des archives de ce forum (merci !)
Je souhaite mettre à disposition de mes collègues un outil leur permettant de rechercher un document cartographique dans un tableau saisi sous Excel. J'ai donc créé un formulaire de recherche par thématique, étendue géographique et service demandeur (bouton dans la feuille 'Rechercher').
Tout fonctionne (presque) à merveille, mais je bute sur une dernière petite chose et je ne parviens pas à trouver de réponse sur les différents forums.
Mon formulaire me permet, grâce à un filtre élaboré, de croiser les critères : par exemple, je peux chercher une carte portant sur la thématique 'Loisirs' ET localisée sur le centre-ville, ou une carte 'Déplacements' ET demandée par le 'Pôle Espace public'.
Mais je souhaiterais également pouvoir choisir plusieurs critères dans une même liste. Par exemple, toutes les cartes 'Loisirs' OU ' Déplacements' dans la listbox 'Thématique', ou bien les cartes 'Centre-ville' OU 'Bourg' dans la listbox 'Étendue géographique'. Mes listbox permettent bien la multi sélection, mais lorsque je sélectionne deux critères dans une même liste, il ne me trouve aucune carte. C'est logique puisqu'il utilise le même opérateur 'ET' que quand il crée le filtre avec deux listbox.
En fait, pour résumer, il faudrait que j'aie un filtre qui me permette à la fois le ET entre les listbox (comme c'est déjà le cas) et le OU dans une même listbox (et là je bloque).
J'espère que je suis assez claire et que quelqu'un va pouvoir m'aider malgré les vacances !!!
Je vous souhaite une bonne journée.
Catherine
Bonjour Banzai64,
Un grand merci, cela fonctionne à merveille ! Cela faisait plusieurs jours que je me cassais le nez sur ce truc et je n'aurais jamais trouvé toute seule.
Une petite question, mais simplement pour mieux comprendre et si tu as le temps : j'ai bien vu le '+' dans le code sur mes deux listbox, qui correspond donc au "AND" si j'ai bien compris, mais peux-tu me "traduire" en langage intelligible pour moi les lignes suivantes du code (l'aide VBA ne m'a pas vraiment éclairée !) :
Critere1 = Left(Critere1, Len(Critere1) - 1) & "+"et
If Len(Critere1) > 0 Then
Critere1 = "(" & Left(Critere1, Len(Critere1) - 1) & ")*"
End IfEt pour quelle raison as-tu modifié la propriété Multiselect des Listbox ?
Encore merci, mes collègues vont être contents et je vais me retrouver avec plein de trucs à développer en VBA, et donc plein d'occasions de revenir sur le forum !
Catherine
Bonsoir,
Solution sans formulaire avec VBA minimum
Le critère donne une intersection de 3 ensembles.
=(SI(NBVAL(CritThematique)=0;VRAI;SOMMEPROD(--(CritThematique=C9))))*(SI(NBVAL(CritEtendue)=0;VRAI;SOMMEPROD(--(CritEtendue=H9))))*(SI(NBVAL(CritDEmandeur)=0;VRAI;SOMMEPROD(--(CritDEmandeur=I9))))
Avec Formulaire
La solution formulaire ne conserve pas de trace de la requête.
Sur cette version, une trace de la requête est affichée avec le résultat de l'extraction:
Private Sub UserForm_Initialize()
Me.ListBox1.List = [thematique].Value
Me.ListBox2.List = [etendue].Value
Me.ListBox3.List = [demandeur].Value
raz
End Sub
Private Sub ListBox1_Change()
Range("CritThematique").ClearContents
For i = 0 To Me.ListBox1.ListCount - 1
If Me.ListBox1.Selected(i) Then j = j + 1: Range("CritThematique").Cells(j, 1).Value = Me.ListBox1.List(i, 0)
Next i
End Sub
Private Sub ListBox2_Change()
Range("CritEtendue").ClearContents
For i = 0 To Me.ListBox2.ListCount - 1
If Me.ListBox2.Selected(i) Then j = j + 1: Range("CritEtendue").Cells(j, 1).Value = Me.ListBox2.List(i, 0)
Next i
End Sub
Private Sub ListBox3_Change()
Range("CritDemandeur").ClearContents
For i = 0 To Me.ListBox3.ListCount - 1
If Me.ListBox3.Selected(i) Then j = j + 1: Range("CritDemandeur").Cells(j, 1).Value = Me.ListBox3.List(i, 0)
Next i
End Sub
Private Sub b_raz_Click()
For i = 0 To Me.ListBox1.ListCount - 1: Me.ListBox1.Selected(i) = False: Next
For i = 0 To Me.ListBox2.ListCount - 1: Me.ListBox2.Selected(i) = False: Next
For i = 0 To Me.ListBox3.ListCount - 1: Me.ListBox3.Selected(i) = False: Next
raz
Extrait
End Sub
Private Sub b_extrait_Click()
Extrait
End Subhttp://boisgontierjacques.free.fr/fichiers/Filtre/FiltreElaboreEnsemble3.xls
http://boisgontierjacques.free.fr/fichiers/Filtre/FiltreElaboreEnsemble3Form2.xls
Pour compliquer, on peut générer la formule de sélection par VBA au lieu d'écrire la formule
=(SI(NBVAL(CritThematique)=0;VRAI;SOMMEPROD(--(CritThematique=C9))))*(SI(NBVAL(CritEtendue)=0;VRAI;SOMMEPROD(--(CritEtendue=H9))))*(SI(NBVAL(CritDEmandeur)=0;VRAI;SOMMEPROD(--(CritDEmandeur=I9))))
http://boisgontierjacques.free.fr/fichiers/Filtre/FiltreElaboreEnsemble3Form2FormuleVBA.xls
Ceuzin
Bonjour
Le + correspond au OU
* correspond au ET
Critere1 = Left(Critere1, Len(Critere1) - 1) & "+"Sert à remplacer le * (ET) par un + (OU)
On prend la partie gauche sauf le dernier caractère à laquelle on rajoute le +, on le fait seulement si dans une ListBox on trouve plus d'une sélection
If Len(Critere1) > 0 Then
Critere1 = "(" & Left(Critere1, Len(Critere1) - 1) & ")*"
End IfQuand on a passé en revue une ListBox et que celle-ci n'a rien de sélectionné, on s'affranchit de mettre entre parenthèses la formule (D'après mon expérience quand il y a des + (OU) il vaut mieux mettre la formule entre parenthèse)
Ce qui se fait en prenant la parenthèse ouvrante ( ( ) à laquelle on ajoute la formule, moins le dernier caractère, la parenthèse fermante et le signe * (ET) ( )* )
cabubu a écrit :Et pour quelle raison as-tu modifié la propriété Multiselect des Listbox ?
Plus facile pour sélectionner des éléments dans une ListBbox, si cette manière te gène, supprime les lignes
ListThema.MultiSelect = fmMultiSelectMultiet enlève la remarque devant les lignes
ListThema.MultiSelect = fmMultiSelectExtendedIdem pour ListGeo
Super,
Merci beaucoup.
J'ai en effet remis la propriété fmMultiSelectExtended. Pour le reste, j'ai tout compris !
Et merci aussi Ceuzin, je vais regarder ce que tu proposes.
Bonne journée
Catherine