[RESOLU] Filtres automatiques sous VBA: ShowAllData et Sauvegarde des filtres actifs

Orodreth

XLDnaute Impliqué
Bonjour le forum,

Après une petite recherche, je suis tombé sur ce post-ci:
https://www.excel-downloads.com/threads/resolu-vba-filtres.203730/
qui répond parfaitement à ma problématique, à savoir, remettre les filtres automatiques sur "Tous" (ShowAllData).

Parfait. Mais histoire d'aller plus loin, et parce que j'anticipe un peu les remarques de mes users, je me demandais s'il était possible de sauvegarder les filtres actifs AVANT de les enlever, pour pouvoir les remettre par la suite.

Je m'explique:
Pour se simplifier la vie, mes utilisateurs filtrent le tableau via les filtres automatiques pour que ce même tableau soit plus lisible parce que réduit, ce que je comprends tout à fait.
Lors d'un ajout fait à l'aide de mon userform, les filtres actifs me posent un problème, donc je dois les enlever.
(Merci Dranreb pour le code:
Code:
Dim F As Worksheet
For Each F In Worksheets
   If F.FilterMode Then F.ShowAllData
   Next F
Une fois l'ajout terminé, je me dis que ça pourrait rendre service à mes utilisateurs si je pouvais, via VBA, remettre les filtres qu'ils avaient mis en place, et donc les sauvegarder au préalable.

Je joins un petit classeur d'exemple qui reprend les deux axes sous forme de boutons sur une feuille excel.

La feuille Data est le tableau à filtrer (planning)
La feuille Filtres contient les 3 entrées possibles sur lesquelles filtrer: Client, Série, et Engin.

Le bouton "- Filtres" enlève les filtres
Le bouton "+ Filtres" devrait les remettre, mais là, je coince.

Remarque: la feuille Filtres ne fait pas office de filtre en elle-même, elle sert juste à sauvegarder le critère de filtrage.

Merci d'avance à tout le monde,
Cordialement,
Orodreth
 

Pièces jointes

  • Manip_Filtres.xls
    39.5 KB · Affichages: 90
Dernière édition:

Staple1600

XLDnaute Barbatruc
Re : Filtres automatiques sous VBA: ShowAllData et Sauvegarde des filtres actifs

Bonjour à tous


Orodeth

As-tu pensé à utiliser la fonctionnalité: Affichages personnalisés ?
cf ci-dessous un exemple de code VBA
Sub Macro1()
ActiveWorkbook.CustomViews.Add ViewName:="TEST1", PrintSettings:=True, _
RowColSettings:=True
End Sub

Je l'utilise souvent (mais je suis l'unique utilisateur du fichier)
J'enregistre les résultats de mes différents filtres avec Affichages personnalisés puis par commodité d'usage
je personnalise le menu principal d'Excel en y ajoutant le menu: Affichages personnalisés
(en faisant Affichage/Barre d'outils/Personnaliser/Commandes/Affichage/Affichages personnalisés clic gauche et déplacement sur le menu principal d'Excel)

Que penses-tu de cette piste?
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Re : Filtres automatiques sous VBA: ShowAllData et Sauvegarde des filtres actifs

Bonjour.
Sinon ça peut s'écrire comme ça :
VB:
Option Explicit
Dim SvgFlt()

Public Sub EnleverFiltre()
Dim N As Long
With Feuil1.AutoFilter.Filters
   ReDim SvgFlt(1 To .Count, 1 To 3)
   For N = 1 To .Count
      With .Item(N)
         If .On Then SvgFlt(N, 1) = .Criteria1: If .Operator Then SvgFlt(N, 2) = .Operator: SvgFlt(N, 3) = .Criteria2
         End With
      Next N
   End With
If Feuil1.FilterMode Then Feuil1.ShowAllData
End Sub

Public Sub RemettreFiltre()
Dim N As Long
With Feuil1.AutoFilter.Range
   For N = 1 To UBound(SvgFlt, 1)
      If Not IsEmpty(SvgFlt(N, 1)) Then
         If SvgFlt(N, 2) Then
            .AutoFilter Field:=N, Criteria1:=SvgFlt(N, 1), Operator:=SvgFlt(N, 2), Criteria2:=SvgFlt(N, 3)
         Else
            .AutoFilter Field:=N, Criteria1:=SvgFlt(N, 1)
            End If
         End If
      Next N
   End With
End Sub
Remarque: je n'ai rien inventé: c'était presque tout écrit dans les exemples de l'aide !
 

Staple1600

XLDnaute Barbatruc
Re : Filtres automatiques sous VBA: ShowAllData et Sauvegarde des filtres actifs

Bonjour Dranreb


J'ai beau chercher dans l'aide VBA, je ne trouve pas d'exemple qui ressemble de loin ou de près au code VBA que tu proposes?
Tu as utilisé quels mots-clés pour ta recherche?
 

Dranreb

XLDnaute Barbatruc
Re : Filtres automatiques sous VBA: ShowAllData et Sauvegarde des filtres actifs

C'est vrai que ce n'est pas direct.
C'est l'aide sur AutoFiter en tant qu'objet.
Donc on peut y arriver à partir de AutoFilter, méthode en faisant la chasse à un bout d'explication comportant "…un objet AutoFilter" constituant un lien.
 

