简体   繁体   English

如何从VBA打开Windows资源管理器中的文件夹?

[英]How to open a folder in Windows Explorer from VBA?

I want to click a button on my access form that opens a folder in Windows Explorer.我想单击我的访问表单上的一个按钮,以在 Windows Explorer 中打开一个文件夹。

Is there any way to do this in VBA? VBA有什么办法吗?

You can use the following code to open a file location from vba. 您可以使用以下代码从vba中打开文件位置。

Dim Foldername As String
Foldername = "\\server\Instructions\"

Shell "C:\WINDOWS\explorer.exe """ & Foldername & "", vbNormalFocus

You can use this code for both windows shares and local drives. 您可以将此代码用于Windows共享和本地驱动器。

VbNormalFocus can be swapper for VbMaximizedFocus if you want a maximized view. 如果要最大化视图,可以将VbNormalFocus替换为VbMaximizedFocus。

The easiest way is 最简单的方法是

Application.FollowHyperlink [path]

Which only takes one line! 仅需一行!

Here is some more cool knowledge to go with this: 这是一些更酷的知识:

I had a situation where I needed to be able to find folders based on a bit of criteria in the record and then open the folder(s) that were found. 我遇到这样的情况,我需要能够根据记录中的一些条件查找文件夹,然后打开找到的文件夹。 While doing work on finding a solution I created a small database that asks for a search starting folder gives a place for 4 pieces of criteria and then allows the user to do criteria matching that opens the 4 (or more) possible folders that match the entered criteria. 在寻找解决方案的过程中,我创建了一个小型数据库,该数据库要求搜索起始文件夹为4条条件提供一个位置,然后允许用户进行条件匹配,从而打开与输入的4个(或更多个)可能匹配的文件夹标准。

Here is the whole code on the form: 这是表格上的整个代码:

Option Compare Database
Option Explicit

Private Sub cmdChooseFolder_Click()

    Dim inputFileDialog As FileDialog
    Dim folderChosenPath As Variant

    If MsgBox("Clear List?", vbYesNo, "Clear List") = vbYes Then DoCmd.RunSQL "DELETE * FROM tblFileList"
    Me.sfrmFolderList.Requery

    Set inputFileDialog = Application.FileDialog(msoFileDialogFolderPicker)

    With inputFileDialog
        .Title = "Select Folder to Start with"
        .AllowMultiSelect = False
        If .Show = False Then Exit Sub
        folderChosenPath = .SelectedItems(1)
    End With

    Me.txtStartPath = folderChosenPath

    Call subListFolders(Me.txtStartPath, 1)

End Sub
Private Sub cmdFindFolderPiece_Click()

    Dim strCriteria As String
    Dim varCriteria As Variant
    Dim varIndex As Variant
    Dim intIndex As Integer

    varCriteria = Array(Nz(Me.txtSerial, "Null"), Nz(Me.txtCustomerOrder, "Null"), Nz(Me.txtAXProject, "Null"), Nz(Me.txtWorkOrder, "Null"))
    intIndex = 0

    For Each varIndex In varCriteria
        strCriteria = varCriteria(intIndex)
        If strCriteria <> "Null" Then
            Call fnFindFoldersWithCriteria(TrailingSlash(Me.txtStartPath), strCriteria, 1)
        End If
        intIndex = intIndex + 1
    Next varIndex

    Set varIndex = Nothing
    Set varCriteria = Nothing
    strCriteria = ""

End Sub
Private Function fnFindFoldersWithCriteria(ByVal strStartPath As String, ByVal strCriteria As String, intCounter As Integer)

    Dim fso As New FileSystemObject
    Dim fldrStartFolder As Folder
    Dim subfldrInStart As Folder
    Dim subfldrInSubFolder As Folder
    Dim subfldrInSubSubFolder As String
    Dim strActionLog As String

    Set fldrStartFolder = fso.GetFolder(strStartPath)

'    Debug.Print "Criteria: " & Replace(strCriteria, " ", "", 1, , vbTextCompare) & " and Folder Name is " & Replace(fldrStartFolder.Name, " ", "", 1, , vbTextCompare) & " and Path is: " & fldrStartFolder.Path

    If fnCompareCriteriaWithFolderName(fldrStartFolder.Name, strCriteria) Then
