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:
1757853539139.png


Je voudrais récupérer ça:
1757853684753.png
ou
1757854549856.png
 
Dernière édition:
@patricktoulon,
Bien sûr qu'il ne faut pas tout jeter. Les valeurs uniques sont la réponse à la question initiales donc il faut les conserver.


Je n'ai absolument pas compris ce que tu dis là.
Les Areas sont des Ranges comme les autres et on peut mettre en table leurs valeurs avec T = Areas.Value car on sait que c'est 8 fois plus rapide de faire référence à la table plutôt qu'aux cellules du Range (de l'Area).
Aussi on a vu plus haut que ce soit pour le T = Range.Value ou les T = Area.Value qu'il faut prendre le CStr(T(i, 1) sous peine de confondre les 0 et les Empty.
on parles alors de tableaux d'array
si tu met un array dans un key du dico il te sortira un array pas une valeur sauf si l'area est une seule cellule

c'est la base
 
si tu met un array dans un key du dico il te sortira un array pas une valeur sauf si l'area est une seule cellule
Je n'ai jamais parlé de mettre une Area dans un Key du dico. J'ai parlé de la récupération de valeurs d'une Area.
VB:
    For Each area In .Areas
        T = area.Value
        For I = 1 To UBound(T): Dico(T(I, 1)) = "": Next
    Next area
    TabVDicoUniquesColonneTS = Dico.Keys
De toutes façons, je vois pas en quoi une Area serait un Array. Une Area c'est un Range. T = Range.Value ou T = Area.Value, c'est du même bois.
Pour moi c'est ça la base. D'ailleurs j'utilise les valeurs des Areas dans le code joint et ça fonctionne, ce qui ne m'a jamais questionné.
Tu dois confondre avec Range.Areas (avec un s) ou je sais pas quoi.

A titre d'exercice, j'ai codé sur la base de vieilles fonctions en stock la récupération des valeurs uniques filtrées.
- En récupération des Criteria 1 et 2 (sous conditions voir Post 103 ci-dessus)
- Et si ça n'a pas fonctionné en parcours des valeurs après Sauvegarde des filtres / Suppression des filtres / Parcours / Restauration des filtres.

Ça a l'air de fonctionner, sauf sans doute dans un cas sur ce sujet que j'avais posté autrefois

Fichier: voir plus loin.
 
Dernière édition:
Ceci dit, ce n'est peut-être pas dénué de sens de prendre les valeurs des cellules visibles même si des filtres sont définis sur d'autres colonnes.
Car ce sera la liste des valeurs uniques visibles dans la colonne ce qui peut présenter un intérêt.
 
re
oui c'est les uniques d'une colonne sur plage filtrée ou pas
donc au final c'est plus une fonction unique qu'une fonction filter list
cala dit en effet sans l'argument filter ,ça répond a la question initiale

le segment c'était bien aussi (dommage qu'il y est une limite qui se situe entre 50 000 et 100 000 lignes)
c'est relatif bien sur ,car sur moins ça fonctionne assez rapidement

bref on peut tourner ça autant de fois que l'on veut l,es seules solutions utilises le parcours
 
je n'ai pas la fonction UNIQUE dont il faudrait préciser si elle rend les valeurs uniques ou les valeurs uniques visibles.
Salut,
La fonction Unique renvoie les valeurs uniques de toute la plage :
La fonction UNIQUE d'Excel permet d'extraire des valeurs uniques à partir d'une plage ou d'un tableau. Elle fait partie des formules dynamiques introduites dans Excel 365 et Excel 2019+.

✅ Syntaxe de la fonction UNIQUE

Code:
=UNIQUE(plage, [par_colonne], [exactement_une_fois])

📌 Description des paramètres :​

ParamètreObligatoire ?Description
plage✅ OuiLa plage ou le tableau à partir duquel extraire les valeurs uniques.
[par_colonne]❌ NonVrai (=TRUE) pour comparer par colonne, Faux (=FALSE ou omis) pour comparer par ligne.
[exactement_une_fois]❌ NonVrai (=TRUE) pour retourner seulement les éléments qui apparaissent exactement une seule fois.
Faux (=FALSE ou omis) pour retourner les éléments distincts

