2014-10-31 40 views
1

启动任何沉重的脚本之前后,自动执行代码,我需要做一些性能调整与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

不一定你在问什么,但我确切地说这存储在一个我总是加载的.xlam文件中,所以当我想要在启动一个新脚本时复制/粘贴时,只需点击一下即可。知道是否有更简单的方法会很有趣 – bmgh1985 2014-10-31 15:11:21

+0

不,不可能做你想问什么,把这些语句放在他们自己的子程序中,并根据需要用'调用mySubroutine()'语句或'Application 。运行“mySubroutine”。 – 2014-10-31 15:35:00

+1

@ bmgh1985你可以使用“PERSONAL。XLSB“文件来包含常用的宏,代码片段等,你可以把它放在XLSTART文件夹中,并用'Workbook_Open'事件隐藏这个文件,这样它就不会像电子表格那样被无意中使用。 – 2014-10-31 15:37:34

回答

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 
+0

如果“ModuleTest”是具有任何属性的类模块,则会中断。 – RubberDuck 2014-10-31 21:08:23

2

代码,并且可以几乎ALWAYS是避免。如果您需要优化重脚本的帮助,请使用资源密集型代码提出另一个问题。

没有看到你的一个“笨重的脚本”的例子,最好的办法是把你的设置和恢复代码放在潜艇中,并在运行你的程序之前和之后调用它们。

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 
+0

这就是我现在正在做的事情。问题是,是否可以自动启动这些东西,而无需插入'Call GetReadyToProcess'进入每一个程序 PS当使用其中有很多公式的工作表时,这段代码会提高性能,并且重新计算需要10+秒以上。 – 2014-10-31 15:21:53

+0

如果您处理多个程序,这是可行的(并且是一种非常有效的方法)在一个文件中是subs,但是我读到的问题更多的是每次你想每次在一个新文件中写入一个新的vba时,不得不不断地输入它。 – bmgh1985 2014-10-31 15:21:57

+3

是什么导致您需要这样做? AFAIK,你不能在每个新的子目录中自动调用它。 – 2014-10-31 15:23:54

0

将采取一点点玩w第i个,但这些方针的东西应该工作,你可以将它设置你想要的

注意:您需要对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 

你可以扩展这个越来越把它转换成你想传递子名称的函数,或者如果你想将它附加到现有的模块,可以传递一个模块名称。

如果有人能指出你应该声明l为,我将它留为空白,但是如果有方法正确设置它,那么这意味着你会得到Intellisene。 - 从米盖尔的回答中得知了这一点,这是类似的情况

现在,我不想有一些乐趣了! :)

+0

您可能感兴趣的。 [我一直在研究一个项目,使它更容易与VBIDE合作](http://codereview.stackexchange.com/q/63815/41243)。 – RubberDuck 2014-10-31 22:09:08

相关问题