Ceci est une page optimisée pour les mobiles. Cliquez sur ce texte pour afficher la vraie page.

XL 2016 VBA - Est-il possible de récupérer toutes les valeurs de filtre possible sans parcourir la colonne

  • Initiateur de la discussion Initiateur de la discussion Dudu2
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

Dudu2

XLDnaute Barbatruc
Bonjour,

Supposons un colonne qui peut être filtrée et qui est ou non filtrée.
Peut-on récupérer toutes les valeurs listées dans la liste déroulante du filtre sans parcourir les données.

Soit ce tableau:


Je voudrais récupérer ça:
ou
 
Dernière édition:
@nullosse,
Dudu2 dis-nous si ce que j'affiche dans le gif animé de mon post #64 c'est ce que tu veux ou bien autre chose ?
Non, j'ai vu que tu ne prenais que les visible cells, donc tu récupères une liste de valeurs après filtre.

J'aurais dû dire, quelque soit le filtre appliqué à la colonne, je veux la liste des valeurs uniques sans parcours des valeurs, ce que les Segments permettent mais avec une performance dégradée. Donc au final seul le parcours de toutes les valeurs permet d'obtenir le résultat.

J'ai dit en Post 1.
Je voudrais récupérer ça:

Ça me semble explicite mais apparemment pas !
 
@patricktoulon, @laurent950,
pour tout de dire je pense que si on voulais lister UNIQUEMENT !!!!! les filtres (actifs!!!)donc cochés
il n'y aurait qu'une solution
boucle sur le visible de la plage
S'il y a filtre on peut récupérer les valeurs sur les filtres.
De mes vielles fonctions...améliorée
VB:
Sub a()
    Dim TabValeursDeFiltre As Variant
    Dim Rep As Variant
    Dim i As Integer
    Dim Area As Range
    Dim Range As Range
   
    Rep = Application.InputBox("Quel numéro de colonne ?", "Valeurs de filtre", 1, Type:=1)
    If VarType(Rep) = vbBoolean Then Exit Sub
   
    TabValeursDeFiltre = TabCriteria1FiltresColonneTS(ActiveSheet.ListObjects(1), CInt(Rep))
   
    Select Case VarType(TabValeursDeFiltre)
        Case vbArray + vbVariant
            For i = 1 To UBound(TabValeursDeFiltre)
                If TabValeursDeFiltre(i) = Empty Then TabValeursDeFiltre(i) = "(vide)"
            Next i
            MsgBox Join(TabValeursDeFiltre, vbCrLf)
       
        Case vbInteger
            If TabValeursDeFiltre = 0 Then MsgBox "Pas de valeurs de filtre pour la colonne #" & Rep & " !"
            If TabValeursDeFiltre = -1 Then MsgBox "La fonction ne peut pas récupérer les valeurs de filtre !"
    End Select
End Sub

'-------------------------------------------------------
'Critères de filtre d'une colonne d'un Tableau Structuré
'Return: Tableau (1-n) des valeurs des critères de filtre
'        0 si aucune valeur de filtre
'        -1 si c'est un cas non traité par la fonction
'-------------------------------------------------------
Private Function TabCriteria1FiltresColonneTS(Tbl As ListObject, TblNoColonne As Integer) As Variant
    Dim ReturnValue As Variant
    Dim Criteria1 As Variant
    Dim Criteria2 As Variant
    Dim Operator As Variant
    Dim ErrNumber As Long
    Dim i As Integer
   
    'Return value par défaut
    ReturnValue = 0

    With Tbl
        'Cas particulier où il n'y a pas de boutons de filtres retirés via Données/Filtrer
        If .AutoFilter Is Nothing Then GoTo SetReturnValue
       
        'Aucune colonne n'est filtrée
        If .AutoFilter.FilterMode = False Then GoTo SetReturnValue
        
        'Il n'y a pas de filtre sur la colonne demandée
        If Not .AutoFilter.Filters(TblNoColonne).On Then GoTo SetReturnValue

        With .AutoFilter
            Criteria1 = .Filters(TblNoColonne).Criteria1
            Operator = .Filters(TblNoColonne).Operator
           
            'Seuls opérateurs traités
            If Not (Operator = 0 Or Operator = xlFilterValues Or Operator = xlOr) Then
                'MsgBox "Function TabCriteria1FiltresColonneTS: Operator = " & Operator & "non supporté !"
                ReturnValue = -1
                GoTo SetReturnValue
            End If
           
            'Criteria1 = tableau de valeurs
            If IsArray(Criteria1) Then
                ReDim ReturnValue(1 To UBound(Criteria1))
                For i = LBound(Criteria1) To UBound(Criteria1)
                    ReturnValue(i) = IIf(Left(Criteria1(i), 1) = "=", Mid(CStr(Criteria1(i)), 2), CStr(Criteria1(i)))
                Next i
           
            'Critéria1 = une seule valeur
            Else
                'Cas particulier de l'exlusion de la valeur vide
                If Operator = 0 And Criteria1 = "<>" Then
                    'MsgBox "Function TabCriteria1FiltresColonneTS: Criteria1 = " & Criteria1 & "non supporté !"
                    ReturnValue = -1
                    GoTo SetReturnValue
                End If
               
                On Error Resume Next
                'Critéria2 = une valeur
                Criteria2 = .Filters(TblNoColonne).Criteria2
                Operator = .Filters(TblNoColonne).Operator
                ErrNumber = Err.Number
                On Error Resume Next
               
                If Err.Number = 0 And Operator = xlOr Then
                    ReDim ReturnValue(1 To 2)
                    ReturnValue(1) = IIf(Left(Criteria1, 1) = "=", Mid(CStr(Criteria1), 2), CStr(Criteria1))
                    ReturnValue(2) = IIf(Left(Criteria2, 1) = "=", Mid(CStr(Criteria2), 2), CStr(Criteria2))
                Else
                    ReDim ReturnValue(1 To 1)
                    ReturnValue(1) = IIf(Left(Criteria1, 1) = "=", Mid(CStr(Criteria1), 2), CStr(Criteria1))
                End If
            End If
        End With
    End With
   