et dans ton classeur est-ce normal que j'ai cela quand je clique sur le bouton valeurs uniques filtrées sur la colonne 1 :
ValUniFiltrées.png


il n'y a pas de A3 dans la colonne 1 ?

Et là tu nous montres un classeur où il n'y a pas beaucoup d'éléments mais dans le classeur qui a 350000 enregistrements et 137 colonnes il y a quoi dans les colonnes ? Le classeur doit avoir une taille gigantesque. Quand on arrive à cela il faut passer à une véritable base de données. Tout sera plus rapide.

Nullosse
 
Dernière édition:
Bonjour @Dudu2
non je ne crois pas(sauf erreur de ma part)
la fonction unique fait FI des lignes visibles ou invisibles ,elle prend toute la plage (et colonne)
c'est pour ça que dans ma dernière fonction j'ai un argument "Filter"
si filter on passe par le dico sinon la fonction unique
c'est juste un switch pour éviter le parcours qui est forcement plus lent si on les veut tous

Patrick
 
Salut les Listeurs,
et dans ton classeur est-ce normal que j'ai cela quand je clique sur le bouton valeurs uniques filtrées sur la colonne 1 :
Oui c'est normal, car la liste des valeurs uniques filtrées de la colonne 1 ce n'est pas la liste des valeurs uniques visibles de la colonne 1.

La liste des valeurs uniques filtrées de la colonne 1 correspond aux valeurs uniques du filtre spécifique à la colonne 1, sans tenir compte des filtres des autres colonnes.
 
Bonjour Le forum


Code:
Début Macro
   │
   ▼
Vérifie si filtre actif ?
   │
   ├─ Non → Option 1 : décocher manuellement un critère
   │        │
   │        ▼
   │     FiltrerDonnees1 (décoche critère différent, récupère visibles, ajoute "Vide" si nécessaire)
   │        │
   │        ▼
   │     StockTableau (capture Criteria1 dans arr)
   │        │
   │        ▼
   │     FiltrerDonnees2 (recapture critère décoché, ajoute dans arr)
   │        │
   │        ▼
   │     Nettoyage arr (supprime '=', transforme en tableau propre)
   │        │
   │        ▼
   │     MsgBox affichage
   │        │
   │        ▼
   │     Désactivation filtre
   │
   └─ Oui → Option 2 : VBA simule décochage (SendKeys)
            │
            ▼
         FiltrerDonnees1
            │
            ▼
         StockTableau
            │
            ▼
         FiltrerDonnees2
            │
            ▼
         StockTableau
            │
            ▼
         Nettoyage arr
            │
            ▼
         MsgBox affichage
            │
            ▼
         Désactivation filtre

Code:
Sub ListeFiltre()
' LireValeursFiltre
  Dim ws As Worksheet
  Dim f As AutoFilter
  Dim filtre As Filter
  Dim arr As Variant
'
    Set ws = ActiveSheet
'
' La Matrice (Le tableau = La Plage)
  Dim premiereCellule As Range
    Set premiereCellule = ActiveCell.CurrentRegion.Cells(1)
'
' Le choix de la colonne de La Matrice (Le tableau = La Plage)
' Ici Choix de la colonne 1
    Dim Colonne As Integer ' Choix de la colonne ici la colonne 1
        Colonne = ActiveCell.Column - premiereCellule.Column + 1
'
' Choix le premier critére de du Filtre
' En rapport avec les deux fonction de récupération :
' FiltrerDonnees1 & FiltrerDonnees2
    Dim Critére As String
    premiereCellule(1, 1).Select
    Critére = premiereCellule(2, 1)
'
' Activer le filtre si ce n'est pas déjà fait
    If ws.AutoFilterMode = False Then
        ws.Rows(1).AutoFilter
