我只是试图遍历一堆单元格并将它们标记为脏(excel计算设置为手动),以便我可以快速告诉excel重新计算只是那些单元格及其的依赖关系。
出于某种原因,excel的.FindNext
方法速度很慢,实际上调用Application.CalculateFull()
要快得多。这怎么这么慢?
以下解决方案几乎完全符合Microsoft推荐的“FindAll”解决方案:http://msdn.microsoft.com/en-us/library/vstudio/e4x1k99a.aspx
app.Calculation = Excel.XlCalculation.xlCalculationManual;
DateTime start = DateTime.UtcNow;
foreach (Excel.Worksheet sheet in app.ActiveWorkbook.Sheets)
{
Excel.Range uncalculatedCell = sheet.Cells.Find("[Wait]",
LookIn: Excel.XlFindLookIn.xlValues, LookAt: Excel.XlLookAt.xlPart,
SearchOrder: Excel.XlSearchOrder.xlByColumns,
SearchDirection: Excel.XlSearchDirection.xlNext, MatchCase: true);
if (uncalculatedCell == null) return;
Excel.Range first = uncalculatedCell;
do
{
uncalculatedCell.Dirty(); //Can be commented out, doesn't impact time
uncalculatedCell = sheet.Cells.FindNext(After: uncalculatedCell);
} while (uncalculatedCell.AddressLocal != first.AddressLocal);
}
TimeSpan markDirty = (DateTime.UtcNow - start); //16 seconds for 300 results?!
app.Calculate(); //Trigger recalculation
TimeSpan recalculate = (DateTime.UtcNow - start) - markDirty; //~2 seconds
//app.CalculateFull() //~4 seconds depending on what else is in the sheet
例如:
如果工作簿中有0-5个匹配的单元格,则此例程在约0.05秒(50毫秒)内完成。大!但是如果有大约300个单元需要标记为脏,则该例程在大约16秒内完成。这没有理由。我们预计有时需要识别数千个这样的细胞。
将单元格标记为脏后,正确运行Calculate()
只会重新计算这些单元格(以及任何易失性单元格)及其依赖项。这个Calculate()
比调用RecalculateFull()
更快,但没有考虑到找到所需单元格所需的时间并将其标记为脏(我预计它几乎是瞬间完成的。)
有没有办法只识别需要重新计算的细胞并让它们更快地更新?