Microsoft 365 ComboBox Liés pour Filtre ListView

TCHIS

XLDnaute Occasionnel
Bonjour le forum

J'ai besoin d'aide pour élaborer une macro de filtre d'une ListView en fonction des critères choisis dans mes combobox le point particulier est que ces ComboBox doivent liées entre elles je veux dire par là que lorsqu'on applique un filtre sur un Critère les Critères restant présenteront leurs données de filtres en fonctions du filtre précédant ainsi de suite.

La particularité c'est que j'ai 9 critères de filtres (9ComboBox) et le filtre ne suit pas un ordre quelconque je veux dire par là qu'on est libre de commencer à filtrer à partir de n'importe quel critère(Voilà pourquoi je me demande si la méthode de filtre en cascade avec les différents Combobox) peut passer 🤔🤔🤔 ?

Voici un extrait du la ListView et des Contrôles
1683544379625.png
 
Solution
Bonjour à tous,
Je me permets de proposer une solution via un module de classe.
Ici il est possible de revenir en arrière pour chaque choix en sélectionnant l'entête dans la liste déroulante. Il y a également un reset pour l'ensemble des filtres.
Démo_.gif

Le code principal est contenu dans le module de classe, + quelques lignes à ajouter dans le code de l'usf.
En PJ, 2 versions avec ou sans listview (usf simplifié pour ne montrer que la fonction filtre)

Nb : pour ce code, on renseigne le tag des combobox avec le n° de la colonne correspondante. Le code est alors fonctionnel sans modif quelque soit le nombre de combobox.

P.

TooFatBoy

XLDnaute Barbatruc
Alors c'est idiot, réfléchissez, parce que toute ComboBox renseignée n'aura plus qu'une liste d'un seul élément qui sera sa valeur.
C'est pourtant bien ce que semble vouloir obtenir Tchiss.

Je sais bien qu'à la fin toutes les ComboBox n'auront plus qu'une seule ligne dans leur liste, mais rien ne dit qu'on ira jusqu'à faire un choix dans toutes les ComboBox.
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Mais bon sang elle ne sert plus à rien cette liste puisqu'un choix y a été fait. À moins qu'on veuille repartir de la situation au moment où on l'avait fait pour choisir autre chose …
Ce n'est pas à la fin que toutes les ComboBox n'ont plus qu'une ligne dans leur liste: même quand une seule ComboBox est renseignée celle ci n'aurait plus qu'une ligne dans sa liste puisqu'il n'y aurait que cette valeur dans la ListView ! On ne pourrait même plus la changer sauf à tout réinitialiser.
 

TooFatBoy

XLDnaute Barbatruc
Ce n'est pas à la fin que toutes les ComboBox n'ont plus qu'une ligne dans leur liste: même quand une seule ComboBox est renseignée celle ci n'aurait plus qu'une ligne dans sa liste puisqu'il n'y aurait que cette valeur dans la ListView ! On ne pourrait même plus la changer sauf à tout réinitialiser.
Si, ce n'est qu'à la fin (ou presque, ça dépend des données). ;)

Oui, évidemment quand on choisi un item dans une ComboBox, celle-ci ne contiendra alors plus qu'un seul item, mais ça n'impactera pas forcément toutes les autres ComboBox.


Du moins, d'après ce que j'ai compris de la question. ;)
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Bien sûr que si, ça impacte les listes des ComboBox non renseignées, où devront figurer les valeurs présentes dans ces lignes là seulement, mais de leurs propres colonnes. C'est ce que fait automatiquement mon objet ComboBoxLiées chaque fois qu'une des ComboBox dont il a la charge change: il révise ainsi les listes de celles non renseignées et avertit l'UserForm et lui transmet la liste des numéros de lignes couverts.
 
Dernière édition:

TooFatBoy

XLDnaute Barbatruc
Bien sûr que si, ça impacte les listes des ComboBox non renseignées, où devront figurer les valeurs présentes dans ces lignes là seulement, mais de leurs propres colonnes.
Tu as raison, dans l'absolu ça impacte bien sûr toutes les ComboBox non encore renseignées.

Ce que je voulais dire, c'est qu'une ComboBox non encore renseignée, et donc impactée, pourra voir sa liste d'items ne pas être modifiée (ça dépend des valeurs restant dans la ListView). C'est en ce sens que je la disais "pas forcément impactée", vu qu'elle reste identique. ;)
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Elle ne seraient pas impactées seulement si dans la colonne de la ComboBox considérée il ne restait qu'une seule valeur possible dans toutes les lignes fitrées d'après les autres ComboBox déjà renseignées. Mais dans ce cas cette valeur serait assumée. Par conséquent tout choix imposé du fait que ce n'est pas le cas réduit les lignes à considérer des non renseignées. Mais c'est vrai que leurs listes elles mêmes peuvent ne pas changer s'il restait les mêmes valeurs partout. Mais les Sujet changent quand même. Ce que j'appelle un Sujet c'est un Varriant/Array(LesClés, LesListes). Les listes de numéros de lignes seront forcément réduites, mais il se peut que ça n'impacte pas les clés si dans le Sujet avant filtre il n'existait aucune clé seulement mentionnée ailleurs que dans les lignes de la liste réduite.
 

