【问题标题】:Poor performance updating Excel slicer selection using VBA使用 VBA 更新 Excel 切片器选择的性能不佳
【发布时间】:2014-02-25 05:07:30
【问题描述】:

我正在使用 VBA 模拟单击​​ Excel 切片器,但遇到了严重的性能问题。

用户单击 X 轴上带有日期的柱形图。单击列时,会在包含日期列表的切片器中选择相应的日期。该列表将随着时间的推移继续增长。

为非 OLAP 数据源(我的情况)设置切片器选择的唯一方法(据我所知)是为每个切片器项目单独设置 selected = true。由于每个设置都会触发重新计算,因此对于具有许多项目的切片器来说,这非常慢。

显示问题的小代码示例:

On Error GoTo Err_Handler:

Dim SC As SlicerCache
Set SC = ActiveWorkbook.SlicerCaches("Slicer_DATE")

Dim SI As SlicerItem

Application.EnableEvents = False
Application.Calculation = xlCalculationManual

For Each SI In SC.SlicerItems
    SI.Selected = True
Next

Err_Handler:
Application.Calculation = xlCalculationAutomatic
Application.EnableEvents = True

之前有人问过类似的问题:

Selecting multiple slicer items at once without a refresh

Pivot Slicer Update To Slow, Can I pause all functions until slicer update is complete?

建议是:

Application.EnableEvents = false

Application.Calculation = xlCalculationManual

更新:我还注意到,尽管关闭了事件和计算,但实际上所有数据透视表都在重新计算!

对我来说,这些选项都不起作用,也不会提高性能。计算确实被推迟了,并且没有触发任何事件。尽管如此, selected=true 的每次迭代仍需要大约 1.5 秒。该操作总共需要大约 5 分钟才能完成。

我的切片器连接到多个工作表中的 23 个数据透视表 (!)。基础数据(MS Access DB 连接)大约有 60,000 行,其中包含约 20 个变量,数量并不多。

感谢任何帮助。

【问题讨论】:

    标签: vba excel pivot-table


    【解决方案1】:

    数据透视表有一个ManualUpdate 属性,可以设置为True。为所有枢轴设置此属性可能有助于加快代码速度。

    请尝试在更新切片器代码所在的上方添加此代码:

    Dim PT As PivotTable
    Dim wb As Workbook
    Dim ws As Worksheet
    
    Set wb = ThisWorkbook
    
    For Each ws In wb.Sheets
        For Each PT In ws.PivotTables
            PT.ManualUpdate = True
        Next PT
    Next ws
    

    然后在你更新切片器后添加这个:

    For Each ws In wb.Sheets
        For Each PT In ws.PivotTables
            PT.ManualUpdate = False
        Next PT
    Next ws
    

    欲了解更多信息:
    Speed up pivot table filtering VBA code
    Turn Off PT Calc
    MSDN: ManulaUpdate

    希望对您有所帮助!

    【讨论】:

    • 非常感谢。我设法解决了这个问题。唯一的问题是,当设置 ManualUpdate = False 时,所有自定义系列格式都会丢失,我必须记录一个宏以在代码末尾运行以正确设置格式。
    • 很高兴它有帮助!感谢您的跟进!
    • 我尝试了以上所有方法,但我的一个切片器仍然有明显的延迟,它有 50 多个选项(我有 4 个级联切片器)。设置 Selected 值很慢,在我的情况下,将除 1 之外的所有值都设置为 false。我通过忽略具有 '.hasdata = false' 的那些来加快它的速度,因为将它们设置为 false 对下一个依赖切片器选择的值没有影响。
    【解决方案2】:

    你需要做的是复制切片器和 将字段复制为切片器和报表过滤器 见http://www.powerpivotpro.com/2010/12/another-way-to-get-and-use-slicer-values-in-formulas/

    然后使用 CurrentPage 属性选择项目:

    Private Sub SelectPivotItem(FieldName As String, Itemname As String)
        Dim PT As PivotTable, PTF As PivotField, PTI As PivotItem
        Set PT = shtInt.PivotTables("PivotTable1")
        Set PTF = PT.PivotFields(FieldName)
        PTF.ClearAllFilters
        PTF.CurrentPage = Itemname
    End Sub
    

    【讨论】:

      【解决方案3】:

      这对性能有很大帮助。同样的方法适用于在 VBA 中选择多个 PivotItem。

      1. 将数据透视表设置为 ManualUpdate。
      2. 在您进行多个切片器选择时,隐藏包含受切片器影响的数据透视表的所有工作表。

      完成后不要忘记将数据透视表设置为不手动更新,如果需要,之后将工作表设置为可见

      这很奇怪,因为即使使用 Application.ScreenUpdating = False 这仍然有很大帮助。

      通过执行此操作,我将 PivotItems 选择宏从 3 分钟缩短到 3 秒。完全不同。

      不幸的是,对于 Slicers 来说,这仍然很慢,大约 30 秒。我希望切换回使用 VBA 和 PivotItems 执行此操作,并完全避免使用切片器,除非我能找到另一种提高性能的方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多