I have an identical situation to what Mr. Jerry Sullivan has solved in this previous thread: pivot table question (and in turn, this: Pivot Table- "Master" Report Filter).
I have a button that initiates the vba to sync all slicers and their respective pivot tables located in a "filtered tables" tab, with a master pivot table that has slicers located on a dashboard.
This is working as designed, but the process is too slow for it's intended use.
Is there any way to only sync the slicers or slicer items that actually have been changed to speed it up?
Or any other ideas on how to speed the code up?
Here is what is implemented (with four pivot tables in "Filtered Tables"):
Dashboard:
Module:
I have a button that initiates the vba to sync all slicers and their respective pivot tables located in a "filtered tables" tab, with a master pivot table that has slicers located on a dashboard.
This is working as designed, but the process is too slow for it's intended use.
Is there any way to only sync the slicers or slicer items that actually have been changed to speed it up?
Or any other ideas on how to speed the code up?
Here is what is implemented (with four pivot tables in "Filtered Tables"):
Dashboard:
Code:
Sub UpdateButton_Click()
Dim sMaster As String, sField As String
Dim CurrentSlicer As Slicer
sMaster = "MasterTable"
With Worksheets("Filtered Tables")
On Error GoTo CleanUp
Application.EnableEvents = False
' sFields are current slicers connected to the "master filter" pivot table (on the Dashboard tab right now)
' that the slicers on Filtered Tables tab (and corresponding pivot tables) are being synced with.
sField = "Slicer1"
Call Synch_All_PT_Filters_BasedOn( _
PT:=.PivotTables(sMaster), sField:=sField)
sField = "Slicer2"
Call Synch_All_PT_Filters_BasedOn( _
PT:=.PivotTables(sMaster), sField:=sField)
sField = "Slicer3"
Call Synch_All_PT_Filters_BasedOn( _
PT:=.PivotTables(sMaster), sField:=sField)
sField = "Slicer4"
Call Synch_All_PT_Filters_BasedOn( _
PT:=.PivotTables(sMaster), sField:=sField)
sField = "Slicer5"
Call Synch_All_PT_Filters_BasedOn( _
PT:=.PivotTables(sMaster), sField:=sField)
sField = "Slicer6"
Call Synch_All_PT_Filters_BasedOn( _
PT:=.PivotTables(sMaster), sField:=sField)
sField = "Slicer7"
Call Synch_All_PT_Filters_BasedOn( _
PT:=.PivotTables(sMaster), sField:=sField)
sField = "Slicer8"
Call Synch_All_PT_Filters_BasedOn( _
PT:=.PivotTables(sMaster), sField:=sField)
sField = "Slicer9"
Call Synch_All_PT_Filters_BasedOn( _
PT:=.PivotTables(sMaster), sField:=sField)
sField = "Slicer10"
Call Synch_All_PT_Filters_BasedOn( _
PT:=.PivotTables(sMaster), sField:=sField)
sField = "Slicer11"
Call Synch_All_PT_Filters_BasedOn( _
PT:=.PivotTables(sMaster), sField:=sField)
sField = "Slicer12"
Call Synch_All_PT_Filters_BasedOn( _
PT:=.PivotTables(sMaster), sField:=sField)
End With
CleanUp:
Application.EnableEvents = True
End Sub
Module:
Code:
Public Function Synch_All_PT_Filters_BasedOn(PT As PivotTable, _
sField As String)
Dim PT2 As PivotTable
Dim vItems As Variant
'---Stores the visible items in an array
vItems = Store_PT_FilterItems(PT, sField)
'---make array of visible items in PT
For Each PT2 In Worksheets("Filtered Tables").PivotTables
If PT2.Name <> PT.Name Then
'---Applies same filter items to each PivotTable
Call Filter_PivotField( _
pvtField:=PT2.PivotFields(sField), _
vItems:=vItems)
End If
Next PT2
End Function
Private Function Store_PT_FilterItems(PT As PivotTable, _
sField As String) As Variant
'---Stores visible items in PivotField sField in an array
Dim sVisibleItems() As String
Dim pviItem As PivotItem
Dim i As Long
With PT.PivotFields(sField)
If .Orientation = xlPageField And _
.EnableMultiplePageItems = False Then
ReDim sVisibleItems(1)
sVisibleItems(0) = .CurrentPage
Else
For Each pviItem In .PivotItems
If pviItem.Visible Then
i = i + 1
ReDim Preserve sVisibleItems(i)
sVisibleItems(i - 1) = pviItem
End If
Next
End If
End With
Store_PT_FilterItems = sVisibleItems
End Function
Private Function Filter_PivotField(pvtField As PivotField, _
vItems As Variant)
'---Filters the PivotField to make stored vItems Visible
Dim sItem As String, bTemp As Boolean, i As Long
On Error Resume Next
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
If Not (IsArray(vItems)) Then
vItems = Array(vItems)
End If
With pvtField
.Parent.ManualUpdate = True
If .Orientation = xlPageField Then .EnableMultiplePageItems = True
If vItems(0) = "(All)" Then
For i = 1 To .PivotItems.Count
If Not .PivotItems(i).Visible Then _
.PivotItems(i).Visible = True
Next i
Else
For i = LBound(vItems) To UBound(vItems)
bTemp = Not (IsError(.PivotItems(vItems(i)).Visible))
If bTemp Then
sItem = .PivotItems(vItems(i))
Exit For
End If
Next i
If sItem = "" Then
MsgBox "None of filter list items found."
GoTo CleanUp
End If
.PivotItems(sItem).Visible = True
For i = 1 To .PivotItems.Count
If IsError(Application.Match(.PivotItems(i), _
vItems, 0)) = .PivotItems(i).Visible Then
.PivotItems(i).Visible = Not (.PivotItems(i).Visible)
End If
Next i
End If
End With
CleanUp:
pvtField.Parent.ManualUpdate = False
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
End Function