Ответ 1
spreadSheet.WorkbookPart.Workbook.CalculationProperties.ForceFullCalculation = true;
spreadSheet.WorkbookPart.Workbook.CalculationProperties.FullCalculationOnLoad = true;
Работает для меня!
Я обновляю некоторые ячейки электронной таблицы Excel через Microsoft Office OpenXML SDK 2.0. Изменение значений делает все ячейки, содержащие формулу, которые зависят от измененных ячеек, недействительны. Однако из-за кэшированных значений Excel не пересчитывает формулу, даже если пользователь нажимает кнопку "Рассчитать сейчас".
Каков наилучший способ аннулировать все зависимые ячейки всей книги через 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();
}
Помимо того, что этот фрагмент не компилируется для меня, он имеет два ограничения:
Я ищу способ, который эффективен (в частности, только делает недействительными ячейки, зависящие от определенного значения ячейки), и учитывает все листы.
Update:
Тем временем мне удалось сделать компиляцию и запуск кода, а также удалить кешированные значения на всех листах книги. (См. Ответы.) Тем не менее меня интересуют лучшие/альтернативные решения, в частности, как только удалять кешированные значения ячеек, которые на самом деле зависят от обновленной ячейки.
spreadSheet.WorkbookPart.Workbook.CalculationProperties.ForceFullCalculation = true;
spreadSheet.WorkbookPart.Workbook.CalculationProperties.FullCalculationOnLoad = true;
Работает для меня!
Я использую этот
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())
;
}
Сбрасывает кешированные значения
здоровается
Так как он частично решает мою проблему и, похоже, пока нет лучшего решения, переместил этот код из вопроса в ответ... Вот как выглядит новый код:
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();
}
}
}
Вам нужно сохранить рабочий лист в конце, это сработало для меня.
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();
}
}
worksheetPart.Worksheet.Save();
}
Алгоритмы:
Пример: при 45 градусах и 56 м/с мяч должен пройти 320 метров.