SetReturnValue:
    'Return Value
    TabCriteria1FiltresColonneTS = ReturnValue
End Function

Mais il faut que l'Operator soit 0 (pas d'Operator) et que le filtre ne soit pas tout sauf valeurs vides, xlFilterValues ou xlOr.
 
Dernière édition:
En 2016, elle n'existe apparemment pas.

Regarde la pièce jointe 1222477

Sur 1 colonne désignée.
Effectivement elle n'existe que depuis Excel 2021
avec ce code dans Excel 2021:
VB:
tabval = Application.Transpose(WorksheetFunction.Unique(tbl.DataBodyRange))
je récupère les valeurs uniques du tableau à 1 colonne dans un array (tabval) sans boucler sur les éléments
 
Dernière édition:
Je pense que la récupérations des valeurs de filtre du Post #80 n'est valide que si les valeurs d'Operator sont:
- 0 (pas d'Operator)
- xlFilterValues
- xlOr

Pour toutes les autres valeurs de Operator de l'énumération, on ne peut déduire les valeurs uniques filtrées qu'en parcourant les VisibleCells.
 
Je l'ai déjà dit en Post #10, il y a une méthode pour trouver la totalité des valeurs uniques sans parcourir les valeurs.

- Défiltrer la colonne
- Ajouter une valeur barbare en fin de colonne
- Filtrer sur tout sauf celle valeur
- Récupérer les valeurs de filtre
- Supprimer la ligne générée par l'ajout de la valeur barbare
- Restorer les filtres d'origine

Je dois avoir toutes les fonctions qui vont bien pour faire ça, mais plus tard car je déconnecte pour le moment.

Edit: ma jolie théorie s'effondre car en filtrant sur tout sauf la valeur barbare, les autres valeurs de filtre n'apparaissent pas en liste des critères de filtre.

La preuve en image avec le fichier joint qui contient quand même quelques fonctions utiles sur les filtres.
 

Pièces jointes

Dernière édition:
selon l'idée de @nulosse
avec le clipboard on recupère les filtres cochés d'une colonne désignées par son index
on traite le vide si il y est
VB:
Sub d()
    Dim TabValeursUniques
    TabValeursUniques = TabclipBoardValeursUniquesColonneTS(ActiveSheet.ListObjects(1), 1)
    MsgBox Join(TabValeursUniques, vbCrLf)
End Sub

Function TabclipBoardValeursUniquesColonneTS(tbl As ListObject, TblNoColonne As Integer)
    Dim DataObj, texte
    tbl.DataBodyRange.Columns(TblNoColonne).SpecialCells(xlCellTypeVisible).Copy
    Set DataObj = CreateObject("New:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
    DataObj.GetFromClipboard
    texte = Replace(DataObj.GetText, vbCrLf, "|")
    Application.CutCopyMode = False
    If Left(texte, 1) = "|" Then texte = "(vides)" & Mid(texte, 1, Len(texte) - 2)
    TabclipBoardValeursUniquesColonneTS = Split(texte, "|")
End Function
mais Attention la encore ça mouline si il n'y a pas de filtre et si la plage est relativement grande

plus ça va plus je suis conforté dans mon opinion la boucle dico reste la méthode la plus simple et plus rapide
 
Dernière édition:
A mon avis la fonction WorksheetFunction.Unique doit être la méthode la plus rapide en VBA pour supprimer les doublons d'un tableau.
Pour un tableau composé de 250000 chaînes aléatoires de 8 lettres j'obtiens un temps de 45ms et dans le tableau résultat j'ai 53393 valeurs.
Mais hélas cette fonction n'existe que depuis Excel 2021
 
@nullosse si c'est un.filtre sur couleurs ?

Il faut écrire la règle.
Tableau ou tableau structuré
Filtre
Qu'elle colonne (1 ou.ou plusieurs)
C'est colonnes sont en états de Filtre actif ou pas
Si oui (comment les critères)
Si oui les couleurs
Et qu elle résultat attendu !

La vitesse c'est a voir ensuite...

Qui écrit la règle ?
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD

Discussions similaires

Réponses
72
Affichages
1 K
Réponses
1
Affichages
141
Les cookies sont requis pour utiliser ce site. Vous devez les accepter pour continuer à utiliser le site. En savoir plus…