'   --- Décocher la première valeur (du Filtre) ---
'   --- Argument = strictement Différent de l'argument.
        FiltrerDonnees1 Critére, premiereCellule, Colonne
        StockTableau ws, f, filtre, arr
        On Error Resume Next
        arr(UBound(arr)) = "Vide"
        ReDim Preserve arr(1 To UBound(arr) + 1)
        On Error GoTo 0
'   --- Cocher la première valeur (du Filtre) ---
'   --- Argument = strictement l'argument.
        FiltrerDonnees2 Critére, premiereCellule, Colonne
        StockTableau ws, f, filtre, arr
'   --- Désactiver le filtre si nécessaire ---
        ws.AutoFilterMode = False
    ElseIf ws.AutoFilterMode = True Then
        Set f = ws.AutoFilter
        Set filtre = f.Filters(Colonne)
            If filtre.On Then
'           --- Décocher la première valeur (du Filtre) ---
'           --- Argument = strictement Différent de l'argument.
                StockTableau ws, f, filtre, arr
                arr(UBound(arr)) = "Vide"
                ReDim Preserve arr(1 To UBound(arr) + 1)
'           --- Cocher la première valeur (du Filtre) ---
'           --- Argument = strictement l'argument.
                FiltrerDonnees2 Critére, premiereCellule, Colonne
                StockTableau ws, f, filtre, arr
'           --- Désactiver le filtre si nécessaire ---
                ws.AutoFilterMode = False
            End If
    End If
    On Error Resume Next
    ' Transformer en chaîne, supprimer "=", puis recréer le tableau
    arr = Split(Replace(Join(arr, "|"), "=", ""), "|")
    MsgBox Join(arr, vbCrLf), vbInformation, "Contenu du tableau"
    On Error GoTo 0
End Sub
'
' ==================================================================================================
'
Sub StockTableau(ByVal ws As Worksheet, ByVal f As AutoFilter, ByVal filtre As Filter, ByRef arr As Variant)
    Set f = ws.AutoFilter
    If Not f Is Nothing Then
        Set filtre = f.Filters(1) ' Exemple : première colonne filtrée : f.Filters(1)
        If filtre.On Then
            ' Criteria1
                'Debug.Print "Critère appliqué : " & "filtre.Criteria1"
            ' --- Charger dans un tableau ---
                    If IsArray(arr) Then
                        If UBound(arr) > 0 Then
                            'x = True
                            arr(UBound(arr)) = filtre.Criteria1
                        Else
                            'x = False
                        End If
                    Else
                        'MsgBox "Tableau vide"
                        arr = filtre.Criteria1
                    End If
            ' Criteria2
                If filtre.Operator = xlOr Then
                    'Debug.Print "OU Critère2 : " & filtre.Criteria2
                End If
        End If
    End If
End Sub
'
' ==================================================================================================
'
Sub FiltrerDonnees1(ByRef Critére As String, ByVal premiereCellule As Range, ByRef Colonne As Integer)
' Argument = strictement Différent de l'argument.
    premiereCellule.AutoFilter
    premiereCellule.AutoFilter Field:=Colonne, Criteria1:="<>" & Critére
End Sub
'
Sub FiltrerDonnees2(ByRef Critére As String, ByVal premiereCellule As Range, ByRef Colonne As Integer)
' Argument = strictement l'argument.
    premiereCellule.AutoFilter
    premiereCellule.AutoFilter Field:=Colonne, Criteria1:=Critére
End Sub

