Détection filtre

Résolu
Shadorb Messages postés 60 Statut Membre -  
Shadorb Messages postés 60 Statut Membre -
Bonjour,



Je voulais savoir s'il était possible de détecter peut être l'index du filtre actif ? Afin de faire un code qui dépendrait du filtre actif.

Merci bien.

3 réponses

  1. ThauTheme Messages postés 1564 Statut Membre 160
     
    Bonjour Shadorb, bonjour le forum,

    Le code ci-dessous renvoie le premier filtre actif. Si il n'y en a qu'un, il devrait convenir, sinon il faudra adapter...

    Public Sub Macro1()
    Dim O As Worksheet 'déclare la variable O (Onglet)
    Dim I As Byte 'déclare la variable I (Incrément)
    Dim CF As Integer 'déclare la variable CF (Colonne Filtrée)
    
    Set O = Sheets("Feuil1") 'définit l'onglet O (à adapter à ton cas)
    If O.FilterMode Then 'condition : si l'onglet O est filtré
        For I = 1 To O.AutoFilter.Filters.Count 'boucles sur toutes les colonnes
            If O.AutoFilter.Filters.Item(I).On Then CF = I: Exit For 'si la colonne est filtrée, définie la variable CF, sort de la procédure
        Next I 'prochaine colonne de la boucle
    End If 'fin de la condition
    MsgBox CF 'message affichant CF
    End Sub

    1
    1. Shadorb Messages postés 60 Statut Membre
       
      Si j'ai bien compris ça renvoi le numéro de la colonne ou le filtre est actif.

      Ca me fait avancer, mais ce n'est pas entièrement ma question, comment savoir quelle index est sélectionner dans ce dit filtre ? Si je trie selon chauffage comment détecter que c'est bien chauffage et non sanitaire qui est sélectionné dans le filtre ?

      EDIT: Après discussion avec les intéressées il a été convié que seul un filtre à la fois sera actif.
      0
  2. ThauTheme Messages postés 1564 Statut Membre 160
     
    Re,

    C'est pile la réponse à ta question !... Ça renvoie l'index du filtre et non pas la valeur de la cellule... Il me semble que c'est cela que tu avais demandé, non ?

    Il suffit d'adapter le message, Si ton tableau commence en A1 :

    MsgBox Cells(1, CF).Value

    où 1 correspond au numéro de la ligne.
    0
    1. Shadorb Messages postés 60 Statut Membre
       
      Dans ce cas je comprend pas alors.
      Comment ça peut me sortir 3 là ?
      http://hpics.li/92baa3c

      Jpense qu'on parle pas de la même chose :)
      0
    2. ThauTheme Messages postés 1564 Statut Membre 160
       
      Quand tu crèves un pneu ? Tu amènes une photo à ton garagiste pour réparer ?...
      0
      1. Shadorb Messages postés 60 Statut Membre > ThauTheme Messages postés 1564 Statut Membre
         
        C'est marrant j'y est pas déjà eu droit à celle là ?

        Je peux pas filer l'excel sinon ça serait déjà fait et on en parlerai plus.
        0
    3. ThauTheme Messages postés 1564 Statut Membre 160
       
      Alors bon courage !...
      0
  3. Utilisateur anonyme
     
    Bonsoir Shadorb,

    Comme tu n'as pas indiqué le nom de ta feuille, je vais supposer que
    c'est Feuil1.

    Dans ton message #2, tu as écrit : « Si je trie selon chauffage comment
    détecter que c'est bien chauffage et non sanitaire qui est sélectionné
    dans le filtre ? ».

    Donc en regardant ensuite ta copie d'écran, je vois que ça concerne la
    colonne n° 2 du tableau, donc le 2ème filtre (il y en a 1 par colonne).

    MsgBox Worksheets("Feuil1").AutoFilter.Filters(2).Criteria1

    Si tu as filtré cette colonne avec le critère « CHAUFFAGE »,
    la ligne ci-dessus devrait t'afficher "=CHAUFFAGE" ;

    À toi d'enlever le 1er caractère si tu veux tester uniquement
    "CHAUFFAGE", mais rien ne t'empêche de laisser tel que et
    tester "=CHAUFFAGE".

    Attention : je pense que tu dois aussi ajouter du code pour
    détecter si le filtre automatique est actif, et seulement si
    c'est le cas, « interroger » quel est le critère.

    Mais pour ça, je te laisse faire !

    Avertis-moi si tu as réussi, puis mets le sujet en « Résolu ».
    Sinon, tu peux me demander des infos complémentaires.

    Cordialement.  😊
     
    0
    1. Shadorb Messages postés 60 Statut Membre
       
      Merci c'est exactement ce que je cherche. Cependant quelque petites question: comment tester le critère sélectionné ? Je veux dire j'ai CHAUFFAGE, SANITAIRE, et ELEC, comment tester les autres ? Ça marche super bien pour chauffage mais seulement lui.

      Autre chose, peut-on détecter Evènement "filtre modifié" ? De façon à pouvoir gérer le code lorsque l'utilisateur trie directement. (Pour l'instant j'ai un bouton).

      Enfin lorsque l'on filtre suivant un critère, il faut que je trouve la dernière ligne remplit. Afin de créer en dessous de celle-ci une ligne total. Le problème c'est que les lignes ont l'air juste masquer et ils me compte toutes les autres en ignorant le filtre. (Je sais pas si c'est bien expliquer)

      j'utilise ça :
      LastLineFeuil1 =Worksheets(1).Range("C"&Rows.Count).End(xlUp).Row


      Merci.
      0
    2. Utilisateur anonyme > Shadorb Messages postés 60 Statut Membre
       
      1) Tu as écris : « Ça marche super bien pour chauffage mais seulement lui. » ;
      si ça retourne bien Criteria1 "=CHAUFFAGE", il n'y a pas de raison pour que
      ça ne retourne pas "=SANITAIRE" ou "=ELECTRICITÉ".

      Mais peut-être ta 1ère question n'était pas pour la même colonne, mais pour
      les autres ? Dans ce cas, il suffit de mettre le bon n° de filtre, c'est-à-dire
      le n° de la colonne correspondante. Donc :

      a) Pour la colonne 1 "Adhérent", c'est le filtre 1
      b) Pour la colonne 2 "Activité", c'est le filtre 2
      c) Pour la colonne 3 "Fournisseur", c'est le filtre 3
      d) Pour la colonne 4 "Prix de vente", c'est le filtre 4
      e) Pour la colonne 5 "Prix de revient", c'est le filtre 5

      Donc il te suffit de mettre le bon n° n pour :
      Worksheets("Feuil1").AutoFilter.Filters(n).Criteria1

      Mais laisse Criteria1 ! Criteria2 est pour un test qui comprend 2 valeurs.

      Exemple : est supérieur ou égal à 20 Et est inférieur ou égal à 100.
      Dans ce cas, Criteria1 : ">=20" et Criteria2 : "<=100".

      -------------------------------------------------------

      2) Regarde cette ligne de code :

      MsgBox Worksheets("Feuil1").AutoFilter.Filters(n).On
      n est le n° de colonne du tableau = n° du filtre
      On est celui de On / Off : actif ou non

      S'il n'y a pas de critère de filtre pour la colonne en question,
      ça retourne FAUX ; dans le cas contraire, ça retourne VRAI,
      et seulement à ce moment-là, interroge les critères de filtre.

      Pour ce que tu demandes, je crois bien qu'il n'y a pas d'autre moyen
      que de comparer, pour chaque filtre, les valeurs « avant » et « après »
      d'abord de On, puis éventuellement de Criteria1 et Criteria2.

      Car si On était avant FAUX puis est devenu après VRAI (ou inversement),
      ça suffit pour déterminer que le filtre de la colonne en question a été
      modifié : inutile alors de tester Criteria1 (et encore moins Criteria2).

      Je veux dire par là qu'il faudra tester Criteria2 seulement si, pour avant
      et après : On = VRAI et Criteria1 est le même.

      Et il faut voir aussi .Operator : 1 pour Et ; 2 pour Ou

      -------------------------------------------------------

      3) Quand on utilise un filtre automatique, heureusement que les lignes qui
      ne correspondent pas au(x) critère(s) sont seulement masquées et pas
      supprimées ! C'est tout à fait normal, et c'est ce qui permet aussi de :

      a) Changer de critère, et voir de nouveau les lignes auparavant masquées
      qui correspondent au(x) nouveau(x) critère(s).

      b) Désactiver le filtre automatique, et voir de nouveau toutes les lignes
      du tableau.

      Mais si ta ligne de code :

      LastLineFeuil1 =Worksheets(1).Range("C"&Rows.Count).End(xlUp).Row

      ne te renvoie pas le n° de la dernière ligne, la seule explication que
      je vois est que tu as une ou plusieurs autre(s) donnée(s) sous ton
      tableau, et donc le .End(xlUp).Row bute dessus, avant de pouvoir
      « rencontrer » la dernière ligne de ton tableau située plus haut.

      À te lire.  😊
       
      0
    3. Shadorb Messages postés 60 Statut Membre > Utilisateur anonyme
       
      Merci beaucoup ça me fait bien avancer.
      Du coup pour compter les lignes non masqués j'ai fais ceci :
      LastLineFeuil1 = Worksheets(1).Range("D" & Rows.Count).End(xlUp).Row
      For l = 4 To LastLineFeuil1
      If Not Rows(l).Hidden Then R = R + 1
      Next l

      Probablement pas la meilleurs solution mais ça fais ce qu'on lui demande.

      Ensuite j'ai un problème assez hasardeux :
      If (Worksheets(1).AutoFilter.Filters(4).On = True) Then
      MsgBox Worksheets(1).AutoFilter.Filters(4).Criteria1
      MsgBox (R)
      Else
      MsgBox ("Filtre fournisseur non utilisé")
      End If


      J'ai juste décaler la colonne de test mais j'ai une erreur qui arrive parfois, je n'arrive pas à identifier la source. Erreur '91' Variable objet ou variable de bloc non définie.

      Si je comprend ce qu'il veut dire ne devrait-il pas rentrer dans le else de ma boucle ?
      Ensuite je n'est pas bien compris comment tester le changement de filtre.
      Je stock dans un string la valeur du filtre actuel et ensuite je compare celui-ci avec le prochain ?

      L'utilisateur devra forcément utiliser un bouton pour lancer le test non ?

      A plus.
      0
    4. Utilisateur anonyme > Shadorb Messages postés 60 Statut Membre
       
      Bonjour Shadorb,

      1) Pour compter les lignes non masquées, essaye plutôt ceci :

      LastLineFeuil1 = Worksheets(1).Range("D" & Rows.Count).End(xlUp).Row
      R = WorksheetFunction.Subtotal(103, Range("D4:D" & LastLineFeuil1))
      

      - plus besoin de boucle For l.. Next l (L minuscule, pas i majuscule)
      - plus besoin de test If Not Rows(l).Hidden Then R = R + 1

      Mais attention à toujours laisser 103 : c'est le code de NBVAL
      pour que la fonction Subtotal retourne le nombre de valeurs
      de la plage indiquée, tout en ignorant les lignes masquées.

      ---------------------------------------------------------

      J'ai mis la même ligne de départ que toi : 4 ; en supposant que ta ligne
      d'en-têtes est en ligne 3, et que la 1ère ligne de donnée est la 4, juste
      en dessous.

      J'ai aussi gardé ta même colonne D, mais tu peux en choisir une autre
      si tu préfères. De toute façon le résultat sera identique, puisque pour
      toutes les colonnes de ton tableau, les lignes masquées sont bien sûr
      les mêmes.

      ---------------------------------------------------------

      Pour plus de renseignements sur la fonction utilisée, tape dans une cellule vierge
      de ta feuille Excel : =sous.total( ; clique sur fx qui est devant la barre de formule,
      et regarde l'aide en ligne. N'oublie pas le point ( . ) entre « sous » et « total » !

      =================================

      2) Dans ton Else, il y a : "Filtre fournisseur non utilisé", ce qui indique donc que
      tu testes le filtre de la colonne « Fournisseur ». Or sur la copie d'écran de ton
      tableau initial, c'est la colonne n° 3 ; donc ton filtre est le n° 3, pas le 4 !

      À moins, bien sûr, que tu aies ajouté une autre colonne avant, mais je ne crois
      pas ; mais si tu as changé la structure de ton tableau, envoies-moi une autre
      copie d'écran (avec les numéros de lignes et lettres de colonnes) !

      ---------------------------------------------------------

      Tu as mis des parenthèses inutiles, ce qui me donne à penser que tu as déjà
      programmé en Turbo-Pascal auparavant, non ?  😉

      Le test « = True » est inutile aussi ; les 2 MsgBox successifs peuvent être réunis
      en un seul (avantage : 1 seule box au lieu de 2) ; et en « factorisant » le filtre 3,
      cela donne :

      With Worksheets(1).AutoFilter.Filters(3)
        If .On Then
          MsgBox .Criteria1 & vbLf & R
        Else
          MsgBox "Filtre fournisseur non utilisé"
        End If
      End With
      

      D'autre part, remarque bien que tes 2 lignes précédentes pour calculer R
      sont utiles seulement si on affiche ce R ; donc comme c'est utile pour
      la 1ère partie du If seulement, et pas pour le Else, on déplace les
      2 lignes en question dans le If, avant utilisation du R :

      With Worksheets(1).AutoFilter.Filters(3)
        If .On Then
          LastLineFeuil1 = Worksheets(1).Range("D" & Rows.Count).End(xlUp).Row
          R = WorksheetFunction.Subtotal(103, Range("D4:D" & LastLineFeuil1))
          MsgBox "Critère : " & .Criteria1 & vbLf & "Nombre de lignes : " & R
        Else
          MsgBox "Filtre fournisseur non utilisé"
        End If
      End With
      

      ---------------------------------------------------------
      Attention !

      Ne déplace pas ta 1ère ligne si la suite de ton code doit utiliser LastLineFeuil1 ;
      ne déplace pas ta 2ème ligne si la suite de ton code doit utiliser R.
      ---------------------------------------------------------

      Tu remarqueras aussi que j'ai ajouté un petit texte devant l'affichage du critère
      et devant R ; si tu aimes moins, mets un autre texte, ou enlève « "..." & ».

      =================================

      3) L'erreur 91 ne concerne pas le fait de rentrer dans le Else ou non ; si c'est
      « Variable objet non définie », ça signifie que VBA ne trouve pas un objet
      dont dépend quelque chose (expression, méthode, propriété ou autre) ;
      si c'est « Variable de bloc non définie », le bloc n'est pas forcément un bloc
      If .. Then .. Else, ça peut être aussi un bloc With .. End ou autre...

      Je ne pense donc pas que ton erreur 91 était due à ton erreur de n° de filtre,
      mais regarde déjà si elle se reproduit alors que tu as mis le filtre n° 3 (avec
      mon code ci-dessus). Car si ça s'est arrangé, inutile de voir plus loin !

      Par contre, si ça se reproduit, il faudrait que tu me montres la partie de code
      où ça se produit, et aussi, dis-moi sur quelle ligne ça s'arrête et met du jaune
      quand tu cliques sur le bouton débogage.

      =================================

      4) Le fait de mettre en place un bouton pour que l'utilisateur lance lui-même
      la macro qui teste s'il y a eu ou non un changement de filtre dépend de ce
      que tu veux faire ; et dans quel but voudrais-tu que l'utilisateur sache que
      le filtre a été modifié ?

      Ce n'est donc pas obligé que ce soit l'utilisateur qui lance lui-même ce test :
      si tu en as vraiment besoin, tu peux le faire automatiquement via VBA,
      sans aucune intervention de l'utilisateur ; et en sachant à quel moment
      tu veux que ça fasse ce test : par exemple, seulement en lançant la macro
      correspondante, ou selon un événement du genre « sur activation de
      la feuille Worksheets(1) » ou autre...

      =================================

      Ce présent message est déjà super long, aussi, pour la façon de tester
      le changement de filtre on verra ça une autre fois, quand tu auras réglé
      tous les problèmes ci-dessus.

      Cordialement.  😊
       
      0
    5. Shadorb Messages postés 60 Statut Membre > Utilisateur anonyme
       
      Quand t'explique tu le fais pas à moitié, c'est cool !

      En effet le tableau à légèrement changé, et avec le filtre ci-dessous activé ça plante.
      http://hpics.li/59c9dff

      Comme je sais pas mettre en jaune sur le site jte remet une image de débogage.
      http://hpics.li/dbc6d44

      Franchement je comprends pas cette erreur. J'ai bien activer le filtre numéro 4. je dois pas comprendre quelque chose avec le fonctionnement des filtres.
      0