在Excel中一次设置多个切片器

时间:2017-10-03 15:46:29

标签: excel vba excel-vba pivot-table

我有一个带有两个数据透视表的工作簿,它们具有完全相同的切片器。我使用VBA脚本来同步两个切片器。我将它们命名为#34; Slicer_xxxx_Master"另一个是" Slicer_xxxx_Slave"。

以下代码运行正常,但有很多选项的切片器除外。由于它一个接一个地设置切片,它会反复重新过滤数据透视表,直到设置了所有必需的切片。

是否有方法将所有切片项值收集到一个数组中,然后一次设置Slave切片器值?

Private Sub Worksheet_PivotTableUpdate(ByVal Target As PivotTable)
Application.ScreenUpdating = False

Dim sC As SlicerCache
Dim sC_Slave As SlicerCache
Dim SL As SlicerCacheLevel
Dim sI As SlicerItem
Dim sI_Slave As SlicerItem


For Each sC In ActiveWorkbook.SlicerCaches
    If InStr(1, sC.Name, "Master") Then
        Set sC_Slave = ThisWorkbook.SlicerCaches(Replace(sC.Name, "Master", "Slave"))
        For Each sI In sC.SlicerItems
            If sI.Name <> ("(blank)") Then
                Set sI_Slave = sC_Slave.SlicerItems(sI.Name)
                If sI_Slave.Selected <> sI.Selected Then
                    sI_Slave.Selected = sI.Selected
                End If
            End If
        Next
    End If
Next

Application.ScreenUpdating = True
End Sub

2 个答案:

答案 0 :(得分:1)

如果您使用的是Excel 2013或更高版本,则可以将每个数据源添加到DataModel,然后只定义它们之间的关系。然后一个切片器将统治它们,并且它将比保持分离快得多,因为OLAP / PowerPivot数据透视表只需要一个数组(VisiblieItemsList),它可以一次性告诉它们显示什么。

但是如果你想把事情分开,那么在改变PivotItems的状态(直接或通过切片器)时加快速度,至少应该将每个数据透视表的.ManualUpdate属性设置为TRUE,以停止更改每个SlicerItem后更新数据透视表。

鉴于我们在这里处理Slicers,您可以通过执行以下操作(并将Pivots的.ManualUpdate属性设置为FALSE)将例程置于过载中:

  1. 暂时断开切片器与主设备和从设备的连接
  2. 像上面那样迭代切片器缓存
  3. 将切片器重新连接到Master和Slave。
  4. 再次快得多的原因是Slicers的实现方式似乎存在错误,因为每次更改SlicerItem的状态都会导致数据透视表更新......即使你已经设置了数据透视表.ManualUpdate设置为true,如我撰写的博文中所述here

    我在编写数据透视表here时编写了一个postcovering瓶颈,这可能会引起人们的兴趣,以及在这里可能值得一看的问题的一些答案,例如{{3} }。

答案 1 :(得分:1)

我在slave pivot table上只使用了ManualUpdate = FALSE和Disconnect / Reconnect功能,事情比他们好得多。谢谢Jeffrey!

Private Sub Worksheet_PivotTableUpdate(ByVal Target As PivotTable)
Application.EnableEvents = False
Application.ScreenUpdating = False

Dim sC As SlicerCache
Dim sC_Slave As SlicerCache
Dim sI As SlicerItem
Dim sI_Slave As SlicerItem
Dim wS As Worksheet
Dim pT As PivotTable

Set wS = ThisWorkbook.Worksheets("Totals Pivot")
wS.PivotTables("TotalsPivot").ManualUpdate = True

For Each sC In ThisWorkbook.SlicerCaches
    If InStr(1, sC.Name, "Master") Then
        Set sC_Slave = ThisWorkbook.SlicerCaches(Replace(sC.Name, "Master", "Slave"))
        sC_Slave.PivotTables.RemovePivotTable ("TotalsPivot")

        For Each sI In sC.SlicerItems
            Set sI_Slave = sC_Slave.SlicerItems(sI.Name)
            If sI_Slave.Selected <> sI.Selected Then
                sI_Slave.Selected = sI.Selected
            End If
        Next

        sC_Slave.PivotTables.AddPivotTable wS.PivotTables("TotalsPivot")
    End If
Next

wS.PivotTables("TotalsPivot").ManualUpdate = False

Application.EnableEvents = True
Application.ScreenUpdating = True
End Sub