反复尝试使用关键字(VBA Access)查找文件夹中的文件
我正在创建一个vba access应用程序,该应用程序带有一个下拉框组合历史记录,使用户能够从名为“扫描工单(归档)”的主文件夹中的子文件夹启动.pdf文件。我想做的是使用一个称为“M”号的特定数字(M号,因为每个数字都以M ex:M765196开头)来查找此文件,而不使用特定的子文件夹。到目前为止,我有:反复尝试使用关键字(VBA Access)查找文件夹中的文件,vba,recursion,directory,Vba,Recursion,Directory,我正在创建一个vba access应用程序,该应用程序带有一个下拉框组合历史记录,使用户能够从名为“扫描工单(归档)”的主文件夹中的子文件夹启动.pdf文件。我想做的是使用一个称为“M”号的特定数字(M号,因为每个数字都以M ex:M765196开头)来查找此文件,而不使用特定的子文件夹。到目前为止,我有: Dim fso、oFolder、oSubfolder、oFile、队列作为集合 Set fso = CreateObject("Scripting.FileSystemObject") S
Dim fso、oFolder、oSubfolder、oFile、队列作为集合
Set fso = CreateObject("Scripting.FileSystemObject")
Set queue = New Collection
queue.Add fso.GetFolder("T:\Scanned Work Orders (Archives)")
Do While queue.Count > 0
Set oFolder = queue(1)
queue.Remove 1 'dequeue
If oFile = Combo_History.Value Then
Application.FollowHyperlink ("T:\Scanned Work Orders (Archives)" & oFile)
End If
For Each oSubfolder In oFolder.SubFolders
queue.Add oSubfolder 'enqueue
Next oSubfolder
For Each oFile In oFolder.Files
If oFile = Combo_History.Value Then
Application.FollowHyperlink ("T:\Scanned Work Orders (Archives)" & oFile)
End If
Next oFile
Loop
问题是它陷入无限循环,因为它找不到关键字名为M765196的.pdf,即使它在该文件夹中。我有什么遗漏吗?或者更容易找到.pdf文件?在查找文件时,循环设置不太适合递归。下面的代码应该适合您 另外,您正在为文件系统对象使用后期绑定,这是非常好的。但是声明它们的方式会导致它们都作为变量进行计算。这可能是一件痛苦的事情,但最好将每个变量
Dim
作为单独的行分开,并准确地指定它应该是什么类型
选项显式
子测试()
作为对象的Dim fso
将根文件夹设置为字符串
将文件名设置为字符串
将完整路径设置为字符串
设置fso=CreateObject(“Scripting.FileSystemObject”)
rootFolder=“C:\Users\user\Documents”
filename=“testfile.txt”
fullpath=FindFile(fso、根文件夹、文件名)
打印“文件是”;
如果Len(完整路径)>0,则
Debug.Print“FOUND!:”&完整路径
其他的
Debug.Print“找不到。自己去找吧!”
如果结束
端接头
函数FindFile(fso作为对象,thisFolder作为字符串,filename作为字符串)作为字符串
On Error GoTo Error_FindFile
将fullFilePath设置为字符串
作为对象的文件夹的尺寸
将oSubfolder作为对象
文件夹集=fso.GetFolder(thisFolder)
“---首先检查文件是否在当前文件夹中
fullFilePath=oFolder.Path&“\”文件名
如果存在fso.filepath(fullFilePath),则
---我们完了,这里没什么可做的了
其他的
“---该文件不在此文件夹中,请检查所有子文件夹并在其中搜索
fullFilePath=“”
对于oFolder.SubFolders中的每个oSubfolder
Debug.Print“looking in”&oSubfolder.Path
如果FindFile(fso,oSubfolder.Path,filename)“,则
“---找到了文件,因此返回完整路径
fullFilePath=oSubfolder.Path&“\”文件名
退出
如果结束
下一个oSubfolder
如果结束
退出查找文件:
FindFile=fullFilePath
退出功能
错误\u查找文件:
“---我们可能会收到大部分权限错误,因此只需跳过(或记录,或打印)
'权限错误并继续
如果错误编号=70,则
Debug.Print“权限错误”&oSubfolder.Path
如果结束
转到出口_FindFile
端函数
在查找文件时,循环设置不太适合递归。下面的代码应该适合您
另外,您正在为文件系统对象使用后期绑定,这是非常好的。但是声明它们的方式会导致它们都作为变量进行计算。这可能是一件痛苦的事情,但最好将每个变量Dim
作为单独的行分开,并准确地指定它应该是什么类型
选项显式
子测试()
作为对象的Dim fso
将根文件夹设置为字符串
将文件名设置为字符串
将完整路径设置为字符串
设置fso=CreateObject(“Scripting.FileSystemObject”)
rootFolder=“C:\Users\user\Documents”
filename=“testfile.txt”
fullpath=FindFile(fso、根文件夹、文件名)
打印“文件是”;
如果Len(完整路径)>0,则
Debug.Print“FOUND!:”&完整路径
其他的
Debug.Print“找不到。自己去找吧!”
如果结束
端接头
函数FindFile(fso作为对象,thisFolder作为字符串,filename作为字符串)作为字符串
On Error GoTo Error_FindFile
将fullFilePath设置为字符串
作为对象的文件夹的尺寸
将oSubfolder作为对象
文件夹集=fso.GetFolder(thisFolder)
“---首先检查文件是否在当前文件夹中
fullFilePath=oFolder.Path&“\”文件名
如果存在fso.filepath(fullFilePath),则
---我们完了,这里没什么可做的了
其他的
“---该文件不在此文件夹中,请检查所有子文件夹并在其中搜索
fullFilePath=“”
对于oFolder.SubFolders中的每个oSubfolder
Debug.Print“looking in”&oSubfolder.Path
如果FindFile(fso,oSubfolder.Path,filename)“,则
“---找到了文件,因此返回完整路径
fullFilePath=oSubfolder.Path&“\”文件名
退出
如果结束
下一个oSubfolder
如果结束
退出查找文件:
FindFile=fullFilePath
退出功能
错误\u查找文件:
“---我们可能会收到大部分权限错误,因此只需跳过(或记录,或打印)
'权限错误并继续
如果错误编号=70,则
Debug.Print“权限错误”&oSubfolder.Path
如果结束
转到出口_FindFile
端函数
我在这里添加了第二个答案,因为通配符的求解与原始答案的差异比我预期的要大
使用通配符搜索文件并不困难,但它会带来一些影响,例如返回结果列表而不是单个结果。此外,幸运的是,我在我的一个子文件夹上遇到了权限错误,这使我思考如何处理这种情况
选项显式
Private recurseDepth作为整数
子测试()
将根文件夹设置为字符串
将文件名设置为字符串
Dim resultFiles()作为字符串
作为整数的Dim i
rootFolder=“C:\Temp”
filename=“*.pdf”
如果FindFile(根文件夹、文件名、结果文件)>0,则
Sub Macro1()
Dim colFiles As New Collection
RecursiveDir colFiles, "C:\Photos\", "*.jpg", True
Dim vFile As Variant
For Each vFile In colFiles
Debug.Print vFile
Next vFile
End Sub
Public Function RecursiveDir(colFiles As Collection, _
strFolder As String, _
strFileSpec As String, _
bIncludeSubfolders As Boolean)
Dim strTemp As String
Dim colFolders As New Collection
Dim vFolderName As Variant
'Add files in strFolder matching strFileSpec to colFiles
strFolder = TrailingSlash(strFolder)
strTemp = Dir(strFolder & strFileSpec)
Do While strTemp <> vbNullString
colFiles.Add strFolder & strTemp
strTemp = Dir
Loop
If bIncludeSubfolders Then
'Fill colFolders with list of subdirectories of strFolder
strTemp = Dir(strFolder, vbDirectory)
Do While strTemp <> vbNullString
If (strTemp <> ".") And (strTemp <> "..") Then
If (GetAttr(strFolder & strTemp) And vbDirectory) <> 0 Then
colFolders.Add strTemp
End If
End If
strTemp = Dir
Loop
'Call RecursiveDir for each subfolder in colFolders
For Each vFolderName In colFolders
Call RecursiveDir(colFiles, strFolder & vFolderName, strFileSpec, True)
Next vFolderName
End If
End Function
Public Function TrailingSlash(strFolder As String) As String
If Len(strFolder) > 0 Then
If Right(strFolder, 1) = "\" Then
TrailingSlash = strFolder
Else
TrailingSlash = strFolder & "\"
End If
End If
End Function
Public Function FindFiles( _
ByVal startFolder As String, _
ByVal fileSpec As String, _
ByRef fileList() As String, _
Optional ByVal subFolders As Boolean = True, _
Optional ByVal fullPath As Boolean = True) _
As Long
'--- starts in the given folder and checks all files against the filespec.
' the filespec MAY HAVE A WILDCARD specified, so the function returns
' an array of files with or withour full pathnames (strings) to each file that matches
' Parameters: startFolder - string containing a full path to the root
' folder for the search
' fileSpec - string containing a single filename to
' search for, --or--
' string containing a wildcard string of
' files to search for
' (result==>)fileList - an array of strings, each will be a full
' path to a file matching the input filespec
' subFolders - include subfolders in startFolder
' fullPath - true=>fullFile path; false=>fileName only
' Returns: (integer) count of the files found that match the filespec
Dim fullFilePath As String
Dim Path As String
Static fso As FileSystemObject
Static pathCollection As Collection
Dim oFile As file
Dim oFolder As Folder
Dim oSubfolder As Folder
On Error GoTo Error_FindFile
'--- first time through, set up the working objects
If recurseDepth = 0 Then
Set fso = New FileSystemObject ' CreateObject("Scripting.FileSystemObject")
Set pathCollection = New Collection
End If
recurseDepth = recurseDepth + 1
'--- focus on the given folder
Set oFolder = fso.GetFolder(startFolder)
'--- first test if we have permissions to access the folder and
' if there are any files in the folder
On Error Resume Next
If oFolder.files.Count > 0 Or oFolder.subFolders.Count > 0 Then
If Err.Number = 0 Then
'--- loop through all items in the folder. some are files and
' some are folders -- use recursion to search the subfolders
If fullPath Then
Path = oFolder.Path & "\"
Else
Path = ""
End If
For Each oFile In oFolder.files
' If oFile.name Like fileSpec Then
If LCase(oFile.name) Like LCase(fileSpec) Then
pathCollection.Add Path & oFile.name
End If
Next oFile
If subFolders Then
For Each oSubfolder In oFolder.subFolders
FindFiles oSubfolder.Path, fileSpec, fileList, subFolders, fullPath
Next oSubfolder
End If
Else
'--- if we get here it's usually a permissions error, so
' just skip this folder
Err.Clear
End If
End If
On Error GoTo Error_FindFile
Exit_FindFile:
recurseDepth = recurseDepth - 1
If (recurseDepth = 0) Then
If (pathCollection.Count > 0) Then
'--- pull the paths out of the collection and make an array, because most
' programs uses arrays more easily
ReDim fileList(1 To pathCollection.Count)
Dim i As Integer
For i = 1 To pathCollection.Count
fileList(i) = pathCollection.Item(i)
Next i
End If
FindFiles = pathCollection.Count
Set fso = Nothing
Set pathCollection = Nothing
Set oFile = Nothing
Set oFolder = Nothing
Set oSubfolder = Nothing
End If
Exit Function
Error_FindFile:
Debug.Print "Error (" & Err.Number & "): " & Err.Description & _
" on " & oSubfolder.Path
GoTo Exit_FindFile
End Function