'        Debug.Print "Found and Opening: " & fldrStartFolder.Name & "Because of: " & strCriteria
        Shell "EXPLORER.EXE" & " " & Chr(34) & fldrStartFolder.Path & Chr(34), vbNormalFocus
    Else
        For Each subfldrInStart In fldrStartFolder.SubFolders

            intCounter = intCounter + 1

            Debug.Print "Criteria: " & Replace(strCriteria, " ", "", 1, , vbTextCompare) & " and Folder Name is " & Replace(subfldrInStart.Name, " ", "", 1, , vbTextCompare) & " and Path is: " & fldrStartFolder.Path

            If fnCompareCriteriaWithFolderName(subfldrInStart.Name, strCriteria) Then
'                Debug.Print "Found and Opening: " & subfldrInStart.Name & "Because of: " & strCriteria
                Shell "EXPLORER.EXE" & " " & Chr(34) & subfldrInStart.Path & Chr(34), vbNormalFocus
            Else
                Call fnFindFoldersWithCriteria(subfldrInStart, strCriteria, intCounter)
            End If
            Me.txtProcessed = intCounter
            Me.txtProcessed.Requery
        Next
    End If

    Set fldrStartFolder = Nothing
    Set subfldrInStart = Nothing
    Set subfldrInSubFolder = Nothing
    Set fso = Nothing

End Function
Private Function fnCompareCriteriaWithFolderName(strFolderName As String, strCriteria As String) As Boolean

    fnCompareCriteriaWithFolderName = False

    fnCompareCriteriaWithFolderName = InStr(1, Replace(strFolderName, " ", "", 1, , vbTextCompare), Replace(strCriteria, " ", "", 1, , vbTextCompare), vbTextCompare) > 0

End Function

Private Sub subListFolders(ByVal strFolders As String, intCounter As Integer)
    Dim dbs As Database
    Dim fso As New FileSystemObject
    Dim fldFolders As Folder
    Dim fldr As Folder
    Dim subfldr As Folder
    Dim sfldFolders As String
    Dim strSQL As String

    Set fldFolders = fso.GetFolder(TrailingSlash(strFolders))
    Set dbs = CurrentDb

    strSQL = "INSERT INTO tblFileList (FilePath, FileName, FolderSize) VALUES (" & Chr(34) & fldFolders.Path & Chr(34) & ", " & Chr(34) & fldFolders.Name & Chr(34) & ", '" & fldFolders.Size & "')"
    dbs.Execute strSQL

    For Each fldr In fldFolders.SubFolders
        intCounter = intCounter + 1
        strSQL = "INSERT INTO tblFileList (FilePath, FileName, FolderSize) VALUES (" & Chr(34) & fldr.Path & Chr(34) & ", " & Chr(34) & fldr.Name & Chr(34) & ", '" & fldr.Size & "')"
        dbs.Execute strSQL
        For Each subfldr In fldr.SubFolders
            intCounter = intCounter + 1
            sfldFolders = subfldr.Path
            Call subListFolders(sfldFolders, intCounter)
            Me.sfrmFolderList.Requery
        Next
        Me.txtListed = intCounter
        Me.txtListed.Requery
    Next

    Set fldFolders = Nothing
    Set fldr = Nothing
    Set subfldr = Nothing
    Set dbs = Nothing

End Sub

Private Function TrailingSlash(varIn As Variant) As String
    If Len(varIn) > 0& Then
        If Right(varIn, 1&) = "\" Then
            TrailingSlash = varIn
        Else
            TrailingSlash = varIn & "\"
        End If
    End If
End Function

The form has a subform based on the table, the form has 4 text boxes for the criteria, 2 buttons leading to the click procedures and 1 other text box to store the string for the start folder. 该表单具有一个基于表的子表单,该表单具有4个用于条件的文本框,2个用于单击过程的按钮和1个用于存储起始文件夹字符串的其他文本框。 There are 2 text boxes that are used to show the number of folders listed and the number processed when searching them for the criteria. 有2个文本框,用于显示列出的文件夹数量和在搜索条件时处理的数量。

If I had the Rep I would post a picture... :/ 如果我有代表,我会发布图片...:/

I have some other things I wanted to add to this code but haven't had the chance yet. 我还有其他想添加到此代码中的内容,但还没有机会。 I want to have a way to store the ones that worked in another table or get the user to mark them as good to store. 我想要一种方法来存储在另一个表中工作过的那些,或者让用户将它们标记为好存储。

