Решением этой проблемы было использование динамического именованного диапазона в Excel для источника данных сводной таблицы. Формула динамического именованного диапазона использует комбинацию функции OFFSET и функции COUNTA следующим образом:
=OFFSET(DataSourceWorksheet!$A$2,0,0,COUNTA(DataSourceWorksheet!$A$2:$A$1000),1)
Приведенная выше формула приведет к диапазону ячеек в A2: A1000, которые имеют данные. В моем случае мне потребовалось более одного столбца, и я увеличил диапазон строк, чтобы «проверить» данные.
Теперь в C # для создания именованного диапазона я использовал следующее:
Names wrkBookNames = wrkBook.Names;
string dynamicRangeFormula = "=OFFSET(DataSourceWorksheet!$A$2,0,0,COUNTA(DataSourceWorksheet!$A$2:$A$1000),1)";
wrkBookNames.Add("MyNamedRange", dynamicRangeFormula );
и затем, чтобы указать этот именованный диапазон в качестве источника данных при создании новой сводной таблицы, я просто передаю строковое значение имени диапазона в метод PivotTableWizard:
//get range for pivot table destination
Range pivotDestinationRange = pivotWorkSheet.get_Range("A1", Type.Missing);
wrkBook.PivotTableWizard(
XlPivotTableSourceType.xlDatabase,
"MyNamedRange",
pivotDestinationRange,
pivotTableName,
true,
true,
true,
true,
Type.Missing,
Type.Missing,
false,
false,
XlOrder.xlDownThenOver,
0,
Type.Missing,
Type.Missing
);
Теперь, когда строки добавляются или удаляются в DataSourceWorkSheet, сводная таблица будет ссылаться только на ячейки со значениями данных, используя именованный диапазон. Обновление сводной таблицы теперь работает как положено, вызывая RefreshTable:
PivotTable pivot = (PivotTable)pivotWorkSheet.PivotTables(pivotTableName);
pivot.RefreshTable();
В целом, это будет происходить в методе создания новой рабочей книги Excel или обновления существующей рабочей книги. Вызов этого метода для существующей рабочей книги теперь зависит от того факта, что существующая сводная таблица была создана с использованием динамического именованного диапазона и будет соответствующим образом обновлена.