如何使用 VBA 关闭在单独的 Excel 实例中打开的工作簿?

问题描述 投票:0回答:2

我有一个 Excel 文件,该文件在 SAP 中运行各种查询,然后将其导出到 Excel,然后在新的 Excel 实例中打开。我不想打开这些文件。不幸的是,似乎没有一个很好的方法来告诉 SAP 停止这样做。我认为一个简单的解决方法是通过向我的原始脚本添加一个循环来关闭它打开的 ~15 个文件;但是,该宏的范围似乎有限,只能关闭“此”Excel 实例中包含的文件。

我已经阅读了 Stackoverflow 和许多旧论坛,但似乎没有人真正有办法做到这一点。如果文件包含在与宏相同的实例中,但似乎无法到达外部,则此代码可以正常工作。

For Each PartNumber In PNArray

    exportFileName = PartNumber & "_Export.xlsx"
    Workbooks(exportFileName).Close SaveChanges:=False

Next PartNumber

有人有什么巧妙的技巧可以帮助我关闭这些文件吗?我更喜欢有针对性的(按文件名)方法,但也许可以直接杀死整个实例。

excel vba office365 sap-gui
2个回答
1
投票

我有一段代码,它返回所有正在运行的 Excel 实例的集合。您可以循环访问每个返回实例中的工作簿,并决定需要关闭哪些实例和/或退出哪些实例。

来源:启动了多个 Excel 实例,如何获取所有这些实例的应用程序对象?

'(32-bit)
Declare Function AccessibleObjectFromWindow Lib "oleacc" ( _
    ByVal hwnd As Long, ByVal dwId As Long, riid As Any, ppvObject As Object) As Long

Declare Function FindWindowExA Lib "user32" ( _
    ByVal hwndParent As Long, ByVal hwndChildAfter As Long, _
    ByVal lpszClass As String, ByVal lpszWindow As String) As Long


Sub Tester()
    Dim col As Collection, xl As Object, wb As Object
    
    Set col = GetExcelInstances()
    Debug.Print col.count & " instance(s) of Excel found"
    
    For Each xl In col
        Debug.Print "----------------------"
        Debug.Print "Instance " & xl.hwnd & " workbooks:"
        For Each wb In xl.Workbooks
            Debug.Print , wb.Name
        Next wb
    Next xl
End Sub

'return a collection of all open Excel instances
Private Function GetExcelInstances() As Collection
    Dim guid&(0 To 3), acc As Object, hwnd, hwnd2, hwnd3
    guid(0) = &H20400
    guid(1) = &H0
    guid(2) = &HC0
    guid(3) = &H46000000
    Dim AlreadyThere As Boolean
    Dim xl As Application
    Set GetExcelInstances = New Collection
    Do
        hwnd = FindWindowExA(0, hwnd, "XLMAIN", vbNullString)
        If hwnd = 0 Then Exit Do
        hwnd2 = FindWindowExA(hwnd, 0, "XLDESK", vbNullString)
        hwnd3 = FindWindowExA(hwnd2, 0, "EXCEL7", vbNullString)
        If AccessibleObjectFromWindow(hwnd3, &HFFFFFFF0, guid(0), acc) = 0 Then
            AlreadyThere = False
            For Each xl In GetExcelInstances
                If xl Is acc.Application Then
                    AlreadyThere = True
                    Exit For
                End If
            Next
            If Not AlreadyThere Then
                GetExcelInstances.Add acc.Application
            End If
        End If
    Loop
End Function

0
投票

只需简单的代码,您就可以关闭Excel的所有实例。请注意,包含以下代码的活动工作簿也将被关闭。

Sub CloseAllExcelProcesses()
    Dim objExcel As Object
    For Each objExcel In GetObject("winmgmts:").ExecQuery("Select * from Win32_Process Where Name = 'EXCEL.EXE'")
        objExcel.Terminate
    Next objExcel
End Sub
© www.soinside.com 2019 - 2024. All rights reserved.