在启动任何繁重的脚本之前,我需要使用Excel进行一些性能调整:
'Save parameters
screenUpdateState = Application.ScreenUpdating
statusBarState = Application.DisplayStatusBar
calcState = Application.Calculation
eventsState = Application.EnableEvents
'Turn them off
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
所以我在运行几乎所有程序之前粘贴此代码(或调用特殊过程,包含此代码,没有区别)。有没有办法自动执行此操作(某种全局构造函数)?
完成程序后,代码的情况也是如此:
'Put everything back
Application.ScreenUpdating = screenUpdateState
Application.DisplayStatusBar = statusBarState
Application.Calculation = calcState
Application.EnableEvents = eventsState
答案 0 :(得分:2)
循环遍历范围并选择各种事物的代码经常需要这种优化,并且几乎可以始终。如果您需要帮助优化繁重的脚本,请使用资源密集型代码提出另一个问题。
如果没有看到一个“重型脚本”的示例,最好的办法就是将设置和恢复代码放在子设备中,并在运行程序之前和之后调用它们。
Sub HeavyLifting()
Call GetReadyToProcess
' code for sub...
Call ReturnSettingsToWhatTheyWere
End Sub
Sub GetReadyToProcess()
'Save parameters
screenUpdateState = Application.ScreenUpdating
statusBarState = Application.DisplayStatusBar
calcState = Application.Calculation
eventsState = Application.EnableEvents
'Turn them off
Application.ScreenUpdating = False
Application.DisplayStatusBar = False
Application.Calculation = xlCalculationManual
Application.EnableEvents = False
End Sub
Sub ReturnSettingsToWhatTheyWere()
'Put everything back
Application.ScreenUpdating = screenUpdateState
Application.DisplayStatusBar = statusBarState
Application.Calculation = calcState
Application.EnableEvents = eventsState
End Sub
答案 1 :(得分:1)
此示例仅适用于1个模块的1个过程,但您可以迭代所有模块的所有过程并使用相同的逻辑。它使用Jon Crowell的程序。
Private Sub SwitchHeaderFooter()
Dim lineNr As Long
Dim procName As String
Dim strHeader As String
Dim strFooter As String
procName = "TestProc"
strHeader = "Call GetReadyToProcess"
strFooter = "Call ReturnSettingsToWhatTheyWere"
Dim vbComp As VBIDE.VBComponent
Dim vbModule As VBIDE.CodeModule
Set vbComp = ThisWorkbook.VBProject.VBComponents("ModuleTest")
Set vbModule = vbComp.CodeModule
lineNr = vbModule.ProcBodyLine(procName, vbext_pk_Proc)
If (vbModule.Lines(lineNr + 1, 1) = strHeader) Then
vbModule.DeleteLines lineNr + 1, 1
Else
vbModule.InsertLines lineNr + 1, strHeader
End If
lineNr = vbModule.ProcCountLines(procName, vbext_pk_Proc)
If (vbModule.Lines(lineNr - 1, 1) = strFooter) Then
vbModule.DeleteLines lineNr - 1, 1
Else
vbModule.InsertLines lineNr, strFooter
End If
End Sub
在ModuleTest中,在第一次执行之前:
Sub TestProc()
MsgBox "This is a test procedure!"
End Sub
第一次执行后:
Sub TestProc()
Call GetReadyToProcess
MsgBox "This is a test procedure!"
Call ReturnSettingsToWhatTheyWere
End Sub
最后,在第二次执行后:
Sub TestProc()
MsgBox "This is a test procedure!"
End Sub
答案 2 :(得分:0)
稍微玩一下,但这些内容应该有效,你可以按照你想要的方式设置它
注意:您需要访问VBA项目对象模型
Sub a()
Dim l as VBIDE.VBComponent
Dim strng As String
strng = "Sub b()" & vbCrLf & "***your routine***" & vbCrLf & "End Sub"
Set l = ThisWorkbook.VBProject.VBComponents.Add(vbext_ct_StdModule)
l.CodeModule.AddFromString strng
End Sub
您可以进一步扩展它并将其转换为一个函数,您可以传递您想要的子名称或传递模块名称(如果您希望它附加到现有模块)。
如果有人可以指出你应该声明 - 从Miguel的回答中得到了这个,这是类似的。l
的内容,我把它留空了,但是如果有办法正确设置它,那么就意味着你会得到Intellisene。
现在,我想要玩得开心! :)