Filtre avancé dans Macro
Bonjour,
je suis en train de me faire une base de données sous excel de mes films,
que j'aimerai pouvoir filtrer en fonction de la sélection d'acteur via un menu déroulant.
Cette liste déroulante est générée automatiquement pour proposer les acteurs présents dans la liste de mes films.
La difficulté que je rencontre est que je souhaite que la liste des acteurs d'un film soit dans une seule case, chaque nom séparé par une virgule suivant d'un espace. (Acteur 1, Acteur 2, ..., Acteur X)
Pour générer ma liste déroulante, voila ce que j'ai fait :
- Fonction "Convertir" de la colonne acteurs pour avoir chaque nom d'acteur dans une case.
- Concaténation des différentes colonnes pour n'en faire plus qu'une
- Filtre pour éliminer les doublons et cases vides
Je vous ai joins mon fichier, cous constaterez donc les problèmes que j'ai rencontré :
- Fonction "Convertir" : Demande une confirmation "Voulez-vous remplacer le contenu des cellules de destination"
---> J'aimerai que cette demande de confirmation disparaisse.
- Quand je filtre par acteur, je dois mettre "*" devant chaque nom d'acteur de la liste déroulante afin qu'ils soient trouver même dans les cases ou ce n'est pas l'acteur principal, j'ai donc concaténé "*" à chaque nom avant de générer ma liste.
---> Est-il possible dans "filtre avancé" de filtré avec comme critère "Contient" ?
Dernière question subsidiaire : Comment lancer ma Macro de filtre dès qu'il y a un changement de valeurs dans la case de choix de filtre ??
Merci d'avance pour votre aide, je débute en Excel et j'ai donc surement fait des manips hasardeuses...
- Messages
- 9'246
- Excel
- Vista Office 2007FR
- Inscrit
- 08/12/2007
- Emploi
- retraité Sce.Méthodes
Bonjour à tous,
Il me semble que tu complique avec la liste déroulante !
Vois cet exemple, simple d'utilisation
Bonne journée
Claude.
Bonsoir,
Regarde le fichier joint
En sélectionnant la cellule D2, tu vas déclencher un évènement qui fera :
- création d'une liste de tous les acteurs
- tri de cette liste
- ajout de cette liste dans la colonne F (masquée)
- insertion d'une validation de données dans la cellule D2
Dès que tu choisis un acteur, la formule dans la cellule E2 (masquée) sert pour le filtre élaboré
pour afficher tous les films, appuie sur Suppr (ou efface la cellule) dans la cellule D2
bonne soirée
Merci pour vos réponses :
Dubois -> Merci pour le fichier exemple, je l'avais déja trouvé dans un autre post sur le forum,
mais ce qui me dérange c'est la recherche par acteurs :
Par exemple si tu recherches tous les films avec "Denis QUAID", tu es obligé de faire 3 recherches : une en recherchant dans Acteur 1, l'autre dans Acteur 2...
Puis en utilisant une colonne par "Acteur", soit tu es limité à un petit nombre d'acteurs (3 dans ton fichier) soit tu te retrouves avec un tableau immense car tu voulais prévoir 10 acteurs.
Et puis je tiens à mes listes déroulantes...
Cousinhub -> Super, Merci ! Ton fichier fait exactement ce que je souhaite faire,
par contre je suis incapable de comprendre le code derrière tout ça !
Aurais-tu la gentillesse de le commenter afin que je puisse comprendre étape par étape comment tu as fait,
et que je puisse transposer ce code dans mon vrai fichier de gestion de films ??
Merci d'avance !
Bonsoir,
le code commenté :
dans le code de la feuille 1
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Count > 1 Then Exit Sub 'si plus d'une cellule modifiée, on quitte
If Target.Address = "$D$2" Then ' si la cellule modifiée est la cellule D2
If Target = "" Then ' si on efface la cellule D2
On Error Resume Next ' au cas où il n'y aurait pas de filtre en fonction, on se prévaut de l'erreur
Me.ShowAllData ' on affiche tout le tableau
On Error GoTo 0 ' on remet la gestion des erreurs en fonction
Else ' si la cellule D12 contient un nom d'acteur
Range("base").AdvancedFilter Action:=xlFilterInPlace, CriteriaRange:= _
Range("E1:E2"), Unique:=False ' on fait un filtre élaboré sur place, avec comme critère
End If ' les cellules E1:E2
End If
End Sub
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim Cel As Range
Dim MesActeurs As Object
Dim Tmp
Dim I As Integer
If Target.Address <> "$D$2" Or Target.Count > 1 Then Exit Sub ' si la cellule sélectionnée n'est pas D2
' ou que tu as sélectionné plusieurs cellules
' on quitte
Set MesActeurs = CreateObject("Scripting.Dictionary") ' création d'un objet "Dictionnary" qui nous permettra
' d'y intégrer tous les noms d'acteurs sans doublons
For Each Cel In Range("B3:B" & [B65000].End(xlUp).Row) ' pour chaque cellule de B3 à Bxx (derlière ligne remplie)
Tmp = Split(Cel.Value, ",") ' dans le tableau à une dimension, on "splitte" la valeur
' de la cellule, chaque nom séparé par une virgule se trouvant
' dans le tableau (tmp(o), pour le 1er nom, tmp(1) pour le 2ème...
For I = LBound(Tmp) To UBound(Tmp) ' de la 1ère valeur du tableau tmp à la dernière
If Not MesActeurs.Exists(Trim(Tmp(I))) Then MesActeurs.Add Trim(Tmp(I)), Trim(Tmp(I))
' c'est ici qu'on utilise l'object dictionnary
' si le nom n'y existe pas, on le rajoute dans l'objet
' Trim permettant de supprimer les espaces en début
' et fin du nom
Next I ' au suivant
Next Cel ' cellule suivante
Tmp = MesActeurs.Items ' on rentre toutes les valeurs de l'objet dictionnary dans
' un tableau à une dimension
Call tri(Tmp, LBound(Tmp), UBound(Tmp)) ' on effectue le tri de ce tableau (voir dans Module1
Columns(6).ClearContents ' on vide la liste des acteurs qu'il y avait dans la colonne F
Application.EnableEvents = False ' on interdit tout déclenchement d'évènement afin d'éviter des boucles
For I = LBound(Tmp) To UBound(Tmp) ' de la première valeur du tableau à la dernière
Cells(I + 1, 6) = Tmp(I) ' on remplit la colonne F des noms des acteurs, qui sont dans le tableau Tmp
Next I
With Target.Validation ' avec la validation des données de la cellule modifiée
.Delete ' on supprime l'ancienne "Données/Validation"
.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Operator:= _
xlBetween, Formula1:="=$F$1:$F$" & [F65000].End(xlUp).Row ' on en créé une nouvelle, avec les noms de la colonne F
End With
Range("A2:B" & [A65000].End(xlUp).Row).Name = "base" ' on détermine l'espace de travail, qui comprend les titres de films
' ainsi que les noms des acteurs (colonne A et B)
Application.EnableEvents = True ' on ré-autorise les déclenchements d'évènements
End Sub
et dans le module1 :
Sub tri(a, gauc, droi) ' Quick sort
'code de tri de JBoisgontier (http://boisgontierj.free.fr/)
'code hyper rapide
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
Bonne soirée
Merci beaucoup,
dès que j'ai un peu de temps, je vais me pencher sur ce code, et tenter de comprendre un temps soit peu ce qu'il fait.
Je reviendrai vers toi si j'ai des questions,
mais je vais essayer de me débrouiller.
Hello le forum,
Je profite de ce post pour vous exposer mon problème.
J'ai sensiblement le même que le problème exposé et la réponse de DUBOIS correspondrait extactement à ma recherche.
Je voudrais cependant y ajouter deux choses:
- Pas de conditions sur les colonnes ( ici le tric s'arrête à la colonne J), je voudrais aller jusqu"à AA voir encore mieux qu'il detectecte automatiquement les colonnes
- SI je tape en A5 un numero de serie par exemple L00010100.
Je voudrais qu'à la suite de la macro xls ne m'affiche que les lignes où mon numéro de serie est compris dans l'intervalle des colonnes A et B,
Tout ceci en gardant la jolie interface de DUBOIS
Merci les experts !
Petit up pour vous informer que je souhaiterai partir vers la macro suivante:
If Target.Address = "$A$1" Then
[F2] = IIf(Target = "", "", "=AND(A$1>=B2,A$1<=C2)")
[B:E].AdvancedFilter xlFilterInPlace, [F1:F2]
[F2] =
Mais comment faire???