Excel VBA - 从多个打开的文件资源管理器窗口中关闭特定的文件资源管理器窗口

Posted

技术标签:

【中文标题】Excel VBA - 从多个打开的文件资源管理器窗口中关闭特定的文件资源管理器窗口【英文标题】:Excel VBA - Closing a specific File Explorer window out of multiple open File Explorer windows 【发布时间】:2018-09-14 14:30:23 【问题描述】:

单元格 A3 包含文件夹路径。下面的单元格包含带有扩展名的文件名。选择下面的单元格后,我的 Excel 宏会在文件资源管理器中打开该文件的位置,并在该文件夹中的多个文件中选择这个特定的文件,可以在预览中看到。在电子表格中选择包含另一个文件名的下一个单元格时,将打开另一个文件资源管理器窗口,即使它与 A3 的路径相同。寻找要添加的代码行,它将首先关闭第一个文件资源管理器窗口,然后再打开一个新窗口。代码需要从多个打开的文件资源管理器窗口中关闭单元格 A3 中的特定文件资源管理器窗口。我到目前为止的代码

更新:运行下面的代码,但它不会关闭现有打开的文件夹,只是打开另一个:

If Target.Column = 1 And Target.Row > 5 Then

Call CloseWindow

Shell "C:\Windows\explorer.exe /select," & Range("A3") & ActiveCell(1, 1).Value, vbNormalFocus 'this works, but opens NEW folder every time

在单独的模块中:

'BELOW GOES WITH Public Sub CloseWindow() FROM: https://***.com/questions/49649663/close-folder-opened-through-explorer-exe
Option Explicit

''for 64-bit Excel use
'Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" _
'    (ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Long) As LongPtr
''for 32-bit Excel use
'Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
'    (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long

'To make it compatible with both 64 and 32 bit Excel you can use
#If VBA7 Then
    Private Declare PtrSafe Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal hWnd As LongPtr, ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Long) As LongPtr
#Else
    Private Declare Function SendMessage Lib "user32" Alias "SendMessageA" _
        (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Long) As Long
#End If
'Note that one of these will be marked in red as compile error but the code will still run.


Const WM_SYSCOMMAND = &H112
Const SC_CLOSE = &HF060

Public Sub CloseWindow()
    Dim sh As Object
    Set sh = CreateObject("shell.application")

    Dim w As Variant
    For Each w In sh.Windows
        'print all locations in the intermediate window
        Debug.Print w.LocationURL

        ' select correct shell window by LocationURL
'        If w.LocationURL = "file://sharepoint.com@SSL/DavWWWRoot/sites/folder" Then
        'If w.LocationURL = "Range("M1").value" Then
        If w.LocationURL = "file://K:/ppp/xx/yy/1 - zzz" Then
            SendMessage w.hWnd, WM_SYSCOMMAND, SC_CLOSE, 0
        End If
    Next w
End Sub

更新 2: 然而,我现在在想,最好的解决方案实际上可能不是关闭文件资源管理器然后打开它,而是让代码识别已经有一个打开的文件资源管理器窗口,其路径来自单元格 A3 并且既不关闭它也不要打开一个新文件,而只需选择与在已打开的文件资源管理器窗口中单击的新单元格相对应的新文件,路径来自单元格 A3。有人能想出办法吗?

【问题讨论】:

@BigBen - Shell "C:\Windows\explorer.exe /select," & Range("A3") & ActiveCell(1, 1).Value, vbNormalFocus '这工作,但打开新每次文件夹 @BigBen - 谢谢,完成 @Pᴇʜ - 你能帮忙解决这个问题吗? 【参考方案1】:

我找到了一个解决方案(不是我自己的),它针对“Win32_Process”类实现 WMI 查询。此处的代码关闭所有 explorer.exe 实例。虽然我不完全理解它,但我确实测试并发现它有效。

Sub CloseWindow()

    Dim objWMIcimv2 As Object, objProcess As Object, objList As Object
    Dim intError As Integer

    Set objWMIcimv2 = GetObject("winmgmts:impersonationLevel=impersonate!\\.\root\cimv2")
    Set objList = objWMIcimv2.ExecQuery("select * from win32_process where name='explorer.exe'")

    For Each objProcess In objList
        intError = objProcess.Terminate
        If intError <> 0 Then Exit For
    Next

    Set objWMIcimv2 = Nothing
    Set objList = Nothing
    Set objProcess = Nothing

End Sub

【讨论】:

【参考方案2】:

这将为您完成这项工作。如果文件夹没有打开它会打开它,否则它会激活它并将它带到前面。

如果您想在文件夹中选择一个文件,您应该稍微修改一下并使用oWinOpen.Quit 关闭窗口然后重新打开它。 Shell 在打开文件夹时的行为与在文件夹中选择文件时的行为完全不同。

Sub OpenFolder(strPath As String)
    
    Dim bFolderIsOpen   As Boolean
    Dim oShell          As Object
    Dim oWinOpen        As Object
    Dim Wnd             As Object
    
    Set oShell = CreateObject("Shell.Application")
    
    bFolderIsOpen = FALSE
    
    For Each Wnd In oShell.Windows
        If Wnd.Document.Folder.Self.Path = strPath Then
            Set oWinOpen = Wnd
            bFolderIsOpen = TRUE
        End If
    Next Wnd
    
    If bFolderIsOpen = FALSE Then 'open it for the first time
        Call Shell("explorer.exe" & " " & """" & strPath & """", vbNormalFocus)
    Else
        oWinOpen.Visible = FALSE
        oWinOpen.Visible = TRUE
    End If

【讨论】:

以上是关于Excel VBA - 从多个打开的文件资源管理器窗口中关闭特定的文件资源管理器窗口的主要内容,如果未能解决你的问题,请参考以下文章

Excel VBA 入门

VBA资源管理器中只有工程(project),无法展开Excel对象,而且点击excel工作表,还会自动添加project

用VBA代码打开其他excel工作簿(有打开密码的)???

Excel VBA 引用文件夹选择器 *VBA 的新功能 * [重复]

使用 VBA 从 Access 运行后从任务管理器中删除 Excel 任务

如何破解vba工程密码