Je me suis fait quelques utilitaires de suppression / restoration de filtres sur tableau structuré.
Pourquoi ? Et bien parce que le Delete de lignes dans une tableau structuré filtré pose différents problèmes qu'on ne peut contourner qu'en supprimant les filtres.
Alors donc 2 fonctions principales dans le fichier joint: - Sub StockerFiltresTableauStructuré
- Sub DéstockerFiltresTableauStructuré
Jusque là pas de problème ça fonctionne, jusqu'au moment où j'ai placé un Filtre Couleur.
Le .Criteria1 récupéré en Stocker est un ObjetCriteria1:=RGB(255, 255, 0). Fort bien !
Mais évidemment le .Criteria1=<l'objet en question> plante en Déstocker. Et je ne sais pas comment le valoriser.
Scénario du test:
- Filtrer la colonne T2 sur la couleur jaune
- Cliquer sur le bouton StockerFiltres
- Cliquer sur le bouton SupprimerFiltres
- Cliquer sur le bouton DéstockerFiltres -> Plantage sur la création du filtre
Oui TabFiltres(j).Criteria1 est un objet, et plus précisément un Interior. J'ignore pourquoi c'est comme ça mais Il possède alors une propriété Color. Hélas elle n'est pas convenablement initialisée.
Oui si tu mets en commentaire l'instruction, y a plus de bug, mais y a plus de création de filtre non plus.
Si le filtre n'est pas un filtre couleur, cette instruction fonctionne parfaitement pour re-créer le filtre car Criteria1 est une variable de type non-objet.
Le problème est que pour le filtre couleur, Criteria1 est un objet (j'ai du modifier le stockage pour le prendre en compte avec un Set). En effet car c'est une fonction RGB() et hélas pas une valeur Long de couleur.
Et pour la recréation du filtre Criteria1:=<objet stocké> ça ne passe pas.
De plus je n'arrive pas à lister les propriétés de cet objet.
Sur Windows 7 j'avais un utilitaire pour le faire mais qui ne fonctionne pas sur Windows 10.
Ça se plante.
VB:
'Ajouter Outils / References / Typelib Information (VSTLBINF.DLL)
'si non trouvé -> http://www.telecharger-dll.fr/dll-vstlbinf.dll.html
Sub DumpProperties(ByVal Obj As Object)
Dim i As Long
Dim t As TLI.TLIApplication
Dim ti As TLI.TypeInfo
Dim mi As TLI.MemberInfo
Set t = New TLI.TLIApplication
Set ti = t.InterfaceInfoFromObject(Obj)
For Each mi In ti.Members
i = i + 1
ActiveCell.Offset(i, 0).Value = mi.Name
ActiveCell.Offset(i, 1).Value = mi.ReturnType
'MsgBox mi.Name
Next
End Sub
Ce que je voulais dire c'est que dans la procédure Sub StockerFiltresTableauStructuré(Tbl As ListObject)
VB:
'https://docs.microsoft.com/fr-fr/office/vba/api/excel.xlautofilteroperator
Select Case .Operator
Case 1, 2
TabFiltres(j).Criteria2 = .Criteria2
Case Else
'Pas de Criteria2
End Select
Il n'y a d'instruction pour le Case Else
Donc logiquement, il devrait pas y en avoir non plus dans la procédure
Sub DéstockerFiltresTableauStructuré(Tbl As ListObject)
non ?
Dans le Stocker on a:
TOUJOURS conservé Criteria1 & Operator
SEULEMENT pour l'Operator xlAnd, xlOr (1 et 2) conservé EN PLUS Critéria2
Donc dans le Déstocker on a:
SEULEMENT pour l'Operator xlAnd, xlOr (1 et 2) restauré Criteria1 & Operator & Criteria2
POUR TOUS les autres Operator (Case Else) restauré Criteria1 & Operator
Les cas de l'Operator xlFilterCellColor et xlFilterFontColor font partir du Else car ils n'ont pas de Criteria2.
Le problème c'est que ces Opertor impliquent un Criteria1 qui est un objet et pas une simple valeur.
Et c'est ça le problème car je ne sais pas affecter ces objets dans l'instruction .Range.AutoFilter Field:=j, Criteria1:=, alors que pour les simples valeurs, l'affectation dans Criteria1 passe sans problème.
En farfouillant, j'ai trouvé ceci.
Et dans les commentaires, je semble avoir compris que c'est mort pour la couleur.
NB: test OK sur ton fichier si on applique un filtre sur les valeurs.
Oui en effet les commentaires évoquent le problème, mais ils l'évoquent à la source:
VB:
Case Else ' These are not correctly restored; there's someting in Criteria1 but can't save it.
FilterCache(ii, 2) = .Operator
' FilterCache(ii, 1) = .Criteria1 ' <-- Generates an error
Pour éviter l'erreur à la source il suffit de capter .Criteria1 comme un objet qu'il est:
VB:
Case Else ' These are not correctly restored; there's someting in Criteria1 but can't save it.
FilterCache(ii, 2) = .Operator
Set FilterCache(ii, 1) = .Criteria1 ' <-- Generates no error at this stage
Le vrai problème est à la restauration du filtre où on essaie de faire:
VB:
Criteria1:= FilterCache(ii, 1)
Je trouve son code vraiment complexe à différencier à ce point les Operators.
Je n'ai pas testé tous les cas mais pour moi il n'y a que 2 situations à différencier:
1 - Criteria1 + Operator + Criteria2
2 - Criteria1 + Operator
Ceci dit ça n'a pas d'importance dans le problème considéré ici.
Certes, mais le Critéria1 n'est pas un Long dans ce cas, et c'est bien dommage.
Son TypeOf est Object qui je pense fait référence à la fonction et ses arguments et non à son résultat Long.
C'est un Interior en effet, je ne sais pas pourquoi, c'est vous qui l'y avez mis, non ?
Difficile à suivre votre code. Notez qu'il possède alors une propriété Color
Et encore une fois, je n'ai pas pu lister les propriétés de cet étrange objet car la fonction du post #4 qui fonctionnait sous W7 ne fonctionne plus sous W10.
Avec les propriétés de cet objet on pourrait peut-être s'en sortir et convertir la fonction RGB en nombre.
Dudu2
Moi, j'essaie juste d'aider
Personnellement pour sauvegarder/restaurer les filtres, j'utilises les Affichages personnalisés.
Manque de pot cela ne fonctionne pas avec les ListObjects
Pire, si il y a un seul ListObject dans un classeur, l'item Personnalisé est grisé sur le ruban.
Bref pour revenir à ta question, que ce soit avec ton code, ou avec celui que j'ai joint dans le message#7, apparemment les filtres sur Couleur ne peuvent pas être sauvegardés/restaurés.