with spreadsheetlight spreadsheetdocument read open office documentformat create .net excel openxml openxml-sdk

.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(); }