01
使用 SUBTOTAL
使用 SUBTOTAL 函数可以 SUM 筛选的列表。 SUBTOTAL 函数很有用,因为与 SUM 不同,它会忽略以下内容:
因筛选列表导致的隐藏行。从 Excel 2003 开始,还可以使 SUBTOTAL 忽略所有隐藏行,而不仅仅是筛选掉的行。
其他 SUBTOTAL 函数。
02
使用 AGGREGATE
AGGREGATE 函数是一种计算 19 种不同聚合数据方法的强大而高效的方法(如 SUM、MEDIAN、PERCENTILE 和 LARGE)。 AGGREGATE 具有选项来忽略隐藏行或筛选掉的行、错误值和嵌套的 SUBTOTAL 和 AGGREGATE 函数。
03
避免使用 DFunctions
DSUM、DCOUNT、DAVERAGE 等 DFunctions 的速度比等效的数组公式快得多。DFunctions 的缺点是条件必须在一个单独的区域内,这使得在许多情况下使用和维护它们都不切实际。从 Excel 2007 开始,应使用 SUMIFS、COUNTIFS 和 AVERAGEIFS 函数而不是 DFunctions。
04
代码运行时禁用某些功能
为了提高 VBA 宏的性能,在执行代码时显式关闭不需要的功能。通常,在代码运行后进行一次重新计算或一次重绘就足够了,并且可以提高性能。在代码执行之后,将功能恢复到其原始状态。
在执行 VBA 宏时,通常可以禁用以下功能:
-
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 将不显示分页符。不需要在代码运行时重新计算分页符,并且在代码执行后计算分页符可以提高性能。
05
单个操作读写大数据块
通过显式减少数据在 Excel 和代码之间传输的次数来优化代码。与其一次循环单元格来获取或设置一个值,不如在一行中获取或设置整个单元格区域内的值,根据需要使用包含二维数组的变体来存储值。下面的代码示例比较这两个方法。
以下代码示例显示了未优化的代码,它以一次一个的方式循环遍历单元格来获取和设置单元格 A1:C10000 的值。这些单元格不包含公式。
Dim DataRange as Range Dim Irow as Long Dim Icol as Integer Dim MyVar as Double Set DataRange=Range("A1:C10000") For Irow=1 to 10000 For icol=1 to 3 ' Read the values from the Excel grid 30,000 times. MyVar=DataRange(Irow,Icol) If MyVar > 0 then ' Change the value. MyVar=MyVar*Myvar ' Write the values back into the Excel grid 30,000 times. DataRange(Irow,Icol)=MyVar End If Next Icol Next Irow
以下代码示例显示了优化后的代码,它以一次全部的方式使用数组来获取和设置单元格 A1:C10000 的值。这些单元格不包含公式。
Dim DataRange As Variant Dim Irow As Long Dim Icol As Integer Dim MyVar As Double ' Read all the values at once from the Excel grid and put them into an array. DataRange = Range("A1:C10000").Value2 For Irow = 1 To 10000 For Icol = 1 To 3 MyVar = DataRange(Irow, Icol) If MyVar > 0 Then ' Change the values in the array. MyVar=MyVar*Myvar DataRange(Irow, Icol) = MyVar End If Next Icol Next Irow ' Write all the values back into the range at once. Range("A1:C10000").Value2 = DataRange