在自己单独的 Microsoft Excel 实例中使用 Excel VBA 到 运行 文件

Use Excel VBA to run file in own separate instance of Microsoft Excel

(最低要求:Excel 2010 和 Windows 7) 我已设法使用在 MSDN 中找到的 Bill Manville 的答案并稍作改动。建议的递归代码基本上使用文件的 Workbook_Open 来创建一个单独的实例,并且 taht 实例将文件打开为可编辑的,没有只读访问提示。

Private Sub Workbook_Open()
  Dim oXcl As Excel.Application
  If Workbooks.Count > 1 Then
    ThisWorkbook.Saved = True
    ThisWorkbook.ChangeFileAccess xlReadOnly
    Set oXcl = CreateObject("Excel.Application")
    oXcl.ScreenUpdating = False
    oXcl.Visible = True
    oXcl.Workbooks.Open fileName:=ThisWorkbook.FullName, ReadOnly:=False
    AppActivate oXcl.Caption
    ThisWorkbook.Close SaveChanges:=False
  Else 
    Call Continue_Open
  End If
End Sub

代码在 Excel 已经 运行ning 时工作得很好,因为它创建了一个新的 Excel 实例,如果打开了一个新的 Excel 文件,它转到另一个 Excel 实例(运行ning 在它之前)。但是,如果带有 Workbook_Open 的文件是 Excel 开头的文件,则通过在该 Excel 实例中双击打开可以打开任何其他 Excel 文件,因为它是最早的 运行 实例因此不再分离。

我已经能够通过使用

来判断(Windows)该文件是否开始Excel
Function NumberOfExcelInstances()
  strComputer = "."
  Set objWMI = GetObject("winmgmts:" & "{impersonationLevel=impersonate}!\" & strComputer & "\root\cimv2")
  Set proc = objWMI.ExecQuery("Select * from Win32_Process Where Name = 'Excel.exe'")
  NumberOfExcelInstances = proc.Count
End Function

但我无法找到一种方法来告诉在打开新文件时不要使用 Excel 实例。任何代码都应与 Worbook_Open 代码捆绑在 Excel 文件中。 我怎么可能在文件中包含 VBA 代码,以便它在单独的 Excel 实例中打开,即使该文件是触发 Excel?

的文件

在对应用程序级别的代码进行研究之后,找到了一个可行的解决方案。我正在发布它,以防其他人感兴趣。

第一次打开工作簿时,它会在应用程序级别(而不是工作簿级别)设置一个工作簿打开事件子例程。

当打开一个新工作簿时,应用程序级别的子程序会打开一个新实例,其中工作簿将通过递归保持分离 - 关闭应用程序实例中检查分离的工作簿,从而从应用程序实例中删除事件处理程序并在新创建的应用程序实例上设置该事件处理程序和代码。

包含所有相关代码,并且需要在三个不同的模块中。

1-a VBA Class 使用以下代码创建名为 cXlEvents 的模块:

'VBA Class Module named cXlEvents 
Public WithEvents appWithEvents As Application
'Instance variables
Dim sEventSetterPath As String
Dim sEventSetterName As String

Private Sub appWithEvents_WorkbookOpen(ByVal Wb As Workbook)
    Call NewAppInstance(Wb, sEventSetterPath, sEventSetterName)
End Sub

2-ThisWorkbook 模块包括:

'1-ThisWorkbook VBA Module calling events at 
'Workbook level.
'2-At Workbook Open set Application level event 
'handler and then instance code by calling subs 
'held in VBA standard module.  
Private Sub Workbook_Open()
  Call SetEventHandler
  Call NewAppInstance(Me)
End Sub

'Code to call "undo" special settings upon opening 
'when file closes
Private Sub Workbook_BeforeClose(Cancel As Boolean)
  Call UndoSettings
End Sub

3-从 class 将在应用程序级别结束的工作簿级别打开事件创建实例所需的所有代码都在标准 VBA 模块中:

'In a VBA standard Module
Dim oXlEvents As New cXlEvents

Sub SetEventHandler()
  If oXlEvents.appWithEvents Is Nothing Then
    Set oXlEvents.appWithEvents = Application
  End If
End Sub

Sub NewAppInstance(wbWbook As Workbook, Optional sEventSetterPath As String, Optional sEventSetterName As String)

  Dim oXcl As Excel.Application
  Dim wbEventSet As Workbook
  Dim lCaseNum As Long
  Dim sResetMacro As String: sResetMacroName = "UndoSettings"

  'Set instance variables
  sEventSetterPath = ThisWorkbook.FullName
  sEventSetterName = ThisWorkbook.Name

  If wbWbook.ReadOnly And wbWbook.FullName = sEventSetterPath Then
    MsgBox "Already open - please use open file.", , "WARNING"
    wbWbook.Close False
    Exit Sub
  End If

  If Workbooks.Count > 1 Then

    If wbWbook.FullName <> sEventSetterPath Then
      lCaseNum = 1
      Set wbEventSet = Workbooks(1)
      wbEventSet.Save
      Application.Run "'" & sEventSetterName & "'!'" & sResetMacro & "'"
    Else
      lCaseNum = 2
      Set wbEventSet = wbWbook
      wbEventSet.Saved = True
    End If
    wbEventSet.ChangeFileAccess xlReadOnly
    Set oXcl = CreateObject("Excel.Application")
    oXcl.Workbooks.Open Filename:=sEventSetterPath, ReadOnly:=False
    oXcl.Visible = True
    Set oXlEvents.appWithEvents = Nothing
    Select Case lCaseNum
      Case Is = 1
        AppActivate Application.Caption
      Case Is = 2
        AppActivate oXcl.Caption
    End Select
    wbEventSet.Close False
  Else
    Call Continue_Open
  End If
End Sub

Sub Continue_Open()
  'Code with special settings and procedures required for the workbook 
End Sub

Sub UndoSettings()
  'Code to "undo" any special settings when workbook opened   
 End Sub