2012-07-13 79 views
2

我想操作Excel 2007數據透視表槽VBA,因此我可以循環槽數據透視表的類別,將所有設置爲不可見,但將其中一個保存作爲pdf並繼續到下一個類別。爲此,我使用下面的一段代碼。無法設置PivotItem類(VBA)的Visible屬性

Dim pf As PivotField 
Set pf = ActiveSheet.PivotTables("PivotTable1").PivotFields("NAME") 

Dim pi as PivotItem 
For Each pi In pf.PivotItems 

    If pi.Visible = False Then 
     pi.Visible = True 'Error here 
    End If 

    Dim pi2 As PivotItem 
    For Each pi2 In pf.PivotItems 
     If pi2 <> pi Then 
      pi2.Visible = False 
     End If 
    Next pi2 

    'Saving to PDF goes here 
Next pi 

循環似乎是工作的第一次。每個類別都取消選擇,但第一個輸出一個不錯的PDF文件。下一次進入循環時,它會在指定的行出現'Unable to set the Visible property of the PivotItem class'錯誤。我知道這樣一個事實,即在數據透視表中必須至少選擇一個項目,但這不是問題,因爲我試圖將可見性設置爲TRUE而不是FALSE。

我試圖通過檢查解決它,因爲也許你不允許將可見的PivotItem設置爲可見,但似乎沒有工作。

任何幫助將非常感謝!

+0

如果您註釋掉創建PDF的部分,它是沒有錯誤的工作? – 2012-07-13 13:46:28

+0

您使用的是什麼版本的Excel? – RBarryYoung 2012-07-13 16:58:32

回答

0

檢查PivotItem的方向。我相信,如果方向是xlHidden,您不能將Visible設置爲True。如果是這樣,那麼只需將方向改爲其他的東西。

3

我意識到這是舊的,但是想爲未來尋找解決方案的人提供幫助。

我遇到了同樣的錯誤,我想出的解決方案是在開始pivotitem循環之前刷新pivottable。使用高速緩存的樞軸項而不是當前一個

ActiveSheet.PivotTables("PivotTable1").RefreshTable 
+0

嗨,本,歡迎來到堆棧溢出! +1爲建設性的答案。確保將任何和所有代碼放入代碼塊(在將代碼輸入到答案文本字段時,只需在代碼前放4個空格)便於閱讀。 – 2013-04-09 15:27:27

5

這是由於透視表:

嘗試下面的代碼行。確保桌子不保留任何舊物品。爲此,請右鍵點擊數據透視表,點擊數據選項卡,然後將「每個字段保留的數量」設置爲「無」。在VBA這樣做的代碼是:

Dim pt As PivotTable 

pt.PivotCache.MissingItemsLimit = xlMissingItemsNone 
0

有可能是下列之一:

  • 至少需要一個可見PivotItem而你把它們都設隱形
  • 透視字段的定向== XlPivotFieldOrientation.xlHidden(0)
  • 透視字段的AutoSortOrder!= Constants.xlManual(-4135)

,您可以在下面找到在C#中的輔助函數的例子用於過濾通過特定的支點項目樞軸場:

public static void FilterPivotItems(PivotField pf, List<string> pivotItemNames) 
{ 
    PivotItems pis = pf.ChildItems; 

    // Orientation != XlPivotFieldOrientation.xlHidden and we need to filter by at least one value (as Excel implies) 
    if (pf.Orientation != 0 && pivotItemNames.Count > 0) 
    { 
     int oldAutoSortOrder = 0; 

     if (pf.AutoSortOrder != (int)Constants.xlManual) 
     { 
      oldAutoSortOrder = pf.AutoSortOrder; 
      pf.AutoSort((int)Constants.xlManual, pf.Name); 
     } 

     int pivotItemsCount = pf.PivotItems().Count; 
     List<int> pivotItemsToHide = new List<int>(); 

     for (int i = 1; i <= pivotItemsCount; i++) 
     { 
      PivotItem pi = pf.PivotItems(i); 

      // check if current pivot item needs to be hidden (if it exists in pivotItemNames) 
      var match = pivotItemNames.FirstOrDefault(stringToCheck => stringToCheck.Equals(pi.Value)); 

      if (match == null) 
      { 
       // hide these pivot items later because we can hit exception "Unable to set the Visible property of the PivotItem class" 
       // (this happens because all pivot items get hidden and we need to have at least one visible) 
       pivotItemsToHide.Add(i); 
      } 
      else 
      { 
       TryFilterPivotItems(pi, true, true); 
      } 
     } 

     for (int i = 0; i < pivotItemsToHide.Count; i++) 
     { 
      PivotItem pi = pf.PivotItems(pivotItemsToHide[i]); 
      TryFilterPivotItems(pi, false, true); 
     } 

     if (oldAutoSortOrder != 0) 
     { 
      pf.AutoSort(oldAutoSortOrder, pf.Name); 
     } 

     PivotTable pt = pf.Parent as PivotTable; 
     if (pt != null) 
     { 
      pt.Update(); 
     } 
    } 
} 

public static void TryFilterPivotItems(PivotItem currentPI, bool filterValue, bool deferLayoutUpdate = false) 
{ 
    try 
    { 
     PivotField pf = currentPI.Parent; 
     PivotTable pt = pf.Parent as PivotTable; 

     if (currentPI.Visible != filterValue) 
     { 
      if (deferLayoutUpdate == true && pt != null) 
      { 
       // just keep these three lines stick together, no if, no nothing (otherwise ManualUpdate will reset back to false) 
       pt.ManualUpdate = true; 
       currentPI.Visible = filterValue; 

       // this may be redundant since setting Visible property of pivot item, resets ManualUpdate to false 
       pt.ManualUpdate = false; 
      } 
      else 
      { 
       currentPI.Visible = filterValue; 
      } 
     } 
    } 
    catch (Exception ex) 
    { 

    } 
} 

public static void TryFilterPivotItems(PivotField pf, string itemValue, bool filterValue, bool deferLayoutUpdate = false) 
{ 
    try 
    { 
     PivotItem currentPI = pf.PivotItems(itemValue); 
     TryFilterPivotItems(currentPI, filterValue, deferLayoutUpdate); 
    } 
    catch (Exception ex) 
    { 

    } 
} 
相關問題