Orodreth

XLDnaute Impliqué
Re : Filtres automatiques sous VBA: ShowAllData et Sauvegarde des filtres actifs

Bonjour Dranreb, Staple1600, le forum,

Merci pour vos réponses.

J'ai fini par trouver une solution, un peu en dur dans le code, mais comme les colonnes à filtrer sont fixes (les autres étant des dates de planning, ça colle pas), ça passe.

Je reviens pour détailler mon code si ça intéresse quelqu'un:

Code:
Sub Filtres_SAVE_And_Redo
        Dim WS_Prog as Worksheet
        Set WS_Prog = Worksheets("Prog.")

        Dim lg_Row_Titre_Prog as Long
        lg_Row_Titre_Prog = 4

	With WS_Prog
        'Si la feuille Prog est en mode Filtre
        If .FilterMode Then
            Dim pcs_Filters As Integer
            
            With .AutoFilter.Filters
                'On boucle sur les critères de filtre des colonnes Client/Serie/Engin (2/3/4)
                For pcs_Filters = 2 To 4
                    'Si les filtres sur la colonne sont actifs
                    If .Item(pcs_Filters).On Then
                        Dim Fil As Filter
                        'On référence le filtre en lui-même
                        Set Fil = .Item(pcs_Filters)
                        
                        'On sauvegarde les valeurs
                        Select Case pcs_Filters
                            Case 2
                                str_Crit1_Act = Fil.Criteria1
                                
                                If Fil.Operator Then
                                    str_Crit2_Act = Fil.Criteria2
                                Else
                                    str_Crit2_Act = "Not Set"
                                End If
                                
                                i_Operator_Act = Fil.Operator
                                
                            Case 3
                                str_Crit1_Serie = Fil.Criteria1
                                
                                If Fil.Operator Then
                                    str_Crit2_Serie = Fil.Criteria2
                                Else
                                    str_Crit2_Serie = "Not Set"
                                End If
                                
                                i_Operator_Serie = Fil.Operator
                                
                            Case 4
                                str_Crit1_Engin = Fil.Criteria1
                                
                                If Fil.Operator Then
                                    str_Crit2_Engin = Fil.Criteria2
                                Else
                                    str_Crit2_Engin = "Not Set"
                                End If
                                
                                i_Operator_Engin = Fil.Operator
                        End Select
                    End If
                Next pcs_Filters
            End With
            
            'On vire les filtres pour afficher le tableau complet (nécessaire pour travailler avec VBA)
            .ShowAllData
        End If
    End With
	'...
	'...
	'On remet les filtres d'activité s'il y en a
    If str_Crit1_Act <> vbNullString Then
        If i_Operator_Act = 0 Then
            WS_Prog.Range("B" & CStr(lg_Row_Titre_Prog)).AutoFilter Field:=2, _
                                                             Criteria1:=str_Crit1_Act
        Else
            WS_Prog.Range("B" & CStr(lg_Row_Titre_Prog)).AutoFilter Field:=2, _
                                                             Criteria1:=str_Crit1_Act, _
                                                             Operator:=i_Operator_Act, _
                                                             Criteria2:=str_Crit2_Act

        End If
    End If
    
    'On remet les filtres de série s'il y en a
    If str_Crit1_Serie <> vbNullString Then
        If i_Operator_Serie = 0 Then
            WS_Prog.Range("C" & CStr(lg_Row_Titre_Prog)).AutoFilter Field:=3, _
                                                             Criteria1:=str_Crit1_Serie
        Else
            WS_Prog.Range("C" & CStr(lg_Row_Titre_Prog)).AutoFilter Field:=3, _
                                                             Criteria1:=str_Crit1_Serie, _
                                                             Operator:=i_Operator_Serie, _
                                                             Criteria2:=str_Crit2_Serie

        End If
    End If
    
    'On remet les filtres d'engin s'il y en a
    If str_Crit1_Engin <> vbNullString Then
        If i_Operator_Engin = 0 Then
            WS_Prog.Range("D" & CStr(lg_Row_Titre_Prog)).AutoFilter Field:=4, _
                                                             Criteria1:=str_Crit1_Engin
        Else
            WS_Prog.Range("D" & CStr(lg_Row_Titre_Prog)).AutoFilter Field:=4, _
                                                             Criteria1:=str_Crit1_Engin, _
                                                             Operator:=i_Operator_Engin, _
                                                             Criteria2:=str_Crit2_Engin

        End If
    End If
End Sub

Quand on a pigé que l'indice du filtre équivaut à l'indice de la colonne, ça devient beaucoup plus clair, mais il m'a fallu un moment.

A noter, toujours si quelqu'un se pose la question:
On ne peut pas tester l'existence d'un critère secondaire de filtre directement, il faut commencer par tester l'Operator.
Si ce dernier est différent de 0 (ni Ou, ni Et en fait, c'est ce qui permet de savoir qu'il n'y a pas de critère 2, à ce que j'ai compris en débogage).

Encore merci à vous pour vos réponses.
Cordialement,
Orodreth
 

Discussions similaires

Réponses
3
Affichages
579

Statistiques des forums

Discussions
312 215
Messages
2 086 322
Membres
103 178
dernier inscrit
BERSEB50