2010-04-19 6 views
10

Я обновляю некоторые ячейки электронной таблицы Excel через Microsoft Office OpenXML SDK 2.0. Изменение значений делает все ячейки, содержащие формулу, которые зависят от измененных ячеек, недействительны. Однако из-за кэшированных значений Excel не пересчитывает формуляр, даже если пользователь нажимает «Рассчитать сейчас».OpenXML SDK: сделать 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:

В то же время я сумел сделать код компиляции & бежать, и удалить кэшированные значения на всех листах книги. (См. Ответы.) Тем не менее меня интересуют лучшие/альтернативные решения, в частности, как только удалять кешированные значения ячеек, которые на самом деле зависят от обновленной ячейки.

+0

После удаления кешированных значений, как вы читаете значение ячейки ?. Нужно ли закрывать объект ?. В моем случае, я получаю значение и ничего не возвращает – mggSoft

ответ

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

Работает для меня!

+0

Прохладный, выглядит намного проще! Чтобы сделать его более читаемым, вы можете отредактировать свой ответ и удалить пробелы перед исходным кодом? (До 4 пробелов, необходимых для форматирования текста в качестве исходного кода) – chiccodoro

+0

Bang! У меня тоже была работа, спасибо! – Brian

+0

Это не работает для меня в этой форме и в предыдущем сообщении. Что я могу попробовать? – mggSoft

1

Поскольку частично решает мою проблему и, кажется, нет лучшего решения до сих пор, что переехал кодоблок из вопроса в ответ ... Вот как новый код выглядит следующим образом:

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

Я использую это

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

Это вымывает кэшированные значения

здоровается

+0

Я пробовал это, и после удаления кешированных значений, я получаю значение и ничего не возвращает – mggSoft

+0

тоже здесь, этот подход не работает для меня. Я опубликовал аналогичный вопрос о SO. –

1

Вам нужно сохранить рабочий лист в конце, это сработало для меня.

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(); 
} 
Смежные вопросы