Выполнить цикл только для отфильтрованных сводных элементов - PullRequest
3 голосов
/ 09 марта 2012

Я хочу сложить DataRange.Value некоторых PivotItems из PivotTable, которые соответствуют определенным критериям, и я не хочу делать это каждый раз, когда PageFilter изменяется. Вот мой код:

Sub Worksheet_PivotTableUpdate(ByVal Target As PivotTable)
    Dim pt As PivotTable, pi As PivotItem, q as Double
    Set pt = ActiveSheet.PivotTables(1)
    q = 0
    For Each pi In pt.PivotFields(1).PivotItems
         If pi.Name = someCriteria Then
                    q = q + pi.DataRange.Value
         End If
    Next pi
End Sub

Код выполняется каждый раз, когда изменяется PT (очевидно), и работает очень хорошо, пока PageFilter не скрывает элемент, соответствующий someCriteria, и затем не произойдет 1004 Error, учитывая, что он не может извлечь DataRange свойство pi.

Два вопроса:

(В этом контексте) Есть ли способ запустить код только при изменении PageFilter (или это должно быть сделано с событием Worksheet_Change)?

Как запустить мой For-Loop только с отфильтрованными элементами?

Я нашел решение для некоторой обработки ошибок, но, думаю, должен быть более элегантный способ сделать это.

Спасибо.

1 Ответ

1 голос
/ 10 марта 2012

Я не могу воспроизвести вашу ошибку.Если я создаю простую сводную таблицу с элементами страницы «Test» и «Test2» и изменяю фильтр страницы, чтобы он не отображал «test», я не получаю ошибку 1004. Значение параметра someCriteria установлено равным «Test».Я получаю сообщение об ошибке 13 Несоответствие типов, независимо от того, скрыт ли «Тест» или нет, потому что он пытается добавить диапазон к q.

Error 13

Строка, выделенная отладчиком: «q = q + pi.DataRange.Value. "

Обратите внимание, что адрес pi.DataRange действительно не зависит от того, выбран ли тест в фильтре страницы.Например, на рисунке выбран Test2, а pi.DataRange.Address равен B4: B5.

Таким образом, если я изменяю код на следующий, он работает без ошибок, но это приводит к 3, хотя Тест не выбран:

Sub Worksheet_PivotTableUpdate(ByVal Target As PivotTable)
Dim pt As PivotTable, pi As PivotItem, q As Double
Dim someCriteria As String
Dim cell As Excel.Range

someCriteria = "test"
Set pt = ActiveSheet.PivotTables(1)
q = 0
For Each pi In pt.PivotFields(1).PivotItems
    If pi.Name = someCriteria Then
        For Each cell In pi.DataRange
            q = q + cell.Value
        Next cell
        Debug.Print q
    End If
Next pi
End Sub

Поскольку я не могу скопировать ваш первоначальный успех или конкретный сбой, мне явно не сильно поможет.Возможно, с более подробной информацией о структуре вашей сводной таблицы я мог бы быть.

Я могу с уверенностью сказать, что если вы хотите фиксировать только изменения в фильтре страницы, вам нужно кодировать событие Worksheet_Change, как вы и предполагали.

...