Оптимизировать для каждого цикла в сводной таблице
Я с трудом пытаюсь оптимизировать VBA For Each
цикл, который должен анализировать 10-15 тыс. строк в сводной таблице, основанной на таблице Excel, все в одной книге. В настоящее время это занимает около 2 минут, что я хотел бы улучшить, поскольку я использую это на собраниях.
Я искал и нашел несколько интересных предложений, таких как отключение обновления экрана, ручные вычисления иdim
"Мои переменные, как и другие типы данных, но я не получил разницы в скорости. Я предполагаю, For Each
Цикл просто не предназначен для этой цели.
Читая этот пост Супер пользователя, похоже, я мог бы поместить соответствующие значения в "Словарь" и это было бы очень быстро. Тот факт, что у меня есть два элемента для фильтрации, делает его немного более сложным для меня.
Я "учусь на собственном опыте" и не претендую на звание программиста VBA, так что любая помощь очень ценится!
Dim pvtTable As PivotTable
Dim pvtField1, pvtField2 As PivotField
Dim pvtItem1, pvtItem2 As PivotItem
Set ws = ActiveSheet
Set pvtTable = ws.PivotTables("PTReport")
Set pvtField1 = pvtTable.PivotFields("callNummer")
Set pvtField2 = pvtTable.PivotFields("Destination")
Application.ScreenUpdating = False
For Each pvtItem1 In pvtField1.PivotItems
If InStr(UCase(pvtItem1), "STORE") > 0 Then
pvtItem1.Visible = True
Else
pvtItem1.Visible = False
End If
Next
For Each pvtItem2 In pvtField2.PivotItems
If InStr(UCase(pvtItem2), "221") > 0 Then
pvtItem2.Visible = True
Else
pvtItem2.Visible = False
End If
Next
Application.ScreenUpdating = True
Если я могу что-то уточнить или предоставить, более подробную информацию, пожалуйста, дайте мне знать.
2 ответа
Я подозреваю, что звонки на 20-30К InStr(UCase())
проблема Я предлагаю вам определить пару вспомогательных столбцов. Например, если ваши данные "callNummer" и "Destination" находятся в столбцах A
а также B
, задавать
Y1
→=IFERROR(SEARCH("store", A1), 0)
Z1
→=IFERROR(SEARCH("221", B1), 0)
а затем измените код VBA, чтобы проверить, Yn
а также Zn
являются > 0
, Таким образом, проверка строки в строке выполняется всякий раз, когда изменяются данные "callNummer" и "Destination", и для подпрограммы VBA требуется гораздо меньше работы. И, конечно же, вы можете скрыть вспомогательные столбцы, когда все заработает.
Я не уверен, как именно перевести ваш pvtItemN.Visible = …
заявления в этой структуре.
Но даже если вы не можете заставить это работать, вы можете изменить InStr(UCase(pvtItem2), "221")
тест на InStr(pvtItem2, "221")
, Если все, что вам нужно, это число, то нет смысла переводить алфавитное содержимое ячейки в верхний регистр.
Перед первым циклом for...next добавьте следующий код:
Dim saveCalc as xlCalculation
With Application
.ScreenUpdating = False
saveCalc = .Calculation
.Calculation = xlCalculationManual
End With
Затем, после второго цикла for...next, добавьте следующий код:
With Application
.ScreenUpdating = True
.Calculation = saveCalc
End With