p56

XLDnaute Occasionnel
Bonjour à tous,
Je me permets de proposer une solution via un module de classe.
Ici il est possible de revenir en arrière pour chaque choix en sélectionnant l'entête dans la liste déroulante. Il y a également un reset pour l'ensemble des filtres.
Démo_.gif

Le code principal est contenu dans le module de classe, + quelques lignes à ajouter dans le code de l'usf.
En PJ, 2 versions avec ou sans listview (usf simplifié pour ne montrer que la fonction filtre)

Nb : pour ce code, on renseigne le tag des combobox avec le n° de la colonne correspondante. Le code est alors fonctionnel sans modif quelque soit le nombre de combobox.

P.
 

Pièces jointes

  • Combo_liées _2023_ListView.xlsm
    89.4 KB · Affichages: 14
  • Combo_liées _2023.xlsm
    84.5 KB · Affichages: 13

Dranreb

XLDnaute Barbatruc
Bonjour.
Remarque: avec mes objets il est très facile de regarnir les contrôles à partir d'une ligne sélectionnée dans la ListView si on a gardé une copie du tableau de Long Lignes transmis à la Sub CLs_Résultat.
VB:
Private Sub Lvw_NATIFS_ItemClick(ByVal Item As MSComctlLib.ListItem)
   Dim LDon As Long
   LDon = TLgn(Item.Index)
   TVL = CLs.Lignes(LDon).Range.Value
   CLs.ValeursDepuis TVL
   CAs.ValeursDepuis TVL
   End Sub
 

cp4

XLDnaute Barbatruc
Bonjour le fil,

@p56 ;) : Merci pour ton partage. Cependant, je viens d'ouvrir le formulaire du fichier Combo_Liées_2023, avec excel2010 32bits, le code plante "incompatibilité de type" dans le code du module de classe.
Est-ce que ma version d'Excel serait en cause?
incompatibilité de type.JPG

Merci. Bon week-end.

edit: même plantage pour l'autre fichier avec Listview
 

p56

XLDnaute Occasionnel
Bonjour à tous,

@cp4 : en effet il se peut que la version d'excel soit en cause. La parade est simple :
1/ copier-coller la Function Transpose (code ci-dessous) dans le module de classe
2/ remplacer les 2 occurrences de Application.Transpose par Transpose tout court (dans le même module)

Et ça devrait régler le problème
Merci du signalement
P.
VB:
Function Transpose(Ttk As Variant) As Variant ' Auteur P56
Dim T As Variant, i As Long, j As Long

    ReDim T(LBound(Ttk, 2) To UBound(Ttk, 2), LBound(Ttk, 1) To UBound(Ttk, 1))
    For i = LBound(Ttk, 2) To UBound(Ttk, 2)
        For j = LBound(Ttk, 1) To UBound(Ttk, 1)
            T(i, j) = Ttk(j, i)
        Next j
    Next i
    Transpose = T
End Function
 

cp4

XLDnaute Barbatruc
Bonjour à tous,

@cp4 : en effet il se peut que la version d'excel soit en cause. La parade est simple :
1/ copier-coller la Function Transpose (code ci-dessous) dans le module de classe
2/ remplacer les 2 occurrences de Application.Transpose par Transpose tout court (dans le même module)

Et ça devrait régler le problème
Merci du signalement
P.
VB:
Function Transpose(Ttk As Variant) As Variant ' Auteur P56
Dim T As Variant, i As Long, j As Long

    ReDim T(LBound(Ttk, 2) To UBound(Ttk, 2), LBound(Ttk, 1) To UBound(Ttk, 1))
    For i = LBound(Ttk, 2) To UBound(Ttk, 2)
        For j = LBound(Ttk, 1) To UBound(Ttk, 1)
            T(i, j) = Ttk(j, i)
        Next j
    Next i
    Transpose = T
End Function
Bizarre que "Application.Transpose" plante car le tableau fait 774 lignes sur 17 colonnes.
J'ai ajouté la fonction et effectué les modifications préconisées. Là, ça plante (voir image ci-dessous)

1683989191149.png

Merci pour tes conseils et retour.
 

p56

XLDnaute Occasionnel
Rhôô! 2010 n'aime pas les Application.machin, on dirait!

Alors pareil, on copie-colle la Function Td_cl (ici équivalent à Application.index) dans le module de classe
puis on remplace la ligne surlignée plus haut par :
Code:
.Range("TTK1").Resize(UBound(Td, 1), 1) = Td_cl(Td, cl)

VB:
Function Td_cl(Td As Variant, cl As Integer)
Dim T As Variant, i As Long

    ReDim T(1 To UBound(Td, 1), 1 To 1)
    For i = 1 To UBound(T)
        T(i, 1) = Td(i, cl)
    Next i
     Td_cl = T
End Function
P.
 

Discussions similaires

Statistiques des forums

Discussions
311 720
Messages
2 081 926
Membres
101 841
dernier inscrit
ferid87