XL 2013 TCD : comment intervenir sur un filtre en champ Page ?

Sebast

XLDnaute Impliqué
Bonjour à toutes et à tous,


je cherche en VBA comment sélectionner un filtre UNIQUEMENT quand il est en champ page, c'est à dire en haut à gauche dans un TCD et non par exemple en ligne dans le TCD


Quand je prends l'enregistreur de macro, je vois que le champ page s'appelle DataLabelRange mais je n'arrive pas à l'insérer dans ma macro …


Pour faire simple, avec l'exemple trivial en pièce jointe, mon code fonctionne pour le TCD1 car le champ Pays est bien en Page mais ça plante quand je veux interdire la sélection (pf.EnableItemSelection = False) et bien sûr je ne veux pas bloquer la possibilité de sélectionner les items du champ "Produits"



D'avance, merci pour vos lumières


Sub FixerPaysEtGelerSelection()

Dim sh As Long

Dim pt As PivotTable

Dim pf As PivotField


For sh = 1 To Sheets.Count

Sheets(sh).Activate

If ActiveSheet.PivotTables.Count > 0 Then

Set pt = ActiveSheet.PivotTables(1)



' Etape 1 : on fixe le filtre en champ Page avec Pays = "Italie" (ça marche !)

With ActiveSheet

.PivotTables("Tableau croisé dynamique1").PivotFields("Pays").ClearAllFilters

.PivotTables("Tableau croisé dynamique1").PivotFields("Pays").CurrentPage = "Italie"

End With


' Etape 2 : on gèle la possibilité de sélectionner autre chose dans le champ Page (ne marche pas !)

Set pf = ActiveSheet.PivotTables("PivotTable1").PivotFields("Pays")

For Each pf In pt.DataLabelRange

pf.EnableItemSelection = False

Next

End If

Next sh


End Sub
 

Pièces jointes

  • Geler_champ_page.xlsm
    25.9 KB · Affichages: 34

chris

XLDnaute Barbatruc
Bonjour

Si j'ai bien compris
Code:
Private Sub Worksheet_PivotTableUpdate(ByVal Target As PivotTable)
    Application.EnableEvents = False
    With PivotTables("Tableau croisé dynamique1")
        If .PivotFields("Pays").CurrentPage <> "Italie" Then Application.Undo
    End With
    Application.EnableEvents = True
End Sub
à placer dans le code de la feuille contenant le TCD.

Ton code semble faire référence à toutes les feuilles : pour que cela fonctionne il faudrait soit raisonner sur l'index du TCD plutôt que son nom soit tous les nommer à l'identique (pas trop conseillé) ou avec un nom structuré. Il faudra alors adpter le code et le placer dans le module du classeur
 
Dernière édition:

Sebast

XLDnaute Impliqué
Chris,

merci de t’être penché sur ma question.

En fait, je ne me suis probablement pas exprimé clairement

Dans le fichier joint, il n’y a qu’un seul TCD mais potentiellement, des dizaines, d’où le besoin de tous les parcourir et donc le For sh = 1 To Sheets.Count

De plus, je ne cherche pas à l’avoir en événement mais à déclencher la macro à la demande, d’où mon besoin d’une sub() et pas d’une Private sub()


Mais le plus important pour moi :


  1. Je veux neutraliser la sélection du champ « pays » UNIQUEMENT si Pays est en PAGE (c’est-à-dire en haut à gauche)
Dans le nouveau fichier joint, dans TCD2 ou TCD3, le filtre « Pays » n’est pas en champ PAGE donc je ne veux pas intervenir dans ces deux cas.


Ce qui m’étonne, c’est que l’enregistreur de macros me dit que le champ PAGE s’appelle datalabelRange mais bizarrement, ça plante quand je mets en œuvre ce terme !



En résumé :


Dans TCD1 : « Pays » est en Page donc j’applique pf.EnableItemSelection = False


Dans TCD2 : « Pays » n’est pas en Page donc je ne verrouille pas (idem TCD3)



Encore merci pour ton aide
 

Pièces jointes

  • Geler_champ_page_2eme_mouture.xlsm
    33.7 KB · Affichages: 38

chris

XLDnaute Barbatruc
RE

Code:
Sub FixerPaysEtGelerSelection()
Dim Sh As Long
Dim pt As PivotTable
Dim pf As PivotField

For Sh = 1 To Sheets.Count
    Sheets(Sh).Activate
    If ActiveSheet.PivotTables.Count > 0 Then
        Set pt = ActiveSheet.PivotTables(1)
       
        With pt
            On Error GoTo fin
            If Not Intersect(.PivotFields("Pays").DataRange, .PageRange) Is Nothing Then
                .PivotFields("Pays").EnableItemSelection = False
                .PivotFields("Pays").ClearAllFilters
                .PivotFields("Pays").CurrentPage = "Italie"
            End If
        End With
    End If
fin:
Next Sh

End Sub

devrait aller
 

Sebast

XLDnaute Impliqué
Bonsoir (bonne nuit ?),