I can not claim full credit for all the code, I cobbled some of it together from stuff I found all around, even in other posts on stackoverflow. 我不能对所有代码都称赞,我从周围发现的东西中整理了一些代码,即使在stackoverflow上的其他帖子中也是如此。

I really like the idea of posting questions here and then answering them yourself because as the linked article says, it makes it easy to find the answer for later reference. 我真的很喜欢在这里发布问题然后自己回答的想法,因为如链接文章所述,它很容易找到答案供以后参考。

When I finish the other parts I want to add I will post the code for that too. 当我完成其他要添加的部分时,我也将发布该代码。 :) :)

Thanks to PhilHibbs comment (on VBwhatnow's answer) I was finally able to find a solution that both reuses existing windows and avoids flashing a CMD-window at the user: 多亏了PhilHibbs的评论(关于VBwhatnow的回答),我终于找到了一个既可以重用现有窗口又可以避免向用户刷新CMD窗口的解决方案:

Dim path As String
path = CurrentProject.path & "\"
Shell "cmd /C start """" /max """ & path & """", vbHide

where 'path' is the folder you want to open. 其中“路径”是您要打开的文件夹。

(In this example I open the folder where the current workbook is saved.) (在此示例中,我打开了保存当前工作簿的文件夹。)

Pros: 优点:

  • Avoids opening new explorer instances (only sets focus if window exists). 避免打开新的资源管理器实例(仅在存在窗口时设置焦点)。
  • The cmd-window is never visible thanks to vbHide. 借助vbHide,cmd窗口将永远不可见。
  • Relatively simple (does not need to reference win32 libraries). 比较简单(不需要引用win32库)。

Cons: 缺点:

  • Window maximization (or minimization) is mandatory. 窗口最大化(或最小化)是强制性的。

Explanation: 说明:

At first I tried using only vbHide. 最初,我尝试仅使用vbHide。 This works nicely... unless there is already such a folder opened, in which case the existing folder window becomes hidden and disappears! 效果很好...除非已经打开了这样一个文件夹,否则现有文件夹窗口将被隐藏并消失! You now have a ghost window floating around in memory and any subsequent attempt to open the folder after that will reuse the hidden window - seemingly having no effect. 现在,您将在内存中浮动一个幻影窗口,此后任何随后尝试打开该文件夹的尝试都会重用隐藏的窗口-似乎没有任何作用。

In other words when the 'start'-command finds an existing window the specified vbAppWinStyle gets applied to both the CMD-window and the reused explorer window. 换句话说,当“start'-命令找到指定vbAppWinStyle被应用到CMD-窗口和重新使用浏览器窗口现有的窗口。 (So luckily we can use this to un-hide our ghost-window by calling the same command again with a different vbAppWinStyle argument.) (因此,幸运的是,可以通过使用不同的vbAppWinStyle参数再次调用同一命令来取消隐藏窗口。)

However by specifying the /max or /min flag when calling 'start' it prevents the vbAppWinStyle set on the CMD window from being applied recursively. 但是,通过在调用“开始”时指定/ max或/ min标志,可以防止在CMD窗口上设置的vbAppWinStyle递归应用。 (Or overrides it? I don't know what the technical details are and I'm curious to know exactly what the chain of events is here.) (或覆盖它?我不知道技术细节是什么,我很好奇确切地知道这里的事件链是什么。)

Here is what I did. 这是我所做的。

Dim strPath As String
strPath = "\\server\Instructions\"    
Shell "cmd.exe /c start """" """ & strPath & """", vbNormalFocus

Pros: 优点:

  • Avoids opening new explorer instances (only sets focus if window exists). 避免打开新的资源管理器实例(仅在存在窗口时设置焦点)。
  • Relatively simple (does not need to reference win32 libraries). 比较简单(不需要引用win32库)。
  • Window maximization (or minimization) is not mandatory. 窗口最大化(或最小化) 不是强制性的。 Window will open with normal size. 窗口将以正常大小打开。

Cons: 缺点:

  • The cmd-window is visible for a short time. 该cmd窗口在短时间内可见。

This consistently opens a window to the folder if there is none open and switches to the open window if there is one open to that folder. 如果没有打开该文件夹,则始终打开该文件夹的窗口;如果该文件夹没有打开,则切换到打开的窗口。

Thanks to PhilHibbs and AnorZaken for the basis for this. 感谢PhilHibbs和AnorZaken为这一基础。 PhilHibbs comment didn't quite work for me, I needed to the command string to have a pair of double quotes before the folder name. PhilHibbs的注释对我来说不太有效,我需要在命令字符串中的文件夹名称前加上双引号。 And I preferred having a command prompt window appear for a bit rather than be forced to have the Explorer window maximized or minimized. 而且我更喜欢让命令提示符窗口出现一点,而不是被迫最大化或最小化资源管理器窗口。

Shell "C:\WINDOWS\explorer.exe /select,""" & ActiveWorkbook.Name & "", vbNormalFocus Shell "C:\WINDOWS\explorer.exe /select,""" & ActiveWorkbook.Name & "", vbNormalFocus

Here's an answer that gives the switch-or-launch behaviour of Start, without the Command Prompt window. 这是一个给出“开始”的切换或启动行为的答案,而没有“命令提示符”窗口。 It does have the drawback that it can be fooled by an Explorer window that has a folder of the same name elsewhere opened. 它确实具有一个缺点,即可以被在其他位置打开了同名文件夹的资源管理器窗口欺骗。 I might fix that by diving into the child windows and looking for the actual path, I need to figure out how to navigate that. 我可能会通过进入子窗口并寻找实际路径来解决此问题,我需要弄清楚如何进行导航。

Usage (requires "Windows Script Host Object Model" in your project's References): 用法(需要项目参考中的“ Windows脚本宿主对象模型”):

Dim mShell As wshShell

mDocPath = whatever_path & "\" & lastfoldername
mExplorerPath = mShell.ExpandEnvironmentStrings("%SystemRoot%") & "\Explorer.exe"

If Not SwitchToFolder(lastfoldername) Then
    Shell PathName:=mExplorerPath & " """ & mDocPath & """", WindowStyle:=vbNormalFocus
End If

Module: 模块:

Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" _
(ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _
(ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
(ByVal hWnd As Long, ByVal lpString As String, ByVal cch As Long) As Long
Private Declare Function BringWindowToTop Lib "user32" _
(ByVal lngHWnd As Long) As Long

Function SwitchToFolder(pFolder As String) As Boolean

Dim hWnd As Long
Dim mRet As Long
Dim mText As String
Dim mWinClass As String
Dim mWinTitle As String

    SwitchToFolder = False

    hWnd = FindWindowEx(0, 0&, vbNullString, vbNullString)
    While hWnd <> 0 And SwitchToFolder = False
        mText = String(100, Chr(0))
        mRet = GetClassName(hWnd, mText, 100)
        mWinClass = Left(mText, mRet)
        If mWinClass = "CabinetWClass" Then
            mText = String(100, Chr(0))
            mRet = GetWindowText(hWnd, mText, 100)
            If mRet > 0 Then
                mWinTitle = Left(mText, mRet)
                If UCase(mWinTitle) = UCase(pFolder) Or _
                   UCase(Right(mWinTitle, Len(pFolder) + 1)) = "\" & UCase(pFolder) Then
                    BringWindowToTop hWnd
                    SwitchToFolder = True
                End If
            End If
        End If
        hWnd = FindWindowEx(0, hWnd, vbNullString, vbNullString)
    Wend

End Function

Private Sub Command0_Click() 私人子Command0_Click()

Application.FollowHyperlink "D:\\1Zsnsn\\SusuBarokah\\20151008 Inventory.mdb" Application.FollowHyperlink“ D:\\ 1Zsnsn \\ SusuBarokah \\ 20151008 Inventory.mdb”

End Sub 结束子

I may not use shell command because of security in the company so the best way I found on internet. 由于公司的安全性,我可能不使用shell命令,所以这是我在Internet上找到的最佳方法。

Sub OpenFileOrFolderOrWebsite() 
'Shows how to open files and / or folders and / or websites / or create    emails using the FollowHyperlink method
Dim strXLSFile As String, strPDFFile As String, strFolder As String, strWebsite As String 
Dim strEmail As String, strSubject As String, strEmailHyperlink As     String 

strFolder = "C:\Test Files\" 
strXLSFile = strFolder & "Test1.xls" 
strPDFFile = strFolder & "Test.pdf" 
strWebsite = "http://www.blalba.com/" 

strEmail = "mailto:YourEmailHere@Website.com" 
strSubject = "?subject=Test" 
strEmailHyperlink = strEmail & strSubject 

 '**************FEEL FREE TO COMMENT ANY OF THESE TO TEST JUST ONE ITEM*********
 'Open Folder
ActiveWorkbook.FollowHyperlink Address:=strFolder, NewWindow:=True 
 'Open excel workbook
ActiveWorkbook.FollowHyperlink Address:=strXLSFile, NewWindow:=True 
 'Open PDF file
ActiveWorkbook.FollowHyperlink Address:=strPDFFile, NewWindow:=True 
 'Open VBAX
ActiveWorkbook.FollowHyperlink Address:=strWebsite, NewWindow:=True 
 'Create New Email
ActiveWorkbook.FollowHyperlink Address:=strEmailHyperlink, NewWindow:=True 
 '******************************************************************************
End Sub 

so actually its 所以实际上它

strFolder = "C:\Test Files\"

and

ActiveWorkbook.FollowHyperlink Address:=strFolder, NewWindow:=True 

I just used this and it works fine: 我只是用这个,它工作正常:

System.Diagnostics.Process.Start("C:/Users/Admin/files"); System.Diagnostics.Process.Start(“ C:/ Users / Admin / files”);

Thanks to many of the answers above and elsewhere, this was my solution to a similar problem to the OP. 由于上面和其他地方的许多答案,这是我对与OP类似问题的解决方案。 The problem for me was creating a button in Word that asks the user for a network address, and pulls up the LAN resources in an Explorer window. 我的问题是在Word中创建一个按钮,该按钮要求用户提供网络地址,并在资源管理器窗口中拉出LAN资源。

Untouched, the code would take you to \\\\10.1.1.1\\Test, so edit as you see fit. 原始代码不会带您进入\\\\10.1.1.1\\Test,因此请根据需要进行编辑。 I'm just a monkey on a keyboard, here, so all comments and suggestions are welcome. 我只是键盘上的猴子,在这里,欢迎提出所有意见和建议。

Private Sub CommandButton1_Click()
    Dim ipAddress As Variant
    On Error GoTo ErrorHandler

    ipAddress = InputBox("Please enter the IP address of the network resource:", "Explore a network resource", "\\10.1.1.1")
    If ipAddress <> "" Then
        ThisDocument.FollowHyperlink ipAddress & "\Test"
    End If

    ExitPoint:
        Exit Sub

    ErrorHandler:
        If Err.Number = "4120" Then
            GoTo ExitPoint
        ElseIf Err.Number = "4198" Then
            MsgBox "Destination unavailable"
            GoTo ExitPoint
        End If

        MsgBox "Error " & Err.Number & vbCrLf & Err.Description
        Resume ExitPoint

End Sub

You can use command prompt to open explorer with path. 您可以使用命令提示符打开带有路径的资源管理器。

here example with batch or command prompt: 这是批处理或命令提示符的示例:

start "" explorer.exe (path)

so In VBA ms.access you can write with: 因此,在VBA ms.access中,您可以编写:

Dim Path
Path="C:\Example"
shell "cmd /c start """" explorer.exe " & Path ,vbHide

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 VBA在Windows资源管理器而不是Internet Explorer中打开Sharepoint文件夹 - VBA to open Sharepoint folder in Windows Explorer, not Internet Explorer 在Access中,如何打开仅知道部分文件夹名称的Windows资源管理器文件夹? - From Access, how do I open a Windows Explorer folder knowing only part of the folder name? 访问 VBA,打开 windows 文件夹并过滤内容 - Access VBA, open a windows folder and filter the contents VBA - 如何在不知道全名的情况下打开文件夹 - VBA - How to open folder without knowing the full name Windows 资源管理器由 VBA 打开 Shell 命令不在最前面 - Windows Explorer Opened by VBA Shell Command Not On Top 在VBA(msaccess)中,当我具有unicode文件夹/文件名时如何使用默认程序打开文件 - in VBA (msaccess) , how to open a file with default program when I have unicode folder/file names 如何从 MS Access vba 打开 localhost - How do I open localhost from MS Access vba 如何在 Word 宏中从 VBA 打开访问数据库 - How to open an access database from the VBA in a Word Macro 根据名称查找和打开文件夹的 VBA 代码 - VBA code to find and open a folder based on its name 有没有办法在 MS Access 中使用 VBA 从 Internet Explorer 检索变量? - Is there a way to retrieve a variable from internet explorer using VBA in MS Access?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM