无法设置PivotItem类(VBA)的Visible属性

我试图操纵一个Excel 2007数据透视表槽低谷VBA,所以我可以循环槽数据透视表的类别,设置所有不可见,但一个,保存为PDF表,并继续到下一个类别。 为此,我使用下面的一段代码。

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 

循环似乎是第一次工作。 每个类别都被取消select,但是第一个输出一个不错的PDF文件。 下一次它进入循环,但它给出了一个'无法设置PivotItem类的可见性属性'错误在指定的行。 我知道这样一个事实,在数据透视表中必须至less有一个项目被选中,但这不是问题,因为我试图将可见性设置为TRUE而不是FALSE。

我试图通过检查解决它,因为也许你是不允许设置一个已经可见的PivotItem可见,但似乎并没有工作。

任何帮助将非常感激!

这是由于数据透视表使用caching的数据透视表而不是当前数据透视表。 确保表格不保留任何旧的项目。 为此,请右键点击数据透视表,点击“数据”选项卡,并将“保留每个字段的数量”设置为“无”。 在VBA中这样做的代码是:

 Dim pt As PivotTable pt.PivotCache.MissingItemsLimit = xlMissingItemsNone 

我意识到这是旧的,但是想为将来寻求解决scheme的人做出贡献。

我遇到了同样的错误,我想到的解决scheme是在开始pivotitem循环之前刷新pivottable。

尝试下面的代码行:

 ActiveSheet.PivotTables("PivotTable1").RefreshTable 

检查PivotItem的方向。 我相信,如果方向是隐藏的,则不能将可见性设置为真。 如果是这样的话,那就先把方向改成别的东西吧。

可能有以下之一:

  • 您至less需要一个可见的PivotItem,并将它们全部设置为不可见
  • PivotField的方向== XlPivotFieldOrientation.xlHidden(0)
  • PivotField的AutoSortOrder!= Constants.xlManual(-4135)

你可以在下面find一个帮助函数的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) { } }