2012-03-09 37 views
4

我想對符合特定條件的PivotTable的某些PivotItemsDataRange.Value進行求和,我不會在每次更改PageFilter時都這樣做。這裏是我的代碼:只對已篩選的PivotItems執行循環操作

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發生,因爲它將無法獲取piDataRange財產。

兩個問題:

(在這種情況下)有沒有一種方法來運行代碼,只有當一個PageFilter變化(或者它必須與Worksheet_Change事件做)?

如何僅在已過濾項目中運行For-Loop

我已經想出了一個解決方案,做一些錯誤處理,但我猜測必須有一個更優雅的方式來做到這一點。

謝謝。

回答

1

我無法重現您的錯誤。如果我使用Page項目「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事件。

+0

這很聰明。我只是做Worksheet_Change並檢查單元格是否在數據透視表的報表過濾器範圍內。您可以檢查命名的範圍,或以編程方式確定報告過濾器範圍。我會做第一個,除非數據透視表可能會移動。 – 2012-03-13 18:11:48

+0

關於過濾器的更改,我不得不使用'PivotTable_Update'事件和'Worksheet_Change'事件的組合來捕獲它,因爲無法將過濾器與表的其餘部分隔離。數據透視表中的任何更改(不僅在過濾器中)都觸發宏。關於'for-loop',我不明白你爲什麼會遇到'13'錯誤,我從來沒有得到它。另一方面,我確定我一直在對「PivotItems」做一個不好的參考。實際的'PivotField'是一個'RowField',它是第二個層次結構。在實際的代碼中,我是用名字來引用它,這可能是一個問題。 – Pragabhava 2012-03-13 18:16:03