在任何编程语言中,最佳实践都是避免过早的优化。但是,如果测试表明您的代码运行太慢,则可以通过在运行时关闭应用程序的某些属性来提高速度。将此代码添加到标准模块中:
Public Sub SpeedUp( _ SpeedUpOn As Boolean, _ Optional xlCalc as XlCalculation = xlCalculationAutomatic _ ) With Application If SpeedUpOn Then .ScreenUpdating = False .Calculation = xlCalculationManual .EnableEvents = False .DisplayStatusBar = False 'in case you are not showing any messages ActiveSheet.DisplayPageBreaks= False 'note this is a sheet-level setting Else .ScreenUpdating = True .Calculation = xlCalc .EnableEvents = True .DisplayStatusBar = True ActiveSheet.DisplayPageBreaks= True End If End With End Sub
有关Office博客的更多信息-Excel VBA性能编码最佳做法
只需在宏的开头和结尾处调用它即可:
Public Sub SomeMacro 'store the initial "calculation" state Dim xlCalc As XlCalculation xlCalc = Application.Calculation SpeedUp True 'code here ... 'by giving the second argument the initial "calculation" state is restored 'otherwise it is set to 'xlCalculationAutomatic' SpeedUp False, xlCalc End Sub
虽然这些可以在很大程度上视为常规Public Sub过程的“增强功能” ,但是Application.EnableEvents = False应该使用禁用事件处理对于Worksheet_Change和Workbook_SheetChange更改一个或多个工作表上的值的私有事件宏是必需的。未能禁用事件触发器将导致事件宏在值更改时在其自身上递归运行,并可能导致“冻结”工作簿。请记住,离开事件宏之前可能要通过“安全退出”错误处理程序重新打开事件。
Option Explicit Private Sub Worksheet_Change(ByVal Target As Range) If Not Intersect(Target, Range("A:A")) Is Nothing Then On Error GoTo bm_Safe_Exit Application.EnableEvents= False 'code that may change a value on the worksheet goes here End If bm_Safe_Exit: Application.EnableEvents= True End Sub
一个警告:虽然禁用这些设置可以改善运行时间,但它们可能会使调试应用程序更加困难。如果您的代码无法正常运行,请注释掉该SpeedUp True调用,直到找出问题所在。
如果要写入工作表中的单元格,然后从工作表函数中读取计算结果,则这特别重要,因为这会xlCalculationManual阻止工作簿的计算。要解决此问题而不禁用它SpeedUp,您可能需要包括Application.Calculate在特定点运行计算。
注意:由于这些是其Application本身的属性,因此您需要确保在宏退出之前再次启用它们。这使得使用错误处理程序并避免出现多个退出点(即End或Unload Me)特别重要。
错误处理:
Public Sub SomeMacro() 'store the initial "calculation" state Dim xlCalc As XlCalculation xlCalc = Application.Calculation On Error GoTo Handler SpeedUp True 'code here ... i = 1 / 0 CleanExit: SpeedUp False, xlCalc Exit Sub Handler: 'handle error Resume CleanExit End Sub