Option 2 (il faut trouver l'astuce avec SenKey) pour reproduire l'option 1 (faite a la main)

Code:
┌───────────────────────────┐
│        Début Macro        │
└─────────────┬─────────────┘
              │
              ▼
┌───────────────────────────┐
│Filtre Excel actif ?        │
└─────────┬─────────┬───────┘
          │         │
          │ Non     │ Oui
          ▼         ▼
 ┌────────────────┐  ┌─────────────────┐
 │Option 1 :      │  │Option 2 :       │
 │Décoche manuel  │  │VBA simule décoch│
 │d’un critère    │  │(SendKeys)       │
 └─────────┬──────┘  └─────────┬───────┘
           │                    │
           ▼                    ▼
  ┌────────────────────┐   ┌────────────────────┐
  │FiltrerDonnees1      │   │FiltrerDonnees1      │
  │- Décoche critère     │   │- Décoche critère     │
  │  différent du cible  │   │  différent du cible  │
  │- Récupère toutes     │   │- Récupère toutes     │
  │  les autres valeurs  │   │  les autres valeurs  │
  │- Ajoute "Vide" si    │   │- Ajoute "Vide" si    │
  │  nécessaire          │   │  nécessaire          │
  └─────────┬───────────┘   └─────────┬───────────┘
            │                          │
            ▼                          ▼
  ┌────────────────────┐   ┌────────────────────┐
  │StockTableau         │   │StockTableau         │
  │- Capture Criteria1  │   │- Capture Criteria1  │
  │  dans arr           │   │  dans arr           │
  └─────────┬───────────┘   └─────────┬───────────┘
            │                          │
            ▼                          ▼
  ┌────────────────────┐   ┌────────────────────┐
  │FiltrerDonnees2      │   │FiltrerDonnees2      │
  │- Recapture critère   │   │- Recapture critère   │
  │  décoché initial     │   │  décoché initial     │
  │- Ajoute valeur dans  │   │- Ajoute valeur dans  │
  │  arr                 │   │  arr                 │
  └─────────┬───────────┘   └─────────┬───────────┘
            │                          │
            ▼                          ▼
  ┌───────────────────────────────┐
  │ Nettoyage du tableau arr       │
  │ - Supprime "="                 │
  │ - Transforme en tableau propre │
  └─────────────┬─────────────────┘
                ▼
  ┌───────────────────────────────┐
  │ Affichage final (MsgBox)      │
  └───────────────────────────────┘
                │
                ▼
  ┌───────────────────────────────┐
  │ Désactivation filtre si besoin │
  └───────────────────────────────┘
 
re:
à ben si Laurent commence à nous faire des cartes mentales d’algorithme alors .... 🤣
vous allez me le faire tilter le dudu là🤪🤣

après trêve de plaisanterie
je pige pas le besoin selon la question de base a savoir (tout les filtres possibles dans une colonne)
d'aller chercher le bouton des filtres et tout les criterials et tout le toutim
unique ou dico c'est tout ou segment si la plage n'est pas trop grande
 
je pige pas le besoin selon la question de base a savoir (tout les filtres possibles dans une colonne)
d'aller chercher le bouton des filtres et tout les criterials et tout le toutim
D'abord c'est pour dire qu'on l'a fait (autant que possible), ensuite c'est immédiat.
Pour ceux qui cherchent la performance, immédiat c'est bien, non ?
P.S. je parle du code de ma fonction (Post #110, TabCriteriaFiltresColonneTS()) , pas du code de @laurent950 que je n'ai pas compris.
 
Dernière édition:
@laurent950
je ne vois pas très bien le but mais si tu y tiens
VB:
Sub developpefilterandcoche()
    [a1].Select
    If Not ActiveCell Is Nothing Then
        Dim sh As Object
        Set sh = CreateObject("WScript.Shell")
       
        sh.SendKeys "%{DOWN}" ' ouverture du dialog filtre
      
         'tout decocher
        sh.SendKeys "{DOWN 8}" 'aller à Sélectionner tout augmenter pour descendre plus base
         sh.SendKeys " " 'decoche l'item
        'si  "selectionner tout" est décoché le dialogue ne peut pas se refermer'
       
        'sinon le premier item du filtre decoché et fermeture du dialog
         'sh.SendKeys "{DOWN 9}" 'sélectionne le premier item après "selectionner tout"
        'sh.SendKeys " " 'decoche l'item
        'sh.SendKeys "{Enter}"
       
    End If
End Sub
Patrick
 
- 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
1
Affichages
145
Retour