IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Multi-sélection sur un filtre de Tableau Croisé Dynamique et lenteur d'exécution


Sujet :

Macros et VBA Excel

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 11
    Points : 9
    Points
    9
    Par défaut Multi-sélection sur un filtre de Tableau Croisé Dynamique et lenteur d'exécution
    Salut à tous,

    J'ai :
    - d'un côté un Tableau croisé dynamique classique, avec un champ "Item" positionné en filtre du rapport.
    - de l'autre une liste de quelques articles qui vont définir le critère du filtre "Item" de mon TCD

    Si je fais ça manuellement, je sélectionne mon filtre "Item", je coche "sélectionner plusieurs éléments", je sélectionne mes codes articles, puis je clique sur "Ok".
    A ce moment - et à ce moment uniquement-, le TCD est mis à jour en tenant compte de la multi-sélection.

    Bon, manuellement, donc, tout va bien

    Passons en vba...

    Depuis vba, je récupère mes articles à cocher depuis une listbox (permettant la sélection multiple), puis je boucle sur ma listbox, et j'affecte à PivotItems la valeur de True ou False, selon ce qui a été sélectionné dans la listbox.

    Bref ;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    ...
        'boucle sur la liste
        For iListIndex = 1 To oList.ListCount
     
            'si l'élement est sélectionné -> PivotItems à TRUE, sinon -> PivotItems à FALSE
           Worksheets("TCD Sheet").PivotTables("TCD1").PivotFields("Item").PivotItems(oList.List(iListIndex)).Visible = oList.Selected(iListIndex)
     
        Next iListIndex

    Jusque là tout va bien, ça fonctionne.
    Sauf que... sauf qu'à chaque passage de la boucle, il remet à jour le TCD (comme si, quand je l'ai fait manuellement, j'avais cliqué sur "Ok" à chaque fois que j'ai ajouté un article dans mon filtre).

    Et comme j'ai 230 articles dans ma Listbox, il rafraichit 230 fois mon TCD (qui pointe sur une plage de 300 000 lignes....), et du coup, ça serait comme qui dirait un chouïa un peu lent...

    Sans cirer les pompes, est-ce que l'un de vous aurait la géniale gentillesse et la magnanime intelligence de venir à mon secours ?

    Merci,
    Sylvain

  2. #2
    Membre actif
    Formateur en informatique
    Inscrit en
    Janvier 2011
    Messages
    134
    Détails du profil
    Informations professionnelles :
    Activité : Formateur en informatique

    Informations forums :
    Inscription : Janvier 2011
    Messages : 134
    Points : 205
    Points
    205
    Par défaut
    Bonjour,

    J'ai déjà été confronté à ce genre de pb que ce soit avec les segments ou les filtres.

    Concernant la boucle : faire attention à faire un premier passage pour mettre à true les PivotItems qui doivent l'être, puis un 2ieme pour mettre à false ceux qui doivent l'être, car autrement il y a un risque que tous passent à false ce qui est soit pas possible soit dans le cas des segments passe tous les items à True.

    Mais ça ne change rien au pb de lenteur ...

    J'avais opté pour une colonne supplémentaire dans la table source (Inclure) qui contient X ou rien, je mets un filtre sur cette colonne dans le TCD, et ma liste déroulante écrit les X qui vont bien dans la colonne Inclure ... dans ce cas un simple RefreshAll en VBA et le tableau est à jour ...

    Cordialement,
    Stéphane

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 11
    Points : 9
    Points
    9
    Par défaut
    Merci Stéphane,

    C'est une bonne idée, je vais essayer. J'ai juste peur que l'écriture des "X" sur mes 300 000 enregistrements soit long, mais ça sera toujours moins terrible qu'un recacul de TCD.

    Dommage qu'on ne dispose pas d'un truc similaire au filtre des onglets excel, du type
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    AutoFilter field:=1, Criteria1:=Array(Tablo)
    Je teste ça demain, je farfouille à droite à gauche, et je te tiens au courant.
    Merci encore,
    Sylvain

  4. #4
    Expert éminent sénior
    Homme Profil pro
    aucune
    Inscrit en
    Septembre 2011
    Messages
    8 203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Septembre 2011
    Messages : 8 203
    Points : 14 354
    Points
    14 354
    Par défaut
    Bonjour,

    Dommage qu'on ne dispose pas d'un truc similaire au filtre des onglets excel, du type
    AutoFilter field:=1, Criteria1:=Array(Tablo)
    Il y a bien "VisibleItemsList", mais c'est limité aux cubes OLAP. Sinon écris tes X dans une variable array et copie-la dans ta nouvelle colonne.
    Cordialement.

    Daniel

    La plus perdue de toutes les journées est celle où l'on n'a pas ri. Chamfort

  5. #5
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    si ça peut aidé!
    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
    Sub test()
    If FiltreTdc(ActiveSheet.PivotTables("Test"), "ChampTdcName", "Toto;Titi") = False Then MsgBox "Pas trouvé"
    End Sub
     
     
     Function FiltreTdc(tb, Champ As String, V As String) As Boolean
    On Error Resume Next
    Dim i As Integer
    Dim I2 As Long
    Dim trouve As Boolean
    Dim T
    T = Split(V & ";", ";")
    FiltreTdc = True
    tb.PivotFields(Champ).ClearAllFilters
    For i = 1 To tb.PivotFields(Champ).PivotItems.Count
        trouve = False
        For I2 = 0 To UBound(T)
        If Trim("" & tb.PivotFields(Champ).PivotItems(i).Name) = Trim("" & T(I2)) Then trouve = True
        Next
        If trouve = False Then tb.PivotFields(Champ).PivotItems(i).Visible = False
        If Err Then FiltreTdc = False
     
    Next
     On Error GoTo 0
    End Function

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2008
    Messages : 11
    Points : 9
    Points
    9
    Par défaut
    Salut à tous et un grand merci, j'ai trouvé grâce à vous un temps de réponse très acceptable pour un tcd de 300 000 lignes.

    En pompant sur Stéphane, voilà ce que j'ai fait :

    1- je charge la liste des articles à filtrer dans un scripting.dictionnary DicoArticleSelectionné
    2- En parallèle, depuis mon onglet source, je charge la colonne "Items" qui contient tout mes enregistrements Articles dans un tableau TabloItem
    3 - Je crée un TabloSelectItem, de même dimension que TabloItem
    4 - Je boucle sur TabloItem, et si DicoArticleSelectionné.Exists(TabloItem(i) Alors je mets un "X" dans TabloSelectItem(i)
    5 - J'écris TabloSelectItem dans une nouvelle colonne de mes données sources.
    6- Dans mon TCD, je n'ai plus qu'à mettre à jour mon filtre "Sélection Article" qui pointe sur cette nouvelle colonne en ne gardant que les "X"

    Bref :
    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
            For iItem_Loop = LBound(oItem) + 1 To UBound(oItem)
     
                If oDico_ArticleSélectionné.Exists(oItem(iItem_Loop, 1)) Then
                    oItemsSélectionné(iItem_Loop, 1) = "X"
                End If
     
            Next iItem_Loop
     
            ThisWorkbook.Worksheets(gcSheetTract).Range("Aticles_Sélectionnées_Col").Value = oItemsSélectionnées
     
            ' Mise à jour des TCD
            ThisWorkbook.Worksheets(gcSheetTCD).PivotTables(gcNameTCD_TRACT).PivotCache.Refresh
     
     
            '        ' Critère de sélection
     
            ThisWorkbook.Worksheets(gcSheetTCD).PivotTables(gcNameTCD_TRACT).PivotFields("Articles Sélectionnées").CurrentPage = "X"
    Merci à tous pour le coup de main et les idées

    Sylvain

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2010] Tableau croisé dynamique sur plage filtrée
    Par Mut dans le forum Excel
    Réponses: 3
    Dernier message: 21/01/2013, 15h55
  2. [XL-2007] Filtrer sur une date un tableau croisé dynamique
    Par formabox dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 06/07/2011, 07h08
  3. [AC-2007] décimales sur champ dans un tableau croisé dynamique
    Par GILLES_M dans le forum IHM
    Réponses: 2
    Dernier message: 31/10/2010, 17h35
  4. [XL-2007] Filtre sur graphe de tableau croisé dynamique
    Par kluh dans le forum Excel
    Réponses: 1
    Dernier message: 25/11/2009, 08h28
  5. [XL-2007] Filtre sur tableau croisé dynamique
    Par Flower123 dans le forum Excel
    Réponses: 2
    Dernier message: 18/06/2009, 16h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo