Cod*_*375 8 excel optimization vba excel-vba filesystemobject
我需要在excel 2010中使用VBA从远程服务器上的文件夹中获取文件名集合.我有一个有效的功能,在大多数情况下它可以完成这项工作,但远程服务器经常有可怕的,可怕的网络性能问题.这意味着循环说300个文件将他们的名字放入一个集合可能需要10分钟,文件夹中的文件数量可能会增加到数千,所以这是不可行的,我需要一种方法来获取所有的文件名在单个网络请求中而不是循环.我相信它连接到占用时间的远程服务器,因此单个请求应该能够在一次通过中快速获得所有文件.
这是我目前的功能:
Private Function GetFileNames(sPath As String) As Collection
'takes a path and returns a collection of the file names in the folder
Dim oFolder As Object
Dim oFile As Object
Dim oFSO As Object
Dim colList As New Collection
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oFolder = oFSO.GetFolder(folderpath:=sPath)
For Each oFile In oFolder.Files
colList.Add oFile.Name
Next oFile
Set GetFileNames = colList
Set oFolder = Nothing
Set oFSO = Nothing
End Function
Run Code Online (Sandbox Code Playgroud)
这个很快闪电:
Sub filesTest()
Dim x() As String
x = Function_FileList("YOUR_PATH_AND_FOLDER_NAME")
Debug.Print Join(x, vbCrLf)
End Sub
Run Code Online (Sandbox Code Playgroud)
哪个叫这个功能:
Function Function_FileList(FolderLocation As String)
Function_FileList = Filter(Split(CreateObject("wscript.shell").exec("cmd /c Dir """ & FolderLocation & """ /b /a-d").stdout.readall, vbCrLf), ".")
End Function
Run Code Online (Sandbox Code Playgroud)
好的,我找到了一个适合我的情况的解决方案,也许其他人也会发现它很有用。该解决方案使用 Windows API,并在 1 秒或更短的时间内获取文件名,而 FSO 方法需要几分钟。它仍然涉及一个循环,所以我不确定为什么它这么快,但确实如此。
这采用类似“c:\windows\”的路径并返回该文件夹中所有文件(和目录)的集合。我使用的确切参数需要 Windows 7 或更高版本,请参阅声明中的注释。
'for windows API call to FindFirstFileEx
Private Const INVALID_HANDLE_VALUE = -1
Private Const MAX_PATH = 260
Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
Private Type WIN32_FIND_DATA
dwFileAttributes As Long
ftCreationTime As FILETIME
ftLastAccessTime As FILETIME
ftLastWriteTime As FILETIME
nFileSizeHigh As Long
nFileSizeLow As Long
dwReserved0 As Long
dwReserved1 As Long
cFileName As String * MAX_PATH
cAlternate As String * 14
End Type
Private Const FIND_FIRST_EX_CASE_SENSITIVE As Long = 1
'MSDN: "This value is not supported until Windows Server 2008 R2 and Windows 7."
Private Const FIND_FIRST_EX_LARGE_FETCH As Long = 2
Private Enum FINDEX_SEARCH_OPS
FindExSearchNameMatch
FindExSearchLimitToDirectories
FindExSearchLimitToDevices
End Enum
Private Enum FINDEX_INFO_LEVELS
FindExInfoStandard
FindExInfoBasic 'MSDN: "This value is not supported until Windows Server 2008 R2 and Windows 7."
FindExInfoMaxInfoLevel
End Enum
Private Declare Function FindFirstFileEx Lib "kernel32" Alias "FindFirstFileExA" ( _
ByVal lpFileName As String, ByVal fInfoLevelId As Long, lpFindFileData As WIN32_FIND_DATA, _
ByVal fSearchOp As Long, ByVal lpSearchFilter As Long, ByVal dwAdditionalFlags As Long) As Long
Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileA" ( _
ByVal hFindFile As Long, lpFindFileData As WIN32_FIND_DATA) As Long
Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long
Private Function GetFiles(ByVal sPath As String) As Collection
Dim fileInfo As WIN32_FIND_DATA 'buffer for file info
Dim hFile As Long 'file handle
Dim colFiles As New Collection
sPath = sPath & "*.*"
hFile = FindFirstFileEx(sPath & vbNullChar, FindExInfoBasic, fileInfo, FindExSearchNameMatch, 0&, FIND_FIRST_EX_LARGE_FETCH)
If hFile <> INVALID_HANDLE_VALUE Then
Do While FindNextFile(hFile, fileInfo)
colFiles.Add Left(fileInfo.cFileName, InStr(fileInfo.cFileName, vbNullChar) - 1)
Loop
FindClose hFile
End If
Set GetFiles = colFiles
End Function
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4266 次 |
最近记录: |