我正在使用Excel Interop,我有一个对象列表。我在循环中的Excel单元格中设置列表中对象的属性时需要很长时间:
- set_fact:
total: "{{ sum(item | int) }}" <--- it's not work!!!
loop:
- 1
- 4
- 3
- debug: var=total
workSheet = (Excel.Worksheet)wbook.ActiveSheet;
var row = 1;
foreach (var shiftStop in shiftStops)
{
row++;
workSheet.Cells[row, "A"] = shiftStop.MachineName;
workSheet.Cells[row, "B"] = shiftStop.MachineType;
workSheet.Cells[row, "C"] = shiftStop.UnitName;
}
列表包含大约4000个对象。完成返回需要4-5分钟。有没有办法让这个过程更快?
答案 0 :(得分:2)
执行代码时通常可以关闭以下功能:
Application.ScreenUpdating
关闭屏幕更新。如果Application.ScreenUpdating
设置为False,则Excel不会重绘屏幕。当您的代码运行时,屏幕会快速更新,并且用户通常无需查看每个更新。代码执行后,更新屏幕一次,可以提高性能。
<强> Application.DisplayStatusBar 强>
关闭状态栏。如果Application.DisplayStatusBar
设置为False,则Excel不会显示状态栏。状态栏设置与屏幕更新设置分开,这样即使屏幕未更新,您仍可以显示当前操作的状态。但是,如果您不需要显示每个操作的状态,则在代码运行时关闭状态栏也可以提高性能。
<强> Application.Calculation 强>
切换到手动计算。如果Application.Calculation
设置为xlCalculationManual
,则Excel仅在用户明确启动计算时计算工作簿。在自动计算模式下,Excel确定何时计算。例如,每次与公式相关的单元格值更改时,Excel都会重新计算公式。如果将计算模式切换为手动,则可以等到所有与公式关联的单元格都更新后再重新计算工作簿。只需在代码运行时根据需要重新计算工作簿,就可以提高性能。
<强> Application.EnableEvents 强>
关闭活动。如果Application.EnableEvents
设置为False,则Excel不会引发事件。如果有加载项侦听Excel事件,那些加载项会在记录事件时消耗计算机上的资源。如果加载项不必记录代码运行时发生的事件,则关闭事件可以提高性能。
<强> ActiveSheet.DisplayPageBreaks 强>
关闭分页符。如果ActiveSheet.DisplayPageBreaks
设置为False,则Excel不会显示分页符。在代码运行时没有必要重新计算分页符,并且在代码执行后计算分页符可以提高性能。
在Excel performance: Tips for optimizing performance obstructions文章中详细了解相关内容。
另外我建议发布底层的COM对象。所有Excel加载项应在不再需要时系统地释放对Excel对象的引用。未能系统地释放对Excel对象的引用可能会阻止Microsoft Office Excel正常关闭。
完成使用后,使用System.Runtime.InteropServices.Marshal.ReleaseComObject释放Excel对象。然后在Visual Basic中将变量设置为Nothing(C#中为null)以释放对该对象的引用。
答案 1 :(得分:0)
每次在Office应用程序中调用对象时都需要时间 - 尤其是通过互操作。这在您展示的循环操作中尤其明显。
相反,请考虑创建值的ARRAY,然后将数组写入Excel范围。 Excel应该将数组的每个元素写入单元格。这是将大量数据写入Excel以加快处理速度的标准做法。
假设shiftStops是一个数组,代码可能如下所示:
workSheet = (Excel.Worksheet)wbook.ActiveSheet;
var row = 1;
Excel.Range rng = worksheet.Cells[row, "A"];
rng = rng.Resize(1, shiftStops.Length);
rng.Value = shiftStops;