merci pour ton code, on s'approche !
ça marche nickel mais j'avais oublié de prendre en compte le fait que parmi les multiples feuilles contenant des tcd, il pouvait y en avoir certains pour lesquels il n'y a pas de champ Page, et du coup ça plante.

Autant j'ai su comment contrôler si on a affaire à un TCD (If ActiveSheet.PivotTables.Count > 0 Then ...), autant je ne sais pas comment contrôler si on a un champ page dans le TCD.
Est-ce possible ?

merci d'avance
 

chris

XLDnaute Barbatruc
Bonjour

C'est pour cela qu'il y a la ligne "On error" : s'il n'y a pas de champ page le test renvoie une erreur et donc on sort du traitement de ce TCD grâce au goto puisque de toute façon le TCD n'est pas concerné.

L'as tu bien mise dans ton code ainsi que l'étiquette associée ?

On peut tester plus proprement ainsi
Code:
Sub FixerPaysEtGelerSelection()
Dim Sh As Long
Dim pt As PivotTable
Dim pf As PivotField

For Sh = 1 To Sheets.Count
    Sheets(Sh).Activate
    If ActiveSheet.PivotTables.Count > 0 Then
        Set pt = ActiveSheet.PivotTables(1)
       
        With pt
            If pt.TableRange2.Cells.Count > pt.TableRange1.Cells.Count Then
                If Not Intersect(.PivotFields("Pays").DataRange, .PageRange) Is Nothing Then
                .PivotFields("Pays").EnableItemSelection = False
                .PivotFields("Pays").ClearAllFilters
                .PivotFields("Pays").CurrentPage = "Italie"
                End If
            End If
        End With
    End If
Next Sh

End Sub

Reste le cas où tu aurais un TCD sans champ pays mais avec un autre champ page : si c'est la cas il faut une boucle testant l’existence de Pays dans les champs de page
 

Sebast

XLDnaute Impliqué
Bonjour Chris,


Merci pour ton aide précieuse


J’avais bien vu l’embranchement en cas d’erreur mais ça plantait quand même.


Effectivement, le cas de feuilles avec TCD présentant un champ Page mais pas l’item Pays existe bel et bien et du coup, ça plante.


Du coup, j’ai placé un On error resume next que je réinitialise en début de boucle (voir code)

Ca me paraît plus simple que de tester l’existence de Pays dans le champ Page

Je sais que on error resume next n’est pas toujours optimal mais dans le cas présent, ça fait le job et je ne vois pas ce que je louperais en le mettant en œuvre.


Qu’en penses-tu ?


PS : avec la nouvelle interface, je ne retrouve plus comment mettre le code sous forme de code ...


Sub FixerPaysEtGelerSelectionRetouché()

Dim Sh As Long

Dim pt As PivotTable

Dim pf As PivotField


For Sh = 1 To Sheets.Count

On Error GoTo 0 ' ici on remet tout à zéro

Sheets(Sh).Activate

If ActiveSheet.PivotTables.Count > 0 Then

Set pt = ActiveSheet.PivotTables(1)



With pt

If pt.TableRange2.Cells.Count > pt.TableRange1.Cells.Count Then

On Error Resume Next ' ici en cas de problème

If Not Intersect(.PivotFields("Pays").DataRange, .PageRange) Is Nothing Then

.PivotFields("Pays").EnableItemSelection = False

.PivotFields("Pays").ClearAllFilters

.PivotFields("Pays").CurrentPage = "Italie"

End If

End If

End With

End If

Next Sh


End Sub






Encore merci
 

chris

XLDnaute Barbatruc
Re

Non resume next n'est pas bon car on continu à traiter un champ pays peu-être inexistant ou qui n'est pas un champ page...

Je vérifies le nom des champs pages. Il y en a rarement beaucoup donc c'est très rapide comme test.
J'ai aussi enlevé l'activate qui ne sert à rien
Code:
Sub FixerPaysEtGelerSelection()
Dim Sh As Long
Dim pt As PivotTable
Dim pf As PivotField

For Sh = 1 To Sheets.Count
    If Sheets(Sh).PivotTables.Count > 0 Then
        Set pt = Sheets(Sh).PivotTables(1)
    
        With pt
            If pt.TableRange2.Cells.Count > pt.TableRange1.Cells.Count Then
                For Each pf In .PageFields
                    If pf.Name = "Pays" Then
                        pf.EnableItemSelection = False
                        pf.ClearAllFilters
                        pf.CurrentPage = "Italie"
                        Exit For
                    End If
                Next pf
            End If
        End With
    End If
Next Sh

End Sub

Pour mettre en code utiliser ici le bouton qui précède l’icône disquette et choisir code.
 

Sebast

XLDnaute Impliqué
Re,

un grand merci, cette fois ça fonctionne parfaitement et ton code est très clair et lisible.
Effectivement, le activate peut avantageusement être remplacé par ta solution
Quand on a le bon code sous les yeux, ça tombe sous le sens !

Encore merci pour ton aide et tes conseils
 

Discussions similaires