Я обновляю некоторые ячейки электронной таблицы Excel через Microsoft Office OpenXML SDK 2.0. Изменение значений делает все ячейки, содержащие формулу, которые зависят от недопустимых измененных ячеек. Однако из-за кэшируемых значений Excel не повторно вычисляет формуляр, даже если пользователь нажимает на "Calculate now".
Что лучший способ состоит в том, чтобы делать недействительным все зависимые ячейки целой рабочей книги через SDK? До сих пор я нашел следующий фрагмент кода по http://cdonner.com/introduction-to-microsofts-open-xml-format-sdk-20-with-a-focus-on-excel-documents.htm:
public static void ClearAllValuesInSheet
(SpreadsheetDocument spreadSheet, string sheetName)
{
WorksheetPart worksheetPart =
GetWorksheetPartByName(spreadSheet, sheetName);
foreach (Row row in
worksheetPart.Worksheet.
GetFirstChild().Elements())
{
foreach (Cell cell in row.Elements())
{
if (cell.CellFormula != null &&
cell.CellValue != null)
{
cell.CellValue.Remove();
}
}
}
worksheetPart.Worksheet.Save();
}
Помимо того, что этот отрывок не компилирует для меня, он имеет два ограничения:
Я ищу путь, который эффективен (в частности, только делает недействительным ячейки, которые зависят от значения определенной ячейки), и принимает все листы во внимание.
Обновление:
Тем временем мне удалось сделать компиляцию кода и работать и удалить кэшируемые значения на всех листах рабочей книги. (См. ответы.) Все еще я интересуюсь лучшими / альтернативными решениями, в особенности как только удалить кэшируемые значения ячеек, которые на самом деле зависят от обновленной ячейки.
Поскольку это частично решает мою проблему и, похоже, лучшего решения пока нет, переместил этот кодовый блок из вопроса в ответ ... Вот как выглядит новый код:
foreach (WorksheetPart worksheetPart in spreadSheet.WorkbookPart.WorksheetParts)
{
foreach (Row row in
worksheetPart.Worksheet.GetFirstChild<SheetData>().Elements())
{
foreach (Cell cell in row.Elements())
{
if (cell.CellFormula != null && cell.CellValue != null)
cell.CellValue.Remove();
}
}
}
Я использую это
static void FlushCachedValues(SpreadsheetDocument doc)
{
doc.WorkbookPart.WorksheetParts
.SelectMany(part => part.Worksheet.Elements<SheetData>())
.SelectMany(data => data.Elements<Row>())
.SelectMany(row => row.Elements<Cell>())
.Where(cell => cell.CellFormula != null)
.Where(cell => cell.CellValue != null)
.ToList()
.ForEach(cell => cell.CellValue.Remove())
;
}
Это очищает кешированные значения
приветствует