OpenXML SDK: Make Excel recalculate formula

I update some cells of an Excel spreadsheet through the Microsoft Office OpenXML SDK 2.0. Changing the values makes all cells containing formula that depend on the changed cells invalid. However, due to the cached values Excel does not recalculate the formular, even if the user clicks on "Calculate now".

What is the best way to invalidate all dependent cells of the whole workbook through the SDK? So far, I've found the following code snippet at 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();
}

Besides the fact that this snippet does not compile for me, it has two limitations:

  • It only invalidates a single sheet, although other sheets might contain dependent formula
  • It does not take into account any dependencies.
  • I am looking for a way that is efficient (in particular, only invalidates cells that depend on a certain cell's value), and takes all sheets into account.

    Update:

    In the meantime I have managed to make the code compile & run, and to remove the cached values on all sheets of the workbook. (See answers.) Still I am interested in better/alternative solutions, in particular how to only delete cached values of the cells that actually depend on the updated cell.


    spreadSheet.WorkbookPart.Workbook.CalculationProperties.ForceFullCalculation = true;
    spreadSheet.WorkbookPart.Workbook.CalculationProperties.FullCalculationOnLoad = true;
    

    适合我!


    I use this

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

    This flushes the cached values

    greets


    由于它部分解决了我的问题,目前似乎还没有更好的解决方案,因此将该代码块从问题中移出来作为答案......这就是新代码的外观:

    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();
            }
        }
    }
    
    链接地址: http://www.djcxy.com/p/27756.html

    上一篇: 单元更新后刷新Excel工作表

    下一篇: OpenXML SDK:使Excel重新计算公式