🎓 VBA : Créer un système de filtres multicritères en cascade
C'est un excellent moyen d'optimiser votre interface. Vous voulez créer un système de filtres en cascade : le mois filtre les IDs, et la zone de recherche vient affiner le résultat final parmi ce qui reste.
Voici comment structurer votre code pour que la recherche soit "intelligente" et croise toutes les conditions (Mois + ID + Texte de recherche).
1. La stratégie de filtrage
Le secret est de créer une procédure unique (que nous appellerons ActualiserFiltre) qui sera appelée par chacun de vos contrôles. À chaque changement, elle vérifie les 3 conditions :
Le mois correspond (si sélectionné).
L'ID correspond (si sélectionné).
Le texte de recherche est présent (si saisi).
2. Le code VBA
'Début***************************************************************recherche gestion******************************** Private Sub Liste_ID_Nom_prenom_DropButtonClick() Dim cell As Range Dim colUnique As New Collection Dim item As Variant Dim tbl As ListObject ' 1. Vérifier si la liste est déjà pleine pour éviter de recalculer inutilement ' (Optionnel : si vous voulez rafraîchir à chaque clic, retirez cette condition) If Liste_ID_Nom_prenom.ListCount > 0 Then Exit Sub ' 2. Sécurité : Vérifier l'existence de la table On Error Resume Next Set tbl = Liste_Paie_Personel_calcule.ListObjects("Tbl_Liste_Paie_Personel_calcule") On Error GoTo 0 If tbl Is Nothing Then MsgBox "Erreur : Table introuvable !", vbCritical Exit Sub End If ' 3. Vidage de la liste Liste_ID_Nom_prenom.Clear ' 4. Extraction des valeurs uniques via une Collection On Error Resume Next For Each cell In tbl.ListColumns("ID et Nom et Prenom").DataBodyRange If Not IsError(cell.Value) And cell.Value <> "" Then ' On utilise la valeur comme Clé pour filtrer les doublons colUnique.Add cell.Value, CStr(cell.Value) End If Next cell On Error GoTo 0 ' 5. Remplissage de la ComboBox For Each item In colUnique Liste_ID_Nom_prenom.AddItem item Next item End Sub Private Sub Liste_Mois_et_annee_DropButtonClick() Dim cell As Range Dim colUnique As New Collection Dim item As Variant Dim tbl As ListObject ' 1. Vérifier si la liste est déjà pleine pour éviter de recalculer inutilement ' (Optionnel : si vous voulez rafraîchir à chaque clic, retirez cette condition) If Liste_Mois_et_annee.ListCount > 0 Then Exit Sub ' 2. Sécurité : Vérifier l'existence de la table On Error Resume Next Set tbl = Liste_Paie_Personel_calcule.ListObjects("Tbl_Liste_Paie_Personel_calcule") On Error GoTo 0 If tbl Is Nothing Then MsgBox "Erreur : Table introuvable !", vbCritical Exit Sub End If ' 3. Vidage de la liste Liste_Mois_et_annee.Clear ' 4. Extraction des valeurs uniques via une Collection On Error Resume Next For Each cell In tbl.ListColumns("Mois et année").DataBodyRange If Not IsError(cell.Value) And cell.Value <> "" Then ' On utilise la valeur comme Clé pour filtrer les doublons colUnique.Add cell.Value, CStr(cell.Value) End If Next cell On Error GoTo 0 ' 5. Remplissage de la ComboBox For Each item In colUnique Liste_Mois_et_annee.AddItem item Next item End Sub Private Sub Liste_Matricule_et_nom_Change() If ActiveSheet.Unprotect = False Then ActiveSheet.Unprotect End If '************Sub RechercherMatricule() Range("A6").Value = "" 'Selection.ClearContents '''RechercherMaxFactureEtModifier() 'Dim ws As Worksheet Dim tbl As ListObject ' Assurez-vous que la table existe dans la feuille active On Error Resume Next Set tbl = Liste_Paie_Personel_calcule.ListObjects("Tbl_Liste_Paie_Personel_calcule") On Error GoTo 0 ' Vérifiez si la table existe If tbl Is Nothing Then MsgBox "La table 'Liste_Paie_Personel_calcule' n'a pas été trouvée dans la feuille active." Exit Sub End If Range("A6").Value = Liste_Matricule_et_nom Call ReprotegerFeuille_et_DeverrouillerColonneTableau_Generic(Bull_Paie, "", "") End Sub' --- Événements qui déclenchent la mise à jour --- Private Sub Liste_Mois_et_annee_Change() ActualiserFiltre End Sub Private Sub Liste_ID_Nom_prenom_Change() ActualiserFiltre End Sub Private Sub Recherche_noms_Change() ActualiserFiltre End Sub ' --- La procédure de filtrage intelligente --- Sub ActualiserFiltre() Dim cell As Range Dim tbl As ListObject Dim condMois As Boolean, condID As Boolean, condTexte As Boolean Dim valMois As String, valID As String, valRecherche As String Dim itemMois As String, itemID As String, itemRecherche As String Set tbl = Liste_Paie_Personel_calcule.ListObjects("Tbl_Liste_Paie_Personel_calcule") ' Récupération des critères de filtrage valMois = Liste_Mois_et_annee.Value valID = Liste_ID_Nom_prenom.Value valRecherche = Recherche_noms.Value Liste_Matricule_et_nom.Clear ' Parcourir le tableau For Each cell In tbl.ListColumns("Recherche").DataBodyRange If Not IsError(cell.Value) Then ' Récupérer les valeurs de la ligne actuelle itemRecherche = cell.Value itemMois = tbl.ListColumns("Mois et année").DataBodyRange(cell.Row - tbl.HeaderRowRange.Row).Value itemID = tbl.ListColumns("ID et Nom et Prenom").DataBodyRange(cell.Row - tbl.HeaderRowRange.Row).Value ' Vérification des 3 conditions (Si vide = OK, sinon on compare) condMois = (valMois = "" Or itemMois = valMois) condID = (valID = "" Or itemID = valID) condTexte = (valRecherche = "" Or InStr(1, itemRecherche, valRecherche, vbTextCompare) > 0) ' Si les 3 conditions sont respectées, on ajoute à la liste If condMois And condID And condTexte Then Liste_Matricule_et_nom.AddItem itemRecherche End If End If Next cell End Sub
3. Explication
🎓 VBA : Créer un système de filtres multicritères en cascade
Dans cet article, nous passons au niveau supérieur. Imaginez que vous ayez des milliers de lignes de paie. Une simple barre de recherche ne suffit plus. Vous avez besoin de filtrer par Période, puis par ID, tout en gardant la possibilité de taper un nom.
Le concept du "Entonnoir" (Cascade)
L'astuce consiste à ne plus traiter chaque filtre séparément, mais à créer une procédure centrale d'analyse. À chaque mouvement de l'utilisateur (choix d'un mois, clic sur un ID ou frappe d'une lettre), le système relit la base de données à travers un "entonnoir" à trois niveaux :
Niveau 1 (Mois) : On ne garde que les lignes de la période choisie.
Niveau 2 (ID) : Parmi ces lignes, on ne garde que l'employé spécifique.
Niveau 3 (Recherche) : On affine le résultat final par rapport aux caractères saisis.
Pourquoi c'est une révolution pour votre fichier ?
Fluidité : Si aucun filtre n'est activé, toute la liste s'affiche. Dès que vous agissez, la liste se réduit instantanément.
Logique cumulative : Le filtre respecte l'ordre de priorité (Mois > ID > Recherche) pour une expérience utilisateur naturelle.
Fiabilité : En utilisant des variables Booléennes (
condMois, etc.), le code est extrêmement rapide et facile à lire.
Conseil de pro :
Pour que ce système soit parfait, n'oubliez pas d'ajouter un petit bouton "Réinitialiser" qui vide vos 3 contrôles (Value = "") pour retrouver la liste complète en un seul clic !
Note technique : J'ai utilisé cell.Row - tbl.HeaderRowRange.Row pour trouver exactement la ligne correspondante dans les autres colonnes du tableau structuré. C'est la méthode la plus propre pour croiser des données dans un ListObject.
Commentaires
Enregistrer un commentaire