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

我有一个具有完全相同的切片机的两个数据透视表的工作簿。 我正在使用VBA脚本来同步两个切片器。 我把它们命名为“Slicer_xxxx_Master”,另一个命名为“Slicer_xxxx_Slave”。

下面的代码工作正常,除了有很多select的切片机。 由于它一个接一个地设置切片,所以它重复地重新过滤数据透视表,直到所有需要的切片被设置。

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

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 

如果您使用Excel 2013或更高版本,则可以将每个数据源添加到DataModel,然后只需定义它们之间的关系。 然后一个切片机将统治他们所有,这将比保持独立的事情快很多,因为OLAP / PowerPivot数据透视表只是简单地得到一个数组(VisiblieItemsList),告诉他们一次性显示什么。

但是如果你想保持独立的东西,那么在改变PivotItems状态(直接或通过切片机)时要加快速度,至less应该将每个数据透视表的.ManualUpdate属性设置为TRUE,以便在停止数据透视表之后更新每一个SlicerItem都被改变了。

鉴于我们在这里处理切片器,您可以通过执行以下操作(并将Pivots的.ManualUpdate属性设置为FALSE)来真正启动例程进行过载:

  1. 临时断开切片机从主和奴隶
  2. 像上面这样遍历切片caching
  3. 将切片机重新连接到主机和从机。

这个速度再快的原因是,Slicers的实现方式似乎存在一个bug,即使您已经设置了PivotTables,只要您更改SlicerItem的状态,就会导致数据透视表更新。 ManualUpdate设置为true,如我在这里写的博客post所述

在编写数据透视表时,我已经写了一个后期的瓶颈,这可能会引起人们的兴趣,还有很多答案可能值得一看,比如这个 。

我只在从属数据透视表上使用了ManualUpdate = FALSE和Disconnect / Reconnectfunction,事情比他们好得多。 谢谢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