.net - spreadsheetlight - SDK de OpenXML: hacer que Excel recalcule la fórmula
spreadsheetdocument c# (4)
Dado que resuelve parcialmente mi problema y parece que no hay una solución mejor hasta ahora, movió ese bloque de código de la pregunta a una respuesta ... Así es como se ve el nuevo código:
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();
}
}
}
Actualizo algunas celdas de una hoja de cálculo de Excel a través de Microsoft Office OpenXML SDK 2.0. Al cambiar los valores, todas las celdas que contienen fórmula que dependen de las celdas modificadas son inválidas. Sin embargo, debido a los valores almacenados en caché, Excel no vuelve a calcular el formulario, incluso si el usuario hace clic en "Calcular ahora".
¿Cuál es la mejor manera de invalidar todas las celdas dependientes de todo el libro de trabajo a través del SDK? Hasta ahora, he encontrado el siguiente fragmento de código en 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();
}
Además del hecho de que este fragmento no compila para mí, tiene dos limitaciones:
- Solo invalida una sola hoja, aunque otras hojas pueden contener una fórmula dependiente
- No tiene en cuenta ninguna dependencia.
Estoy buscando una forma que sea eficiente (en particular, solo invalide celdas que dependen del valor de cierta celda), y toma todas las hojas en cuenta.
Actualizar:
Mientras tanto, he logrado hacer que el código se compile y se ejecute, y eliminar los valores almacenados en caché en todas las hojas del libro de trabajo. (Consulte las respuestas.) Aún estoy interesado en soluciones mejores / alternativas, en particular, cómo eliminar solo los valores en caché de las celdas que realmente dependen de la celda actualizada.
yo uso esto
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())
;
}
Esto vacía los valores almacenados en caché
saluda
spreadSheet.WorkbookPart.Workbook.CalculationProperties.ForceFullCalculation = true;
spreadSheet.WorkbookPart.Workbook.CalculationProperties.FullCalculationOnLoad = true;
¡Funciona para mi!
Debe guardar la hoja de trabajo al final. Esto funcionó para mí.
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();
}