Bonsoir,
J'ai nommé tes plages, c'est plus confortable, et ça permet de se passer des feuilles...
Les noms sont (base et plage filtrée) sont dynamiques, ils s'adapteront aux extensions.
Il faut toujours penser à supprimer le filtrage précédent avant d'en faire un nouveau... !
Sub FiltreData()
[PlgFltr].Offset(1).ClearContents
[Base].AdvancedFilter xlFilterCopy, [Crit], [PlgFltr]
End Sub
Pour ta ListBox, j'ai eu quelques doutes sur tes intentions. J'ai fini par opter par une multicolonnes, et j'ai donc complété la construction pour l'élargir un peu de façon qu'elle accueille tes datas en largeur. J'ai aussi réduit un peu la hauteur, ça surtout parce que plus haute que mon écran, cela ne facilite pas le travail, et de toute façon elle n'aurait pas été assez haute pour en pas avoir besoin de scrollbar avec certains filtrages...
Private Sub CommandButton1_Click()
Dim PlgF, i%
If ComboBox1.ListIndex > -1 And TextBox1.Value <> "" Then
With [Crit]
.Cells(1, 1) = ComboBox1.Value
.Cells(2, 1) = TextBox1.Value
End With
FiltreData
With [PlgFltr]
If .Rows.Count > 1 Then
PlgF = .Offset(1).Resize(.Rows.Count - 1).Value
Else
MsgBox "Aucune correspondance trouvée.", vbInformation, "FiltreData"
End If
End With
With ListBox1
If UBound(PlgF) > 1 Then
.List = PlgF
Else
.AddItem PlgF(1, 1)
For i = 1 To 4
.List(0, i) = PlgF(1, i + 1)
Next i
End If
End With
Else
MsgBox "Définir les critères de filtrage !", vbExclamation, "FiltreData"
End If
End Sub
Pour ta procédure de recherche, il convenait d'abord de tester si l'utilisateur avait bien défini les critères de recherche avant de poursuivre...
Puis tester si le filtrage avait été productif, ce qu'on pouvait faire directement sans passer par l'utilisation d'une gestion d'erreur.
Le transfert du résultat du filtrage sur un tableau facilite l'opération. Les noms de plage incluent les en-têtes (en raison de leur utilisation pour le filtre avancé, et cela permet d'ailleurs que la plage filtrée soit toujours définie même si aucun élément filtré), en passant par un tableau on rajuste pour éliminer les en-têtes.
RowSource n'était pas le meilleur choix pour l'affectation à la ListBox : plage mouvante et sur laquelle tu seras peut-être susceptible d'intervenir, ce qui aurait pose des problèmes avec RowSource, qui lie la plage à la liste...
Ayant le résultat en tableau on l'affecte avec List (ce qui t'évite d'ailleurs de recalculer l'adresse de la plage, ce que tu n'avais pas fait encore ), en dissociant le cas où un seul élément est filtré, pour lequel List n'est pas utilisable.
Vois déjà si le résultat va dans le sens de ce que tu voulais. Il me semble que ta TextBox ne sera pas très facile d'emploi... Pour ma part j'opterais volontiers sur une ComboBox, ce qui oblige d'une part à avoir des listes d'éléments uniques des colonnes de ta base (ce serait à faire sur une autre feuille pour éviter d'encombrer plus la feuille de ta Base), à faire par filtrage avancé (et à tenir à jour), et d'autre part alimenter cette Combo à partir du choix de la Combo1.
A toi d'y réfléchir, mais cela te faciliterait les choix.
Un petit problème potentiel réside dans ta Base où les colonnes (les 4 premières) contiennent des valeurs texte composées uniquement de chiffres, et les formats de cellule sont en format nombre. Une fausse manoeuvre pourrait facilement dans ces conditions entraîner la conversion de ces valeurs en nombre, qui fausserait toute ton application. Tu as utilement mis ta zone de critère en format Texte. Je ne suis pas habituellement partisan du format Texte, mais je crois que dans ton cas, placer ces 4 colonnes de la base en format Texte serait une sécurité.
Bonne continuation.
Cordialement.