首页 > 解决方案 > 终止所有剩余的 Excel 会话,仅由 Access VBA 过程创建

问题描述

有什么方法可以将 MS-Access VBA 创建的 EXCEL 会话与用户创建的其他 EXCEL 会话区分开来?

目前,我在过程结束时明确地通过其进程 ID 终止了 Excel 会话。由于它们可以保留,即使该实例肯定会关闭。

为了避免任何剩余的 Excel 会话,我想终止 MS-Access VBA 创建的所有其他 Excel 会话,但不包括用户的 Excel 会话。

这是当前脚本仅供您参考。我们可以通过#2 子程序终止所有 excel 会话,但可以包含用户会话。

-- #1 检查进程 ID 并在程序结束时终止

Public Declare Function GetWindowThreadProcessId Lib "user32" _
  (ByVal hwnd As Long, ByRef lpdwProcessId As Long) As Long

'Create New Instance
Set objExcel = New Excel.Application

'Get ProcessID of Excel Instance, Opened in this procedure.
Dim ProcXLID
Dim CurrentThreadID

ProcXLID = 0
CurrentThreadID = GetWindowThreadProcessId(objExcel.hwnd, ProcXLID)
Debug.Print "Current Excel Instance Handle : " & objExcel.hwnd & " ProcessID : " & ProcXLID

~ Export Excel Reports ~

'Close instance
objExcel.Quit
Set objExcel = Nothing

'Terminate own Excel Session if remains
ExcelProcess_kill ProcXLID

——#2。程序终止 Excel 会话

Sub ExcelProcess_kill(ByVal ProcID As Integer)

On Error Resume Next

    Dim objProcList
    Dim objProcess

    Dim StrProcName
    StrProcName = "EXCEL.EXE"

    Dim SessionCnt As Long
    SessionCnt = 0

    Set objProcList = GetObject("winmgmts:").InstancesOf("win32_process")

    'For Named Excel Process -- ExcelProcess_kill(pid)
    If ProcID > 0 Then

        For Each objProcess In objProcList
            If LCase(objProcess.Name) = StrProcName And LCase(objProcess.ProcessID) = ProcID Then
                Debug.Print "Terminate Session Info."; objProcess.Name; objProcess.ProcessID
                objProcess.Terminate
                SessionCnt = SessionCnt + 1
            End If
        Next

    'For All Excel Process -- ExcelProcess_kill(0) 
    Else

        For Each objProcess In objProcList
            If LCase(objProcess.Name) = StrProcName Then
                Debug.Print "Terminate Session Info."; objProcess.Name; objProcess.ProcessID
                objProcess.Terminate
                SessionCnt = SessionCnt + 1
            End If
        Next

    End If

    Debug.Print "Terminated Session Cnt :" & SessionCnt

End Sub

任何建议将再次受到高度赞赏。

标签: excelms-accesssessionpid

解决方案


确定用户是否打开 Excel 应用程序的一种简单方法是使用Application.UserControl属性,对于用户打开的应用程序为 true,而对于使用 VBA 打开的应用程序为 false。

您可以使用此答案中的代码获取所有正在运行的 Excel 应用程序的应用程序对象列表。然后,您可以使用现有代码杀死它们。

请注意,其他程序打开的 Excel 应用程序也将被终止。无法区分哪个 COM 程序打开了 Excel 应用程序。

另请注意,使 Excel 应用程序可见会将此属性设置为 true。但这可能是需要的,因为用户可能会在您创建的可见应用程序实例中打开其他工作簿,并且杀死这可能会导致用户丢失工作。


推荐阅读