写入Excel文件包含公式是非常缓慢的

我们有一个自动的过程,打开一个模板excel文件,写入数据行,并将文件返回给用户。 这个过程通常很快,但是最近我被要求用一些Excel公式添加一个摘要页面到其中一个模板,现在这个过程需要一个永久的过程。

几分钟后它成功地运行了大约5条logging,但是本周的logging集将近400行,而且我已经让它运行的最长时间是在取消它之前的大约半个小时。 如果没有这些公式,只需要几秒钟就可以运行。

将行写入包含公式的Excel文件中是否存在任何已知问题? 或者有没有办法告诉Excel不要评估公式,直到文件被用户打开?

汇总表上的公式是这样的:

' Returns count of cells in column where data = Y =COUNTIF(Sheet1!J15:Sheet1!J10000, "Y") =COUNTIF(Sheet1!F15:Sheet1!F10000, "Y") ' Return sum of column where data is a number greater than 0 ' Column contains formula calculating the difference in months between two dates =SUMIF(Sheet1!I15:Sheet1!I10000,">0",Sheet1!I15:Sheet1!I10000) ' Returns a count of distinct values in a column =SUMPRODUCT((Sheet1!D15:Sheet1!D10000<>"")/COUNTIF(Sheet1!D15:Sheet1!D10000,Sheet1!D15:Sheet1!D10000&"")) 

写入excel的代码看起来像这样:

 Dim xls as New Excel.Application() Dim xlsBooks as Excel.Workbooks, xlsBook as Excel.Workbook Dim xlsSheets as Excel.Sheets, xlsSheet as Excel.Worksheet Dim xlsCells as Excel.Range xls.Visible = False xls.DisplayAlerts = False xlsBooks = xls.Workbooks xlsBooks.Open(templateFile) xlsBook = xlsBooks.Item(1) ' Loop through excel Sheets. Some templates have multiple sheets. For Each drSheet as DataRow in dtSheets.Rows xlsSheets = xlsBook.Worksheets xlsSheet = CType(xlsSheets.Item(drSheet("SheetName")), Excel.Worksheet) xlsCells = xlsSheet.Cells ' Loop though Column list from Database. Each Template requires different columns For Each drDataCols as DataRow in dtDataCols.Rows ' Loop though Rows to get data For Each drData as DataRow in dtData.Rows xlsCells(drSheet("StartRow") + dtData.Rows.IndexOf(drData), drDataCols("DataColumn")) = drData("Col" + drDataCols("DataColumn").toString).toString Next Next Next xlsSheet.SaveAs(newFile) xlsBook.Close xls.Quit() 

使用auto模式计算时,每次input/更改数据后都会重新计算。 我有同样的问题,通过设置Manual计算模式解决。 (参考MSDN 链接 。)

 xls.Calculation = Excel.XlCalculation.xlCalculationManual 

另外,只有在打开Workbook之后才能设置此属性,否则会引发运行时错误。

每次写入单元格时,Excel都会重新计算打开的工作簿并刷新屏幕。 这两个东西都很慢,所以你需要设置Application.Screenupdating = false和Application.Calculation = xlCalculationManual

另外,每次写入单元的开销都很高,因此在数组中实现数据交换更加快速,然后通过一次调用Excel对象模型将数组写入范围。

多年来救我的一个办法就是补充一下

 Application.ScreenUpdating = False 

直接执行一个可能冗长的方法之前,然后

 Application.ScreenUpdating = True 

直接在代码之后,或者至less在稍后的一些代码中。 这迫使Excel不重绘可见屏幕上的任何东西,直到它完成这个问题是我发现冗长的运行操作经常从干。