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

时间:2011-12-27 14:17:51

标签: asp.net vb.net excel

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

几分钟后它成功运行了大约5条记录,但是本周的记录设置几乎是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()

3 个答案:

答案 0 :(得分:3)

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

每次写入单元格时都会产生很高的开销,因此,对数组中的数据进行细化,然后通过单次调用Excel对象模型将数组写入范围会快得多。

答案 1 :(得分:1)

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

xls.Calculation = Excel.XlCalculation.xlCalculationManual

此外,只能在打开工作簿后设置此属性,否则会抛出运行时错误。

答案 2 :(得分:0)

多年来拯救我的一种方法是添加

Application.ScreenUpdating = False

直接执行可能冗长的方法,然后

Application.ScreenUpdating = True

直接在代码之后,或者至少在代码中的某个稍后时间点。这迫使Excel在可见屏幕上不重绘任何内容,直到完成为止这个问题是我经常发现冗长的运行操作。