Bonjour,
J'ai pourtant publié le code qui permet de savoir si une colonne, d'un tableau structuré, est filtrée ou pasPour le filtrage, il n'a jamais bien réussi à évaluer si un filtre était actif, non dans le tableau, mais DANS LA COLONNE!
Bonjour,
J'ai pourtant publié le code qui permet de savoir si une colonne, d'un tableau structuré, est filtrée ou pasPour le filtrage, il n'a jamais bien réussi à évaluer si un filtre était actif, non dans le tableau, mais DANS LA COLONNE!
Philippe Tulliez
Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément. (Nicolas Boileau)
Lorsque vous avez la réponse à votre question, n'oubliez pas de cliquer sur et si celle-ci est pertinente pensez à voter
Mes tutoriels : Utilisation de l'assistant « Insertion de fonction », Les filtres avancés ou élaborés dans Excel
Mon dernier billet : Utilisation de la fonction Dir en VBA pour vérifier l'existence d'un fichier
Bonjour,
Il me semblait avoir répondu à votre demande avec le code fourni au message numéro 13, et indiqué la procédure à suivre.
Suis je passé à côté de quelque chose ?
Mes tutoriels : Mémento sur la programmation pour Excel; La programmation en mode graphique; Le problème du voyageur de commerce; Crypter vos données dans Excel; Les fonctions SQL pour gérer les données; Créer des fonctions pour simplifier la vie des utilisateurs; Comprendre la méthode de factorisation du Crible Quadratique; Programmation de menus personnalisés pour Excel; Manipuler les données des bases Access depuis Excel; Transférer des fichiers volumineux avec Outlook; Algorithme ECM de factorisation par les courbes elliptiques; Un classeur Excel multi-utilisateur; Compresser/décompresser des fichiers au format ZIP; Fonctions pour gérer les Tableaux Structurés; Fonctions pour générer des courriels depuis Excel.
Merci pour vos réponses!
laurent_ott: non vous n'êtes pas passé à côté de quelque chose! C'est simplement que mes compétences ne sont pas à la hauteur des vôtres.
J'ai incorporé les fonctions appelées dans la macro, indiqué le nom de mon tableau structuré, mais j'ai "une erreur de syntaxe" dans la macro Public Function TS_TrierUneColonne, à la ligne
Du coup, je n'ai pas su comment continuer, surtout que, pour mon niveau, vos macros sont déjà complexes!
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2'Pose le tri sur la colonne TS.ListObject.Sort.SortFields.Add etc
Philippe Tulliez: c'est bien la macro que vous m'avez suggérée que j'ai utilisée:
...mais je n'ai pas su comment insérer le code permettant de savoir si une colonne est filtrée ou triée. Du coup, j'ai passé par l'IA, qui s'est assez vite égarée...
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 Sub SortFilter(Target As Range) Dim oList As ListObject Dim c As Integer Set oList = Target.ListObject With oList ' Calcul du numéro de colonne du tableau c = Target.Column - .Range.Column + 1 ' Calcul ' Vérifie si Target est dans DataBodyRange If Not Intersect(Target, .DataBodyRange) Is Nothing Then ' Appeler la macro de filtrage FiltrerColonne oList, c, Target.Value End If ' Vérifie si Target est dans HeaderRowRange If Not Intersect(Target, .HeaderRowRange) Is Nothing Then ' Appeler la macro de tri TrierColonne oList, c End If End With Set oList = Nothing End Sub
Si je reviens à vos propositions, celle qui suit est bien à placer dans un module standard?
Mais comment l'insérer dans la macro FiltrerColonne oList?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10 Function IsFilteredColumn(oList As ListObject, Column As Variant) ' Arguments ' oList Table a tester ' Column soit le nom de la colonne, soit son numéro ' With oList If VarType(Column) = vbString Then Column = .ListColumns(Column).Index IsFilteredColumn = .AutoFilter.Filters.Item(Column).On End With End Function
Mes questions vous paraîtront sans doute basiques, mais pour moi, elles ne sont pas si simples...
Merci de votre aide!
J'ai réussi à implémenter, en fonction de la structure que vous m'avez donnée, les macros de tri et de filtrage. Surtout, qui fonctionnent correctement... Cela n'a pas été si facile que ça, en fonction de mon degré de connaissances. Mais cela a fonctionné, avec l'aide (approximative) de Chat GPT. Merci pour votre aide!
Bonjour,
Ravi d'apprendre que cela fonctionneJ'ai réussi à implémenter, en fonction de la structure que vous m'avez donnée, les macros de tri et de filtrage. Surtout, qui fonctionnent correctement... Cela n'a pas été si facile que ça, en fonction de mon degré de connaissances. Mais cela a fonctionné, avec l'aide (approximative) de Chat GPT. Merci pour votre aide!
Comme j'étais en train de rédiger ma réponse, je la publie tout de même.
La procédure événementielle Workbook_SheetBeforeDoubleClick vérifie si un double-clic a lieu dans un tableau structuré du classeur. Si c'est le cas, elle invoque la procédure SortFilter (présente dans un module Standard).
La procédure SortFilter détermine si le double-clic a eu lieu dans la zone des titres ou dans celle des données du tableau :
Si l'événement a eu lieu dans la zone des données (DataBodyRange), elle filtre sur la valeur de la cellule où le double-clic a été effectué, ou supprime le filtre si la colonne était déjà filtrée.
Si l'événement a eu lieu dans la zone des titres, elle invoque la procédure SortTable en effectuant un tri croissant si la colonne n'était pas triée, ou si la colonne était triée par ordre décroissant.
Comment savoir si une colonne est filtrée ?
En invoquant la fonction IsFilteredColumn.
Comment savoir si une colonne est triée par ordre croissant ou décroissant ?
Lorsque l'on trie une ou plusieurs colonnes, le tri reste en mémoire. Il suffit donc de vérifier quelques propriétés du premier niveau de tri.
Comment savoir si le double-clic a eu lieu dans la zone des titres ou des données ?
En invoquant soit la fonction IsHeaderRowRange, soit la fonction IsDataBodyRange.
En pièce jointe, un classeur de test avec deux feuilles contenant chacune un tableau structuré. N'ayant pas plus de temps à consacrer à ce sujet, le filtre ne fonctionne pas avec les dates.
Code des procédures utilisées
Procédure événementielle Workbook_SheetBeforeDoubleClick
La procédure SortFilter
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 Private Sub Workbook_SheetBeforeDoubleClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean) Dim oList As ListObject Set oList = Target.ListObject ' Si le DoubleClick à lieu dans un tableau structuré on invoque SortFilter If Not oList Is Nothing Then SortFilter Target: Cancel = True Set oList = Nothing End Sub
La procédure SortTable
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 Sub SortFilter(Target As Range) ' Trie ou filtre la colonne d'un tableau structuré suivant un contexte ' Trie la colonne de Target si celui-ci se trouve dans Row ' Argument ' Target Cellule où a eu lieu le DoubleClick ' Déclaration des variables Dim oList As ListObject Dim c As Integer Set oList = Target.ListObject With oList ' Calcule le numéro de colonne du tableau c = Target.Column - .Range.Column + 1 ' Vérifie si Target est dans HeaderRowRange If IsDataBodyRange(Target) Then ' Si Target est dans DataBodyRange on filtre ou on supprime le filtre If IsFilteredColumn(oList, c) Then .Range.AutoFilter Field:=c Else .Range.AutoFilter Field:=c, Criteria1:=Target.Value End If End If ' Vérifie si Target est dans DataBodyRange If IsHeaderRowRange(Target) Then SortTable oList, IIf(GetSortOrder(oList, c) = 1, "-", "") & .ListColumns(c) End If End With Set oList = Nothing End Sub
Code des fonctions booléennes IsHeaderRowRange, IsDataBodyRange et IsFilteredColumn
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37 Function SortTable(oList As ListObject, _ Optional LabelList As String, _ Optional CustomList As String, _ Optional CaseSensitive As Boolean) ' Fonction de tri pour ListObject ' Trie Ascendant/Descendant de colonne(s) d'un tableau structuré ' Author : Philippe Tulliez (www.magicoffice.be) ' Date : 05/07/2021 ' Version : 3.1 ' Arguments ' oList (ListObject) ' [LabelList] (String) (Nom des étiquettes de colonne à trier séparé par ; (Exemple Voiture;Logement) ' Si l'étiquette est précédée par un signe négatif, le tri est descendat ' Exemple ("Service;-Logement;-Voiture") ' signifie que la colonne "Service" sera triée par ordre croissant, les deux autres par ordre décroisant ' [CustomList] String ' [CaseSensitive] Boolean ' Déclaration & Affectation Dim Sc As Range ' Colonne à trier Dim So As Byte ' Ordre de tri Dim Sl As Variant ' Liste des champs à trier Dim El As Integer ' Variable de boucle ' Liste des champs à trier suivant argument [LabelList] (Si vide l'Array prend l'étiquette de la première colonne) Sl = IIf(Len(LabelList), Split(LabelList, ";"), Array(oList.ListColumns(1).Name)) ' With oList .Sort.SortFields.Clear ' Insert level sort For El = LBound(Sl) To UBound(Sl) So = 1 + Abs(Left(Sl(El), 1) = "-"): Set Sc = .ListColumns(Mid(Sl(El), So)).DataBodyRange .Sort.SortFields.Add Key:=Sc, SortOn:=xlSortOnValues, Order:=So Next ' Sort With .Sort: .MatchCase = CaseSensitive: .Apply: End With End With Set Sc = Nothing End Function
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 Function IsHeaderRowRange(oRange As Range) As Boolean ' Renvoie True si oRange est dans HeaderRowRange Dim oList As ListObject Set oList = oRange.ListObject If Not oList Is Nothing Then IsHeaderRowRange = Not Intersect(oRange, oList.HeaderRowRange) Is Nothing Set oList = Nothing End If End Function
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 Function IsDataBodyRange(oRange As Range) As Boolean ' Renvoie True si oRange est dans DataBodyRange Dim oList As ListObject Set oList = oRange.ListObject If Not oList Is Nothing Then IsDataBodyRange = Not Intersect(oRange, oList.DataBodyRange) Is Nothing Set oList = Nothing End If End FunctionLa procédure GetSortOrder
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 Function IsFilteredColumn(oList As ListObject, Column As Variant) As Boolean ' Renvoie True si la colonn est filtrée ' Arguments ' oList Tableau structuré ' Column N° ou nom de la colonne ' With oList If VarType(Column) = vbString Then Column = .ListColumns(Column).Index IsFilteredColumn = .AutoFilter.Filters.Item(Column).On End With End Function
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 Function GetSortOrder(oList As ListObject, colIndex As Integer) As Integer ' Renvoie ' 0 si la colonne n'est pas triée ' 1 si la colonne est triée par ordre croissant ' 2 si la colonne est triée par ordre décroissant With oList.Sort If .SortFields.Count > 0 Then With .SortFields(1) If (.Key.Column - oList.Range.Column + 1 = colIndex) And .SortOn = xlSortOnValues Then GetSortOrder = .Order End If End With End If End With End Function
Philippe Tulliez
Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément. (Nicolas Boileau)
Lorsque vous avez la réponse à votre question, n'oubliez pas de cliquer sur et si celle-ci est pertinente pensez à voter
Mes tutoriels : Utilisation de l'assistant « Insertion de fonction », Les filtres avancés ou élaborés dans Excel
Mon dernier billet : Utilisation de la fonction Dir en VBA pour vérifier l'existence d'un fichier
Merci pour toutes ces précisions, qui m'auront été très utiles!
J'ai deux questions encore sur les tableaux structurés:
1) Comment, dans une macro comme celle que j'ai utilisée pour le DoubleClick (voir ci-dessous), peut-on ignorer certaines colonnes (pour le filtre, pour le tri, voire pour les deux? Comment indiquer à Excel, dans ce cas, qu'il ne doit rien faire en cas de double clic dans ces colonnes-là?
2) Peut-on laisser, dans un tableau structuré, certaines colonnes vides (sans valeurs, verrouillées, juste pour séparer visuellement certaines colonnes)?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14 Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) Application.ScreenUpdating = False Application.EnableEvents = False ' Vérifier si la cellule double-cliquée fait partie du tableau structuré "Rapports_finaux" If Not Intersect(Target, ActiveSheet.ListObjects("Rapports_finaux").Range) Is Nothing Then ' Appeler la macro pour trier ou filtrer en fonction de la cellule double-cliquée SortFilter Target ' Annuler l'événement de double-clic par défaut Cancel = True End If Application.EnableEvents = True End Sub
Bonjour,
En utilisant une structure décisionnelle comme If...End If ou un Select...Case. Voir l'exemple1) Comment, dans une macro comme celle que j'ai utilisée pour le DoubleClick (voir ci-dessous), peut-on ignorer certaines colonnes (pour le filtre, pour le tri, voire pour les deux? Comment indiquer à Excel, dans ce cas, qu'il ne doit rien faire en cas de double clic dans ces colonnes-là?
Un tableau structuré doit avoir un titre à chaque colonne.2) Peut-on laisser, dans un tableau structuré, certaines colonnes vides (sans valeurs, verrouillées, juste pour séparer visuellement certaines colonnes)?
Attention que la protection de la feuille bloque la propagation des lignes d'un tableau structuré
Dans l'exemple ci-dessous, on ne traite pas les colonnes "DATE FACTURE", "DATE D'ECHEANCE" et "Réalisé" mais attention que si l'on doit traiter plusieurs tableaux, il faudra éventuellement inclure le nom de la table.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 Private Sub Workbook_SheetBeforeDoubleClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean) Dim oList As ListObject Dim c As Integer Set oList = Target.ListObject ' Si le DoubleClick à lieu dans un tableau structuré on invoque SortFilter If Not oList Is Nothing Then With oList c = Target.Column - .Range.Column + 1 Select Case LCase(.ListColumns(c)) Case "date facture", "date d'echeance", "réalisé" Case Else SortFilter Target: Cancel = True End Select End With End If Set oList = Nothing End Sub
Philippe Tulliez
Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément. (Nicolas Boileau)
Lorsque vous avez la réponse à votre question, n'oubliez pas de cliquer sur et si celle-ci est pertinente pensez à voter
Mes tutoriels : Utilisation de l'assistant « Insertion de fonction », Les filtres avancés ou élaborés dans Excel
Mon dernier billet : Utilisation de la fonction Dir en VBA pour vérifier l'existence d'un fichier
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager