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 :

Synchroniser les filtres des tableaux croisés dynamiques du classeur


Sujet :

Macros et VBA Excel

  1. #1
    Nouveau Candidat au Club
    Inscrit en
    Février 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 7
    Points : 1
    Points
    1
    Par défaut Synchroniser les filtres des tableaux croisés dynamiques du classeur
    Bonjour,

    J'ai plusieurs tableaux croisés dynamiques basés sur les même données et qui présentent les mêmes champ de page, situés dans le même classeur.

    J'ai trouvé du code dans un livre: il marche mais présente plusieurs problèmes:

    1) il marche uniquement si on ne sélectionne qu'un seul élément dans le filtre du champ de page. Pour ce que j'ai à faire, il faudrait que je puisse sélectionner plusieurs éléments dans le filtre de champ.

    2) Dans le cas où on sélectionne l'élément "(Tous)" dans l'un des tableaux croisés dynamiques du classeur, la macro remplace l'un des éléments du champ de page des autres TCD par "(All)".

    J'ai essayé de rajouter une ligne avec une instruction du type pt.EnableMultiplePageItems = True mais cela ne marche pas...

    Le code suivant est dans un module:

    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
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     
    Option Explicit
    Sub SynchPivotTables(BasePivot As PivotTable)
     
        'Variable declaration
        Dim Pivot As PivotTable
        Dim Sheet As Worksheet
        Dim BasePage As PivotField
        Dim Page As PivotField
        Dim Itm As PivotItem
     
        'Synchronize the Pivot Tables in the Active Sheet
        'Set Sheet = ActiveSheet
        'or loop through all the Pivot Tables in the active workbook
        For Each Sheet In ActiveWorkbook.Worksheets
            'Loop through the Pivots in the worksheet
            For Each Pivot In Sheet.PivotTables
                'Try to synch if is not the base pivot table
                If Not Pivot Is BasePivot Then
                    'Loop through the page fields of the Base Pivot
                    For Each BasePage In BasePivot.PageFields
                        'Clear the old page value
                        Set Page = Nothing
                        'Check if its in the pages of the Pivot
                        'Continue if error occurs
                        On Error Resume Next
                        Set Page = Pivot.PageFields(BasePage.Name)
                        On Error GoTo 0
                        'Is it there?
                        If Not Page Is Nothing Then
                            'Try to assign the current page
                            On Error Resume Next
                            Page.CurrentPage.Caption = BasePage.CurrentPagepage.Caption
                            'Succeed?
                            If Page.CurrentPage <> BasePage.CurrentPage Then
                                'Try using the PivotItems collection
                                For Each Itm In Page.PivotItems
                                    If Itm.Caption = BasePage.CurrentPage Then
                                        Page.CurrentPage = Itm.Caption
                                    End If
                                Next Itm
                            End If
                        On Error GoTo 0
                        End If
                    Next BasePage
                End If
            Next Pivot
        Next Sheet
     
    End Sub
    Le code suivant est dans l'objet ThisWorkbook:

    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
     
    Option Explicit
    Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
    'This procedure goes in the ThisWorkbook module of the same workbook.
     
    If TypeName(Sh) = "Worksheet" Then
        On Error GoTo exiting:
        With Target.PivotTable
            Application.EnableEvents = False
            SynchPivotTables Target.PivotTable
            Application.EnableEvents = True
        End With
    End If
    exiting:
     
    End Sub

    Merci pour vos réponses.

  2. #2
    pgz
    pgz est déconnecté
    Expert éminent Avatar de pgz
    Homme Profil pro
    Développeur Office VBA
    Inscrit en
    Août 2005
    Messages
    3 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Office VBA
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2005
    Messages : 3 692
    Points : 6 591
    Points
    6 591
    Par défaut
    Bonjour.

    Je n'ai pas tout lu et je vais donc peut-être être inutile. Mais si le fond de ton pb est la multisélection d'un champ de page :
    • La méthode CurrentPage ne permet de choisir qu'un élément
    • Pour sélectionner plusieurs éléments, il faut utiliser la propriété .Visible des items du champ.
    Avec tous les problèmes classiques et surprenants quand on manipule la propriété Visible. Notamment tu as intérêt à paramétrer le champ sur "tri manuel".

    EN espérant que cela t'aide,

    PGZ
    pluritas non est ponenda sine necessitate - Le rasoir d'Okham
    Ne jamais attribuer à la malignité ce que la stupidité peut expliquer -Le rasoir d'Hanlon

  3. #3
    Nouveau Candidat au Club
    Inscrit en
    Février 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Salut cgm,

    J'ai tenté d'adapter mon code avec la méthode que tu proposes (.visible) mais je n'arrive pas à le faire fonctionner. Comme je ne connais pas trop cette méthode quelque chose m'échappe...

    Peux-tu regarder et me dire ce que j'ai de faux?
    Merci d'avance

    Code dans module standard:
    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
    38
    39
    40
    41
    42
    43
     
    Option Explicit
    Sub SynchPivotTables2(bpt As PivotTable)
     
    Dim ws As Worksheet
    Dim pt As PivotTable
    Dim bpf As PivotField
    Dim pf As PivotField
    Dim bpi As PivotItem
    Dim pi As PivotItem
     
    Application.EnableEvents = False
    Application.ScreenUpdating = False
     
    For Each ws In ThisWorkbook.Worksheets
        For Each pt In ws.PivotTables
           If Not pt Is bpt Then
                 For Each bpf In pt.PageFields
                    For Each pf In pt.PageFields
                        If pf Is bpf Then
                            For Each pi In pt.PageFields(pf.Name).PivotItems
                                pi.Visible = True
                            Next pi
                            For Each pi In pt.PageFields(pf.Name).PivotItems
                                For Each bpi In bpt.PageFields(bpf.Name).PivotItems
                                    If pi Is bpi Then
                                        If bpi.Visible = False Then
                                            pi.Visible = False
                                        End If
                                    End If
                                Next bpi
                            Next pi
                        End If
                    Next pf
                Next bpf
            End If
        Next pt
    Next ws
     
    Application.EnableEvents = True
    Application.ScreenUpdating = True
     
    End Sub
    Code dans module "thisworkbook":

    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
     
    Option Explicit
    Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
     
    If TypeName(Sh) = "Worksheet" Then
        On Error GoTo exiting:
        With Target.PivotTable
            Application.EnableEvents = False
            SynchPivotTables2 Target.PivotTable
            Application.EnableEvents = True
        End With
    End If
    exiting:
     
    End Sub

  4. #4
    pgz
    pgz est déconnecté
    Expert éminent Avatar de pgz
    Homme Profil pro
    Développeur Office VBA
    Inscrit en
    Août 2005
    Messages
    3 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Office VBA
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2005
    Messages : 3 692
    Points : 6 591
    Points
    6 591
    Par défaut
    Bonjour.

    En regardant rapidement, je ne comprends pas comment peut fonctionner la lignebpf est censé être un objet pagefield, mais instancié où et comment?
    Une fois que tu as une instance du pvt à modifier, soit tous tes pvt ont les mêmes champs de page et tu fait
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    set pf = pvt.pagefields("Nom")
    soit non, et tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    for each pf in pvt.pagefields
        if pf.name = "Nom" Then
            ...
        End if
    Next pf
    A mon avis.

    PGZ
    pluritas non est ponenda sine necessitate - Le rasoir d'Okham
    Ne jamais attribuer à la malignité ce que la stupidité peut expliquer -Le rasoir d'Hanlon

  5. #5
    Nouveau Candidat au Club
    Inscrit en
    Février 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Si je comprends bien, dans la solution que tu proposes il faut mentionner les noms des champs de page du TCD modifié (en toutes lettres).

    Or j'ai pas mal de champs de page et c'est pourquoi j'ai fait une boucle for each...then...next afin de décrire l'ensemble des champs de page du TCD qui est modifié par l'utilisateur.

    D'où la ligne:
    pour n'appliquer ce code qu'aux champs de page des TCD non modifiés qui sont identiques à ceux du TCD modifié.

    J'ai aussi essayé avec la propriété .name:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if bf.name=bpf.name then
    mais ça ne marche pas non plus.

    Je pense que j'ai effectivement mal écrit cette ligne. As-tu une idée pour corriger la syntaxe?

  6. #6
    pgz
    pgz est déconnecté
    Expert éminent Avatar de pgz
    Homme Profil pro
    Développeur Office VBA
    Inscrit en
    Août 2005
    Messages
    3 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Office VBA
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2005
    Messages : 3 692
    Points : 6 591
    Points
    6 591
    Par défaut
    Re,

    On va s'y prendre autrement. A quel endroit de ton code se fait l'instanciation de l'objet bpf? Je n'ai rien vu à ce sujet.
    J'imagine donc, mais peut-être à tort, que bpf est NOTHING (au sens VBA de cette constante).
    Tu peux vérifier en faisant Msgbox (ou debug.print) bpf is NOTHING; ou bpf.name



    PGZ
    pluritas non est ponenda sine necessitate - Le rasoir d'Okham
    Ne jamais attribuer à la malignité ce que la stupidité peut expliquer -Le rasoir d'Hanlon

  7. #7
    Nouveau Candidat au Club
    Inscrit en
    Février 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    J'ai fait tourner ce que tu m'as dit. Réponse=vrai.

    Je pensais pourtant que l'on n'avait pas besoin d'instancier une variable de procédure pour peu qu'on la déclare:

    Dim bpf As PivotField

    dans le code.

    Faut-il que je déclare aussi une autre variable PivotTable dont dépendrait bpf?

  8. #8
    pgz
    pgz est déconnecté
    Expert éminent Avatar de pgz
    Homme Profil pro
    Développeur Office VBA
    Inscrit en
    Août 2005
    Messages
    3 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Office VBA
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2005
    Messages : 3 692
    Points : 6 591
    Points
    6 591
    Par défaut
    Hello,

    Quand tu déclares une variable objet, tu crées un objet Nothing que tu peux instancier c'est-à-dire que cette variable objet peut ensuite représenter un objet après une instruction du style Dans ton cas quel est le contexte? Tu détectes une modification d'un TCD et sans savoir si c'est un champ de page qui a été modifié, tu veux mettre à jour ceux des autres TCD. Pourquoi pas, mais a minima, comme tu ne sais pas ce qui a été modifié, c'est bien tous les champs de page qui doivent alors être remis à jour.

    Question : tes TCD ont-ils tous les mêmes champs de page?

    PGZ
    pluritas non est ponenda sine necessitate - Le rasoir d'Okham
    Ne jamais attribuer à la malignité ce que la stupidité peut expliquer -Le rasoir d'Hanlon

  9. #9
    Nouveau Candidat au Club
    Inscrit en
    Février 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    salut,

    mes tcd ont tous des champs de page communs oui.

  10. #10
    pgz
    pgz est déconnecté
    Expert éminent Avatar de pgz
    Homme Profil pro
    Développeur Office VBA
    Inscrit en
    Août 2005
    Messages
    3 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Office VBA
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2005
    Messages : 3 692
    Points : 6 591
    Points
    6 591
    Par défaut
    Bonjour,

    Alors essaie de faire un code qui applique les suggestions que je t'ai faites, par exemple
    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
    Sub SynchPivotTables2(bpt As PivotTable)
     
    Dim ws As Worksheet
    Dim pt As PivotTable
    Dim bpf As PivotField
    Dim pf As PivotField
    Dim bpi As PivotItem
    Dim pi As PivotItem
    Dim lTri As Long
     
    Application.EnableEvents = False
    Application.ScreenUpdating = False
     
    For Each ws In ThisWorkbook.Worksheets
        For Each pt In ws.PivotTables
           If Not pt Is bpt Then
                 For Each bpf In pt.PageFields
                    Set pf = pt.PageFields(bpf.Name)
                    lTri = pf.AutoShowType
                    pf.AutoSort xlManual, pf.Name
                    For Each pi In pf.PivotItems
                        pi.Visible = bpf.PivotItems(pi.Name).Visible
                    Next pi
                    pf.AutoSort lTri, pf.Name
                Next bpf
            End If
        Next pt
    Next ws
     
     
    Application.EnableEvents = True
    Application.ScreenUpdating = True
     
    End Sub
    Et tu dis si ça plante.

    Cordialement,

    PGZ
    pluritas non est ponenda sine necessitate - Le rasoir d'Okham
    Ne jamais attribuer à la malignité ce que la stupidité peut expliquer -Le rasoir d'Hanlon

  11. #11
    Nouveau Candidat au Club
    Inscrit en
    Février 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Salut pgz,

    Non ça ne marche pas: aucune réaction du programme et pas de mise à jour des autres tcd avec les valeurs des champs de page du premier tcd...

    J'ai bien vérifié: ils ont exactement les mêmes champs de page. Par contre ils ont des champs de colonne différents:

    tcd1: chp de col= val1
    tcd2: chp de col= val1
    chp de col= val2

    Est-ce que ça peux avoir un impact sur l'éxécution de la macro?

    Cdlt

  12. #12
    pgz
    pgz est déconnecté
    Expert éminent Avatar de pgz
    Homme Profil pro
    Développeur Office VBA
    Inscrit en
    Août 2005
    Messages
    3 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Office VBA
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2005
    Messages : 3 692
    Points : 6 591
    Points
    6 591
    Par défaut
    Bonjour.

    Les champs de colonnes n'ont pas d'importance.
    Aucun effet? Es-tu sûr que la procédure soit exécutée?
    Si tu mets un point d'arrêt au début de la procédure, tu dois voir si tu y passes.
    Peux-tu montrer le code d'appel et la procédure tels qu'ils sont dans ton projet?

    PGZ
    pluritas non est ponenda sine necessitate - Le rasoir d'Okham
    Ne jamais attribuer à la malignité ce que la stupidité peut expliquer -Le rasoir d'Hanlon

  13. #13
    Nouveau Candidat au Club
    Inscrit en
    Février 2010
    Messages
    7
    Détails du profil
    Informations forums :
    Inscription : Février 2010
    Messages : 7
    Points : 1
    Points
    1
    Par défaut
    Salut pgz,

    Quand j'appelle la procédure SynchPivotTables2 depuis le module de l'une des feuilles de calcul (cad. sans programmer d'évènement qui déclenche l'éxécution du code), ça marche très bien. Merci!

    Seul problème restant: le déclenchement de la macro. J'ai essayé de triturer le code de déclenchement évènementiel mais je n'arrive à rien (le code ne se lance pas quand je change la sélection dans un champ de page quelconque).

    Voici le code de ma feuille:

    1)Dans le module ThisWorkbook:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Option Explicit
    Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
     
    If TypeName(Sh) = "Worksheet" Then
        On Error GoTo exiting:
        With Target.PivotTable
            SynchPivotTables2 Target.PivotTable
        End With
    End If
    exiting:
    End Sub
    2)Dans un module standard:
    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
    Option Explicit
    Sub SynchPivotTables2(bpt As PivotTable)
     
    Dim WS As Worksheet
    Dim pt As PivotTable
    Dim bpf As PivotField
    Dim pf As PivotField
    Dim pi As PivotItem
    Dim lTri As Long
     
    Application.EnableEvents = False
    Application.ScreenUpdating = False
     
    For Each WS In ThisWorkbook.Worksheets
        For Each pt In WS.PivotTables
            If Not pt Is bpt Then
                For Each bpf In bpt.PageFields
                    Set pf = pt.PageFields(bpf.Name)
                    lTri = pf.AutoShowType
                    pf.AutoSort xlManual, pf.Name
                        For Each pi In pf.PivotItems
                            pi.Visible = bpf.PivotItems(pi.Name).Visible
                        Next pi
                    pf.AutoSort lTri, pf.Name
                Next bpf
            End If
        Next pt
    Next WS
     
    Application.EnableEvents = True
    Application.ScreenUpdating = True
     
    End Sub
    Cdlt

    Bon: en fait je viens de fermer et de re-ouvrir la feuille et la procédure d'appel située dans le module ThisWorkbook marche....?

    J'ai du mal à comprndre pourquoi ça marche maintenant alors que je n'ai rien modifié par rapport à avant où ça ne marchait pas... Si tu peux éclairer ma lanterne?

    En tout cas un grand merci pour l'aide apportée sur la macro de synchronisation des TCD!!!

    Cdlt

  14. #14
    pgz
    pgz est déconnecté
    Expert éminent Avatar de pgz
    Homme Profil pro
    Développeur Office VBA
    Inscrit en
    Août 2005
    Messages
    3 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Office VBA
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2005
    Messages : 3 692
    Points : 6 591
    Points
    6 591
    Par défaut
    Bonjour.

    Peut-être à la suite d'un debug, l'exécuteur de code était-il arrêté. Dans ce cas à l'ouverture suivante, l'exécuteur marche à nouveau.

    Je trouve que tu n'as pas bien choisi l'évènement car celui-ci se produit à chaque changement, même s'il ne concerne pas les TCD.

    Il vaudrait mieux, à mon avis, utiliser PivotTableUpdate sur chaque feuille qui contient un TCD.

    Cordialement,

    PGZ
    pluritas non est ponenda sine necessitate - Le rasoir d'Okham
    Ne jamais attribuer à la malignité ce que la stupidité peut expliquer -Le rasoir d'Hanlon

Discussions similaires

  1. Réponses: 0
    Dernier message: 28/10/2013, 17h44
  2. [XL-2007] Changer en masse les critères des Tableaux croisés dynamiques
    Par anthooooony dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 11/10/2012, 18h43
  3. Réponses: 1
    Dernier message: 11/07/2011, 10h54
  4. [XL-2003] Instabilité des classeurs avec des Tableaux Croisés Dynamiques
    Par oohcalme dans le forum Macros et VBA Excel
    Réponses: 0
    Dernier message: 04/08/2009, 11h45
  5. Faire des tableaux croisés dynamique
    Par richard038 dans le forum Bases de données
    Réponses: 6
    Dernier message: 12/04/2006, 21h51

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