There might be one of the following:
- You need at least one visible PivotItem and you're setting them all to invisible
- PivotField's Orientation == XlPivotFieldOrientation.xlHidden (0)
- PivotField's AutoSortOrder != Constants.xlManual (-4135)
You can find below an example in C# of helper functions for filtering a pivot field by specific pivot items:
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)
{
}
}