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

时间:2012-06-26 10:49:04

标签: ms-access vba

我想点击访问表单上的一个按钮,在Windows资源管理器中打开一个文件夹。

有没有办法在VBA中执行此操作?

11 个答案:

答案 0 :(得分:38)

您可以使用以下代码从vba打开文件位置。

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

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

您可以将此代码用于Windows共享和本地驱动器。

如果你想要一个最大化的视图,VbNormalFocus可以是VbMaximizedFocus的交换器。

答案 1 :(得分:15)

最简单的方法是

Application.FollowHyperlink [path]

只需要一行!

答案 2 :(得分:7)

以下是一些更酷的知识:

我遇到的情况是,我需要能够根据记录中的一些条件找到文件夹,然后打开找到的文件夹。在寻找解决方案的过程中,我创建了一个小型数据库,要求搜索起始文件夹为4条条件提供一个位置,然后允许用户进行标准匹配,打开与输入的匹配的4个(或更多)可能的文件夹标准。

以下是表单上的完整代码:

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

表单有一个基于表格的子表单,表单有4个标准文本框,2个按钮指向单击过程,另外1个文本框存储开始文件夹的字符串。有2个文本框用于显示列出的文件夹数和搜索条件时处理的数字。

如果我有Rep,我会张贴一张照片......:/

我还有其他一些我想添加到此代码中的东西,但还没有机会。我想有办法存储在另一个表中工作的那些或让用户将它们标记为存储的好。

我无法完全承认所有代码,我将其中的一些内容从我发现的东西中拼凑出来,即使是在stackoverflow上的其他帖子中也是如此。

我非常喜欢在这里发布问题然后自己回答问题的想法,因为正如链接文章所说,它可以很容易地找到答案供以后参考。

当我完成其他要添加的部分时,我也会发布代码。 :)

答案 3 :(得分:6)

感谢PhilHibbs的评论(关于VBwhatnow的回答)我终于找到了一个解决方案,它既可以重用现有的窗口,又可以避免在用户处闪烁CMD窗口:

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

其中&#39;路径&#39;是您要打开的文件夹。

(在本例中,我打开保存当前工作簿的文件夹。)

<强>优点:

  • 避免打开新的资源管理器实例(仅在窗口存在时设置焦点)。
  • 由于vbHide,cmd窗口从不可见。
  • 相对简单(不需要引用win32库)。

<强>缺点:

  • 窗口最大化(或最小化)是强制性的。

说明:

起初我尝试过只使用vbHide。这很好用......除非已经打开了这样的文件夹,在这种情况下现有的文件夹窗口变得隐藏并消失!你现在有一个鬼窗口在内存中漂浮,随后任何打开的尝试之后的文件夹将重用隐藏的窗口 - 看似没有效果。

换句话说,当&#39; start&#39; -command找到现有窗口时,指定的vbAppWinStyle将应用于两者 CMD窗口和重用的资源管理器窗口。 (幸运的是,我们可以使用它来通过使用不同的vbAppWinStyle参数再次调用相同的命令来取消隐藏我们的ghost窗口。)

但是,通过在调用&#39; start&#39;时指定/ max或/ min标志。它可以防止在CMD窗口上设置的vbAppWinStyle被递归应用。 (或者覆盖它?我不知道技术细节是什么,我很想知道这里的事件链是什么。)

答案 4 :(得分:2)

这就是我所做的。

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

<强>优点:

  • 避免打开新的资源管理器实例(仅在窗口时设置焦点 存在)。
  • 相对简单(不需要引用win32库)。
  • 窗口最大化(或最小化)必需。窗口将以正常尺寸打开。

<强>缺点:

  • cmd窗口可以在短时间内看到。

如果没有打开文件夹,这将始终打开文件夹的窗口,如果有一个文件夹打开,则会切换到打开的窗口。

感谢PhilHibbs和AnorZaken的基础。 PhilHibbs评论对我来说不太合适,我需要命令字符串在文件夹名称之前有一对双引号。我更喜欢让命令提示窗口显示一点,而不是强制让Explorer窗口最大化或最小化。

答案 5 :(得分:0)

这是一个答案,它给出了Start的切换或启动行为,没有命令提示符窗口。它确实有一个缺点,它可以被一个资源管理器窗口所欺骗,该窗口在其他地方打开了一个同名文件夹。我可以通过潜入子窗口并寻找实际路径来解决这个问题,我需要弄清楚如何导航。

用法(在项目的参考中需要“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

模块:

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

答案 6 :(得分:0)

Private Sub Command0_Click()

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

End Sub

答案 7 :(得分:0)

由于公司的安全性,我可能不会使用shell命令,这是我在互联网上找到的最佳方式。

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 

实际上是它的

strFolder = "C:\Test Files\"

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

答案 8 :(得分:0)

我刚使用过它并且工作正常:

System.Diagnostics.Process.Start(&#34; C:/用户/管理员/文件&#34);

答案 9 :(得分:0)

感谢上面和其他地方的许多答案,这是我对OP的类似问题的解决方案。对我来说,问题是在Word中创建一个按钮,要求用户输入网络地址,并在资源管理器窗口中提取LAN资源。

未触及,代码会将您带到\\10.1.1.1\Test,,以便根据需要进行编辑。我只是一个键盘上的猴子,所以欢迎所有意见和建议。

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

答案 10 :(得分:0)

您可以使用命令提示符以路径打开资源管理器。

此处包含批处理或命令提示符的示例:

start "" explorer.exe (path)

所以在VBA ms.access中你可以写:

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