Ускорение цикла слайсера в VBA

Я пытаюсь отсортировать сводную таблицу на основе некоторых значений True/False на другой вкладке. Я читал, что самый простой способ сделать это - слайсер. Код выполняется успешно, но для выполнения сортировки 230 элементов SlicerItem требуется около 45 секунд. Есть мысли как ускорить?

Вот мой код:

Sub CategoryMacro()
'Runs through Pivot Slicer and selects items from pivot table that meet certain certain TRUE/FALSE on MacroHelper

Dim wb As Workbook
Dim ws1, ws2 As Worksheet
Dim kpicat As String

'Speed Up
Application.EnableEvents = False
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False

Set wb = ThisWorkbook
Set ws1 = wb.Sheets("MacroHelper")
Set ws2 = wb.Sheets("Visual")

'Prep with some clean-up
ws2.Activate
ActiveWorkbook.SlicerCaches("Slicer_PRODNAME").ClearManualFilter

'Toggles off products with decreasing margin
For i = 2 To 230
    Let kpicat = ws1.Range("A" & i).Value
    If ws1.Range("D" & i).Value = 0 Then ActiveWorkbook.SlicerCaches("Slicer_PRODNAME").SlicerItems(kpicat).Selected = False
Next i

'Un-Speed Up
Application.ScreenUpdating = True
Application.EnableEvents = True
Application.Calculation = xlCalculationAutomatic

End Sub

Я использовал вариант этого кода ReDim (из здесь из ответа Криса) очень успешно работает с огромными наборами данных, но я не уверен, что его можно применить здесь. Если это возможно, я не уверен, как бы я его применил.

Sub GetRows()
    Dim valMatch As String
    Dim rData As Range
    Dim a() As Long, z As Variant
    Dim x As Long, i As Long
    Dim sCompare As String

    Set rData = Range("A1:A50000")
    z = rData
    ReDim a(1 To UBound(z, 1))
    x = 1
    sCompare = "aa"
    For i = 1 To UBound(z)
        If z(i, 1) = sCompare Then a(x) = i: x = x + 1
    Next
    ReDim Preserve a(1 To x - 1)    
End Sub

person Matt Cottrill    schedule 17.04.2018    source источник
comment
Поскольку ваш код работает, но работает медленно, он, вероятно, лучше подходит для проверки кода.   -  person dwirony    schedule 17.04.2018
comment
Есть ряд вещей, которые вы можете сделать, чтобы радикально ускорить процесс, и я вскоре опубликую ответ. Но сначала, какую версию Excel вы используете?   -  person jeffreyweir    schedule 18.04.2018
comment
@jeffreyweir Я использую Excel 2016.   -  person Matt Cottrill    schedule 18.04.2018
comment
@MattCottril Круто. Ознакомьтесь с моим измененным ответом ниже и соответствующими ссылками, и вы найдете то, что вам нужно, чтобы сделать это молниеносно.   -  person jeffreyweir    schedule 19.04.2018


Ответы (1)


Если вы когда-нибудь повторяете PivotItems, установите сводную таблицу .ManualUpdate в TRUE, пока вы вносите изменения, и установите его обратно в FALSE впоследствии, чтобы избежать обновления сводной таблицы после каждого изменения. Это радикально ускорит ваш код.

См. мой ответ на Как обновить кэш слайсера с помощью VBA для кода, который быстро фильтрует слайсер в массиве.

Обратите внимание, что еще быстрее ввести в сводную таблицу какое-либо поле "Истина/Ложь", добавив столбец подстановки к своим данным, а затем перенеся это поле в сводную таблицу в качестве поля страницы и установив для этого поля значение "ИСТИНА". Это почти сразу отфильтрует вашу сводную таблицу без итерации.

Чтобы узнать больше об эффективном программировании сводных таблиц, ознакомьтесь с моим сообщением в блоге по адресу http://dailydoseofexcel.com/archives/2013/11/14/filtering-pivots-based-on-external-ranges/

Если у вас есть Excel 2016, вы также можете использовать Measures и DataModel, чтобы сделать это через связанную таблицу, независимо от того, есть ли у вас расширенная версия с установленным PowerPivot. Но вам потребуется обновлять сводную таблицу каждый раз, когда ваша входная таблица изменяется.

person jeffreyweir    schedule 17.04.2018