Vba 在Excel中同时设置多个切片器

Vba 在Excel中同时设置多个切片器,vba,excel,pivot-table,Vba,Excel,Pivot Table,我有一个工作簿,其中有两个数据透视表,它们具有完全相同的切片器。我正在使用VBA脚本同步两个切片器。我给它们取了相同的名字,一个叫“切片机xxxx\u主控”,另一个叫“切片机xxxx\u从控” 下面的代码运行良好,除了在具有许多选项的切片器上。因为它一个接一个地设置了切片,所以它会一次又一次地重新过滤透视表,直到设置了所有需要的切片 是否有一种方法将所有切片项值收集到一个数组中,然后一次性设置所有从属切片器值 Private Sub Worksheet_PivotTableUpdate(ByVa

我有一个工作簿,其中有两个数据透视表,它们具有完全相同的切片器。我正在使用VBA脚本同步两个切片器。我给它们取了相同的名字,一个叫“切片机xxxx\u主控”,另一个叫“切片机xxxx\u从控”

下面的代码运行良好,除了在具有许多选项的切片器上。因为它一个接一个地设置了切片,所以它会一次又一次地重新过滤透视表,直到设置了所有需要的切片

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

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
Private子工作表\u数据透视表更新(ByVal目标作为数据透视表)
Application.ScreenUpdating=False
将sC变暗为切片机
作为切片机的Dim sC_从机
将SL调暗为切片机水平
Dim sI As Ritem
作为一种仪式的昏暗的奴隶
对于ActiveWorkbook.SlicerCaches中的每个sC
如果仪表(1,sC.名称,“主机”),则
设置sC_Slave=thishworkbook.SlicerCaches(替换(sC.Name,“Master”,“Slave”))
对于sC中的每个sI
如果sI.Name(“(空白)”),则
设置sI_Slave=sC_Slave.SlicerItems(sI.Name)
如果选择了sI_Slave.sI.则
sI_Slave.Selected=sI.Selected
如果结束
如果结束
下一个
如果结束
下一个
Application.ScreenUpdating=True
端接头

如果您使用的是Excel 2013或更高版本,则可以将每个数据源添加到数据模型中,然后定义它们之间的关系。然后,一个切片器将控制所有数据,这比将数据分开要快得多,因为OLAP/PowerPivot数据透视表只需输入一个数组(VisiblieItemsList),该数组一次性告诉它们要显示什么

但是,如果希望保持数据的独立性,那么为了在更改数据透视项的状态时加快速度(无论是直接更改还是通过切片器更改),至少应将每个数据透视表的.ManualUpdate属性设置为TRUE,以便在更改每个切片后停止数据透视表的更新

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

  • 暂时断开切片器与主机和从机的连接
  • 像上面那样迭代切片器缓存
  • 将切片器重新连接到主机和从机
  • 速度更快的原因是,切片器的实现方式似乎存在一个缺陷,即无论何时更改切片器的状态,它都会导致数据透视表更新…即使您已将数据透视表设置为true。ManualUpdate设置为true,正如我写的一篇博客文章所述


    我在编程数据透视表时写了一篇后处理瓶颈的文章,这可能是我感兴趣的,还有很多关于这里的问题的答案,可能值得一看,例如。

    我只在从属数据透视表上使用了ManualUpdate=FALSE和Disconnect/Reconnect函数,情况比以前好多了。谢谢杰弗里

    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
    
    Private子工作表\u数据透视表更新(ByVal目标作为数据透视表)
    Application.EnableEvents=False
    Application.ScreenUpdating=False
    将sC变暗为切片机
    作为切片机的Dim sC_从机
    Dim sI As Ritem
    作为一种仪式的昏暗的奴隶
    将wS设置为工作表
    数据透视表
    设置wS=ThisWorkbook.Worksheets(“总计轴”)
    wS.PivotTables(“TotalsPivot”).ManualUpdate=True
    对于此工作簿中的每个sC.SlicerCaches
    如果仪表(1,sC.名称,“主机”),则
    设置sC_Slave=thishworkbook.SlicerCaches(替换(sC.Name,“Master”,“Slave”))
    sC_Slave.PivotTables.RemovePivotTable(“TotalsPivot”)
    对于sC中的每个sI
    设置sI_Slave=sC_Slave.SlicerItems(sI.Name)
    如果选择了sI_Slave.sI.则
    sI_Slave.Selected=sI.Selected
    如果结束
    下一个
    sC_Slave.PivotTables.AddPivotTable wS.PivotTables(“TotalsPivot”)
    如果结束
    下一个
    wS.PivotTables(“TotalsPivot”).ManualUpdate=False
    Application.EnableEvents=True
    Application.ScreenUpdating=True
    端接头
    
    两个问题:首先,我们这里讨论的是表切片器还是数据透视表切片器。我假设是支点。如果是,数据透视“传统”数据透视是基于工作簿中的范围,还是基于OLAP/PowerPivot模型绘制?它们是基于完全相同的数据源(在这种情况下,您可以修改SlicerConnections属性,以便它们在不使用代码的情况下同步每个轴)还是基于不同的缓存?您好,谢谢。数据透视表切片器,传统数据透视表。它们有单独的数据集,但两个数据集具有完全相同的切片字段。每个透视表实际上有5个单独的切片器,但它们都分别命名为“主”和“从”。主切片器在仪表板工作表上可见,从切片器与透视表隐藏在同一工作表上,因此它只需要单向同步。谢谢Jeffrey!这是一个很好的建议。我的公司仍在为我提供2010,所以我不能使用数据模型,尽管这听起来像是我将考虑实现的东西。不过,我会担心分发该文件,因为用户可能仍在使用2010。目前,我使用了.ManualUpdate=TRUE函数,这大大缩短了等待时间。这是一个简单的解决办法!等我有更多的时间,我会看看你的替代方法。我很感兴趣,酷。如果我今天有时间,我将发布一些采用这种方法的代码。