如何实例化一个已命名的Excel.Application对象,以便在意外之后进行后置macros垃圾回收

我是一个相对的VBA新手,devise一个相当复杂的macros,可以运行10秒到10分钟之间的任何东西,它的大部分工作在Dim appDatabaseInstance = New Excel.Application创build的Excel的另一个不可见实例中。 在代码执行过程中有很多函数和子程序被使用,尽pipe我已经尽了最大的努力来确保在任何半可预测性出错的情况下调用appDatabaseInstance.Quit ,但有一件事我无法控制- 用户。

具体来说,如果用户决定程序崩溃并且存在转义,VBA将会中断执行,并且由于发生了这个中断,我的垃圾收集例程(我认为)都不会发生。

因此,如果我能以某种可预测的方式命名我创build的实例,然后在创build新实例之前尝试find一个现有的实例并进行适当的处​​理,我会更加快乐。 这样,即使一个不幸的应用程序实例被打开,一旦用户尝试涉及程序的其他任何事情(如果不是这样,那么一个实例不太可能在上下文中引起太多的麻烦),它将被closures。

有没有人有什么build议?

您可以使用Application对象的EnableCancelKey属性来确定当用户中断您的代码时会发生什么

我build议你在迪克博客的EnableCancelKey上看到这篇文章 。

作为一个总结, EnableCancelKey有三个可能的设置:

  • xlDisable – 防止用户中断代码
  • xlInterrupt – 正常操作。 显示debugging器,代码处于debugging模式,无论中断时发生哪一行。
  • xlErrorHandler – 引发错误编号18,并与其他错误一样反应。 如果你有error handling设置,它被称为。

我以前不得不在VBA中做类似的事情。 下面的方法将closures所有其他excel进程,除了当前正在运行的代码。 请记住在尝试运行这个代码之前保存你的东西!

 Declare Function GetCurrentProcessId Lib "kernel32" () As Long Sub CloseOtherInstances() Dim currentId As Long Dim wmiObj As Object Dim process As Object Dim processes As Object currentId = GetCurrentProcessId Set wmiObj = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2") Set processes = wmiObj.ExecQuery("select * from win32_process where name ='EXCEL.exe'") For Each process In processes If process.ProcessId <> currentId Then process.Terminate Next process End Sub