branston
02-18-2021, 10:01 AM
Version 2102 MS Excel for MS 365 MSO
My file is a bit cumbersome, I've copied the FileSearch code below ... I hope that's ok?
Thanks for all your help.
'Version 2.31
'Andreas Killer
'11.04.2018
'Replica of the office FileSearch object
Option Explicit
Option Compare Text
'Set this define to False if you use Office 2003 or prior versions
#Const UseNewOfficeFileExtensions = True
'Support unicode chars in filenames, otherwise ANSI chars only
#Const UniCode = True
'This event is raised before the search goes into a subdirectory
' Set Cancel to True to skip that folder (and its subfolders)
Public Event BeforeSearchFolder(ByVal Path As String, ByRef Cancel As Boolean)
#Const FoundEvents = True
#If FoundEvents Then
'This event is raised when a file is found, set Cancel to True to skip that file
Public Event FoundFile(ByVal FullName As String, ByVal Attributes As Long, ByVal DateCreated As Date, _
ByVal DateLastAccessed As Date, ByVal DateLastModified As Date, ByVal Size As Variant, ByRef Cancel As Boolean)
'This event is raised when a folder is found, set Cancel to True to skip that folder
Public Event FoundFolder(ByVal FullName As String, ByVal Attributes As Long, ByVal DateCreated As Date, _
ByVal DateLastAccessed As Date, ByVal DateLastModified As Date, ByRef Cancel As Boolean)
#End If
' Sub Example_FileSearch()
' Dim ApplicationFileSearch As New FileSearch
' Dim FName
' With ApplicationFileSearch
' 'Setup a file mask to search for
' .FileName = "*.*"
' 'Remarks:
' 'A 3 characters long extension did not find a 4 characters long extension
' ' Means *.xlsm or *.xlsx files are not found if you search for *.xls
' ' If you want to include that files, search for "*.xls*"
' ' If you want to exclude *.xls files, search for "*.xls?"
' ' Search for *.* to find all files
' ' Search for *.*.* to find only files with a dot in the filename
' 'You can search with multiple masks at the same time if you use an array
' ' E.g. if you want to find different picture file types:
' ' .FileName = Array("*.jpg", "*.jpeg", "*.bmp", "*.gif")
' ' The .FileType property fills the .FileName property with some predefinied arrays
' ' E.g. this searches for all Excel files .FileType = msoFileTypeExcelWorkbooks
'
' 'Setup a path to search for files
' .LookIn = "C:\"
' 'Remarks:
' ' If the class is initialized or if you call .NewSearch the path is set
' ' to your personal directory, e.g. "C:\Users\UserName\Documents" on Win7
'
' 'Search through sub folders or not, the default value is False
' .SearchSubFolders = True
'
' 'If you want to find a files that you have modified, but you can't remember the filename
' ' use the .LastModified property and specify a time period
' ' The default value of this property is msoLastModifiedAnyTime
' '.LastModified = msoLastModifiedToday
'
' 'Execute the search, the number of found files are returned
' If .Execute > 0 Then
' 'Remarks:
' ' The argument AlwaysAccurate does nothing, it is only for backward compatibility
' ' The returned order of the files is unsorted by default
' ' You can sort by FileName, FileType (Extension), LastModified or Size ascending or descending
'
' 'After a successfully search, two collections are filled with the results:
' ' .FoundFiles contains all found files
' ' .FoundDirs contains all found directories
' '
' 'You can access a collection in 2 ways:
' ' Many people do an index access like this
' ' For i = 1 To .FoundFiles.Count
' ' FName = .FoundFiles(i)
' ' Next
'
' 'But a FOR EACH loop executes much faster:
' For Each FName In .FoundFiles
' 'Debug.Print FName
' Next
' End If
' End With
' End Sub
Public Enum msoSortBy
msoSortByFileName = 1
msoSortBySize = 2
msoSortByFileType = 3
msoSortByLastModified = 4
End Enum
Public Enum msoFileType
msoFileTypeAllFiles = 1
msoFileTypeOfficeFiles = 2
msoFileTypeWordDocuments = 3
msoFileTypeExcelWorkbooks = 4
msoFileTypePowerPointPresentations = 5
msoFileTypeBinders = 6
msoFileTypeDatabases = 7
msoFileTypeTemplates = 8
End Enum
Public Enum msoLastModified
msoLastModifiedYesterday = 1
msoLastModifiedToday = 2
msoLastModifiedLastWeek = 3
msoLastModifiedThisWeek = 4
msoLastModifiedLastMonth = 5
msoLastModifiedThisMonth = 6
msoLastModifiedAnyTime = 7
End Enum
Public Enum msoSortOrder
msoSortOrderAscending = 1
msoSortOrderDescending = 2
End Enum
Public SearchSubFolders As Boolean
Public FoundFiles As Collection
Public FoundDirs As Collection
Private fsFileName As Variant
Private fsFileExt As Variant
Private fsFileBase As Variant
Private fsLookIn As String
Private fsFileType As msoFileType
Private fsLastModified As msoLastModified
Private SortFiles As Collection
Private SortDirs As Collection
Private SortFilesBy As msoSortBy
Private fso As Object 'FileSystemObject
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
#If Win64 Then
#If UniCode Then
Private Declare PtrSafe Function FindFirstFileEx Lib "kernel32" Alias "FindFirstFileExW" ( _
ByVal lpFileName As LongPtr, ByVal fInfoLevelId As Long, ByVal lpFindFileData As LongPtr, _
ByVal fSearchOp As Long, ByVal lpSearchFilter As Long, ByVal dwAdditionalFlags As Long) As LongPtr
Private Declare PtrSafe Function FindNextFile Lib "kernel32" Alias "FindNextFileW" ( _
ByVal hFindFile As LongPtr, ByVal lpFindFileData As LongPtr) As Long
#Else
Private Declare PtrSafe 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 LongPtr
Private Declare PtrSafe Function FindNextFile Lib "kernel32" Alias "FindNextFileA" ( _
ByVal hFindFile As LongPtr, lpFindFileData As WIN32_FIND_DATA) As Long
#End If
Private Declare PtrSafe Function FindClose Lib "kernel32" (ByVal hFindFile As LongPtr) As Long
#Else
#If UniCode Then
Private Declare Function FindFirstFileEx Lib "kernel32" Alias "FindFirstFileExW" ( _
ByVal lpFileName As Long, ByVal fInfoLevelId As Long, ByVal lpFindFileData As Long, _
ByVal fSearchOp As Long, ByVal lpSearchFilter As Long, ByVal dwAdditionalFlags As Long) As Long
Private Declare Function FindNextFile Lib "kernel32" Alias "FindNextFileW" ( _
ByVal hFindFile As Long, ByVal lpFindFileData As Long) As Long
#Else
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
#End If
Private Declare Function FindClose Lib "kernel32" (ByVal hFindFile As Long) As Long
#End If
Private Type SYSTEMTIME
wYear As Integer
wMonth As Integer
wDayOfWeek As Integer
wDay As Integer
wHour As Integer
wMinute As Integer
wSecond As Integer
wMilliseconds As Integer
End Type
#If Win64 Then
Private Declare PtrSafe Function FileTimeToSystemTime Lib "kernel32" ( _
lpFileTime As FILETIME, lpSystemTime As SYSTEMTIME) As Long
Private Declare PtrSafe Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
lpDest As Any, lpSource As Any, ByVal nCount As Long)
#Else
Private Declare Function FileTimeToSystemTime Lib "kernel32" ( _
lpFileTime As FILETIME, lpSystemTime As SYSTEMTIME) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" ( _
lpDest As Any, lpSource As Any, ByVal nCount As Long)
#End If
'Private Type SHITEMID
' cb As Long
' abID As Byte
'End Type
'Private Type ITEMIDLIST
' mkID As SHITEMID
'End Type
'
'#If Win64 Then
'Private Declare PtrSafe Function SHGetSpecialFolderLocation Lib "Shell32" ( _
' ByVal hwndOwner As Long, ByVal nFolder As Long, ByRef ppidl As ITEMIDLIST) As Long
'Private Declare PtrSafe Function SHGetPathFromIDList Lib "Shell32" ( _
' ByVal pidList As Long, ByVal lpBuffer As String) As Long
'#Else
'Private Declare Function SHGetSpecialFolderLocation Lib "Shell32" ( _
' ByVal hwndOwner As Long, ByVal nFolder As Long, ByRef ppidl As ITEMIDLIST) As Long
'Private Declare Function SHGetPathFromIDList Lib "Shell32" ( _
' ByVal pidList As Long, ByVal lpBuffer As String) As Long
'#End If
Private IsWow64 As Boolean
#If Win64 Then
Private Declare PtrSafe Function Wow64DisableWow64FsRedirection Lib "kernel32" ( _
ByRef OldValue As Long) As Long
Private Declare PtrSafe Function Wow64RevertWow64FsRedirection Lib "kernel32" ( _
ByVal OldValue As Long) As Long
Private Declare PtrSafe Function GetModuleHandleA Lib "kernel32" ( _
ByVal lpModuleName As String) As LongPtr
Private Declare PtrSafe Function GetProcAddress Lib "kernel32" ( _
ByVal hModule As LongPtr, ByVal lpProcName As String) As LongPtr
Private Declare PtrSafe Function IsWow64Process Lib "kernel32" ( _
ByVal hProcess As LongPtr, ByRef Wow64Process As LongPtr) As Long
Private Declare PtrSafe Function GetCurrentProcess Lib "kernel32" () As LongPtr
#Else
Private Declare Function Wow64DisableWow64FsRedirection Lib "kernel32" ( _
ByRef OldValue As Long) As Long
Private Declare Function Wow64RevertWow64FsRedirection Lib "kernel32" ( _
ByVal OldValue As Long) As Long
Private Declare Function GetModuleHandleA Lib "kernel32" ( _
ByVal lpModuleName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32" ( _
ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function IsWow64Process Lib "kernel32" ( _
ByVal hProcess As Long, ByRef Wow64Process As Long) As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
#End If
Private Function DetectWow64() As Boolean
#If Win64 Then
Dim Ret As LongPtr
#Else
Dim Ret As Long
#End If
If GetProcAddress(GetModuleHandleA("kernel32.dll"), "IsWow64Process") Then
IsWow64Process GetCurrentProcess, Ret
DetectWow64 = (Ret <> 0)
End If
End Function
Private Function Path2MyDocuments() As String
' Const S_OK = 0
' Const MAX_PATH = 260
' Dim IIDL As ITEMIDLIST
' If SHGetSpecialFolderLocation(0, 5, IIDL) = S_OK Then
' Path2MyDocuments = Space$(MAX_PATH)
' If SHGetPathFromIDList(IIDL.mkID.cb, Path2MyDocuments) Then
' Path2MyDocuments = Left$(Path2MyDocuments, InStr(Path2MyDocuments, vbNullChar) - 1)
' Else
' Path2MyDocuments = ""
' End If
' End If
Dim WSHShell As Object
Set WSHShell = CreateObject("Wscript.Shell")
Path2MyDocuments = WSHShell.SpecialFolders("MyDocuments")
End Function
Private Sub Class_Initialize()
Set FoundDirs = New Collection
Set FoundFiles = New Collection
Set SortFiles = New Collection
Set SortDirs = New Collection
Set fso = CreateObject("Scripting.FileSystemObject")
FileType = msoFileTypeOfficeFiles
LastModified = msoLastModifiedAnyTime
LookIn = Path2MyDocuments
IsWow64 = DetectWow64
End Sub
Private Sub Class_Terminate()
Set FoundDirs = Nothing
Set FoundFiles = Nothing
Set SortFiles = Nothing
Set SortDirs = Nothing
Set fso = Nothing
End Sub
Public Sub NewSearch()
FileName = ""
LookIn = Path2MyDocuments
FileType = msoFileTypeOfficeFiles
LastModified = msoLastModifiedAnyTime
SearchSubFolders = False
ClearCollections
End Sub
Private Sub ClearCollections()
If FoundFiles.Count > 0 Then
Set FoundFiles = Nothing
Set FoundFiles = New Collection
Set SortFiles = Nothing
Set SortFiles = New Collection
End If
If FoundDirs.Count > 0 Then
Set FoundDirs = Nothing
Set FoundDirs = New Collection
Set SortDirs = Nothing
Set SortDirs = New Collection
End If
End Sub
Property Let FileName(Value As Variant)
If IsArray(Value) Then
fsFileName = Value
Else
fsFileName = Array(Value)
End If
fsFileType = 0
End Property
Property Get FileName() As Variant
FileName = Join(fsFileName, ", ")
End Property
Property Let FileType(Value As msoFileType)
fsFileType = Value
#If UseNewOfficeFileExtensions Then
Select Case Value
Case msoFileTypeAllFiles
fsFileName = Array("*.*")
Case msoFileTypeOfficeFiles
fsFileName = Array( _
"*.doc", "*.docm", "*.docx", "*.dot", "*.dotm", "*.dotx", _
"*.htm", "*.html", _
"*.mdb", "*.mdbm", "*.mdbx", "*.mpd", "*.mpdm", "*.mpdx", _
"*.obd", "*.obdm", "*.obdx", "*.obt", "*.obtm", "*.obtx", _
"*.pot", "*.potm", "*.potx", "*.pps", "*.ppsm", "*.ppsx", "*.ppt", "*.pptm", "*.pptx", _
"*.xls", "*.xlsm", "*.xlsx", "*.xlt", "*.xltm", "*.xltx", "*.xlsb")
Case msoFileTypeWordDocuments
fsFileName = Array("*.doc", "*.docm", "*.docx", "*.htm", "*.html")
Case msoFileTypeExcelWorkbooks
fsFileName = Array("*.xls", "*.xlsm", "*.xlsx", "*.xlsb")
Case msoFileTypePowerPointPresentations
fsFileName = Array("*.pps", "*.ppsm", "*.ppsx", "*.ppt", "*.pptm", "*.pptx")
Case msoFileTypeBinders
fsFileName = Array("*.obd", "*.obdm", "*.obdx")
Case msoFileTypeDatabases
fsFileName = Array("*.mdb", "*.mdbm", "*.mdbx", "*.mpd", "*.mpdm", "*.mpdx")
Case msoFileTypeTemplates
fsFileName = Array( _
"*.dot", "*.dotm", "*.dotx", _
"*.obt", "*.obtm", "*.obtx", _
"*.pot", "*.potm", "*.potx", _
"*.xlt", "*.xltm", "*.xltx")
Case Else
fsFileType = 0
fsFileName = Array("*.*")
End Select
#Else
Select Case Value
Case msoFileTypeAllFiles
fsFileName = Array("*.*")
Case msoFileTypeOfficeFiles
fsFileName = Array("*.doc", "*.dot", "*.htm", "*.html", "*.mdb", "*.mpd", "*.obd", "*.obt", _
"*.pot", "*.pps", "*.ppt", "*.xls", "*.xlt")
Case msoFileTypeWordDocuments
fsFileName = Array("*.doc", "*.htm", "*.html")
Case msoFileTypeExcelWorkbooks
fsFileName = Array("*.xls")
Case msoFileTypePowerPointPresentations
fsFileName = Array("*.pps", "*.ppt")
Case msoFileTypeBinders
fsFileName = Array("*.obd")
Case msoFileTypeDatabases
fsFileName = Array("*.mdb", "*.mpd")
Case msoFileTypeTemplates
fsFileName = Array("*.dot", "*.obt", "*.pot", "*.xlt")
Case Else
fsFileType = 0
fsFileName = Array("*.*")
End Select
#End If
End Property
Property Get FileType() As msoFileType
FileType = fsFileType
End Property
Property Let LastModified(Value As msoLastModified)
If Value >= 1 And Value <= 7 Then
fsLastModified = Value
Else
fsLastModified = msoLastModifiedAnyTime
End If
End Property
Property Get LastModified() As msoLastModified
LastModified = fsLastModified
End Property
Property Let LookIn(ByVal Value As String)
fsLookIn = fso.BuildPath(fso.GetAbsolutePathName(Value), "\")
End Property
Property Get LookIn() As String
LookIn = fsLookIn
End Property
Private Function MakeDecimal(ByVal Lo As Long, ByVal Hi As Long, _
Optional ByVal wEx As Long = 0, _
Optional Minus As Boolean = False) As Variant
If Minus Then MakeDecimal = CDec(-1) Else MakeDecimal = CDec(1)
CopyMemory ByVal VarPtr(MakeDecimal) + 8, Lo, 4
CopyMemory ByVal VarPtr(MakeDecimal) + 12, Hi, 4
If wEx <> 0 Then CopyMemory ByVal VarPtr(MakeDecimal) + 4, Lo, 4
End Function
Private Function FirstWeek(ByVal Datum As Date) As Date
'Liefert den 1. Tag der Woche in dem Datum liegt
FirstWeek = Datum - Weekday(Datum, vbUseSystemDayOfWeek) + 1
End Function
Private Sub SearchPrim(ByVal Path As String)
#If Win64 Then
Dim hFindFile As LongPtr
#Else
Dim hFindFile As Long
#End If
Dim hFoundFile As WIN32_FIND_DATA
Dim FName As String
Dim STime As SYSTEMTIME
Dim FTime As Date, ETime As Date, LTime As Date
Dim CTime As Date, MTime As Date, ATime As Date
Dim i As Integer, j As Long
Dim AddIt As Boolean, Cancel As Boolean
If fsLastModified <> msoLastModifiedAnyTime Then
Select Case fsLastModified
Case msoLastModifiedYesterday
ETime = Date - 1
LTime = Date - 1
Case msoLastModifiedToday
ETime = Date
LTime = Date
Case msoLastModifiedLastWeek
ETime = FirstWeek(Date) - 7
LTime = ETime + 6
Case msoLastModifiedThisWeek
ETime = FirstWeek(Date)
LTime = ETime + 6
Case msoLastModifiedLastMonth
ETime = DateSerial(Year(Date), Month(Date) - 1, 1)
LTime = DateSerial(Year(Date), Month(Date), 0)
Case msoLastModifiedThisMonth
ETime = DateSerial(Year(Date), Month(Date), 1)
LTime = DateSerial(Year(Date), Month(Date) + 1, 0)
End Select
End If
'Suche nach den Dateien
For i = LBound(fsFileName) To UBound(fsFileName)
#If UniCode Then
hFindFile = FindFirstFileEx(StrPtr(Path & fsFileName(i) & vbNullChar), _
FindExInfoStandard&, VarPtr(hFoundFile), FindExSearchNameMatch&, 0&, 0&)
#Else
hFindFile = FindFirstFileEx(Path & fsFileName(i) & vbNullChar, _
FindExInfoStandard&, hFoundFile, FindExSearchNameMatch&, 0&, 0&)
#End If
If hFindFile <> INVALID_HANDLE_VALUE Then
Do
With hFoundFile
'Die Verzeichnisse ausschließen
If (.dwFileAttributes And vbDirectory) = 0 Then
If fsLastModified = msoLastModifiedAnyTime Then
AddIt = True
Else
'Konvertiere Dateizeit zu Systemzeit
FileTimeToSystemTime .ftLastWriteTime, STime
'Generiere VBA-Datum
With STime
FTime = DateSerial(.wYear, .wMonth, .wDay)
End With
AddIt = FTime >= ETime And FTime <= LTime
End If
If AddIt Then
j = InStr(.cFileName, vbNullChar) - 1
FName = Mid$(.cFileName, 1, j)
If j - InStrRev(FName, ".") > 3 Or Len(fsFileExt(i)) > 3 Then
'Problem *.htm findet auch *.html
AddIt = fso.GetExtensionName(FName) Like fsFileExt(i) And fso.GetBaseName(FName) Like fsFileBase(i)
End If
End If
#If FoundEvents Then
If AddIt Then
FileTimeToSystemTime .ftLastAccessTime, STime
With STime
ATime = DateSerial(.wYear, .wMonth, .wDay) + TimeSerial(.wHour, .wMinute, .wSecond)
End With
FileTimeToSystemTime .ftLastWriteTime, STime
With STime
MTime = DateSerial(.wYear, .wMonth, .wDay) + TimeSerial(.wHour, .wMinute, .wSecond)
End With
FileTimeToSystemTime .ftCreationTime, STime
With STime
CTime = DateSerial(.wYear, .wMonth, .wDay) + TimeSerial(.wHour, .wMinute, .wSecond)
End With
RaiseEvent FoundFile(Path & FName, .dwFileAttributes, CTime, ATime, MTime, MakeDecimal(.nFileSizeLow, .nFileSizeHigh), AddIt)
End If
#End If
If AddIt Then
FoundFiles.Add Path & FName
'Sollen wir sortieren?
Select Case SortFilesBy
Case msoSortByFileName
'Pfad, dann Name
SortFiles.Add FName & Path
Case msoSortByFileType
'Extension, dann Pfad, dann Name
SortFiles.Add fso.GetExtensionName(FName) & Path & FName
Case msoSortByLastModified
'Konvertiere Dateizeit zu Systemzeit
FileTimeToSystemTime .ftLastWriteTime, STime
'Generiere VBA-Datum
With STime
FTime = DateSerial(.wYear, .wMonth, .wDay) + TimeSerial(.wHour, .wMinute, .wSecond)
End With
SortFiles.Add FTime
Case msoSortBySize
SortFiles.Add MakeDecimal(.nFileSizeLow, .nFileSizeHigh)
End Select
End If
Else
If fsLastModified = msoLastModifiedAnyTime Then
AddIt = True
Else
'Konvertiere Dateizeit zu Systemzeit
FileTimeToSystemTime .ftLastWriteTime, STime
'Generiere VBA-Datum
With STime
FTime = DateSerial(.wYear, .wMonth, .wDay)
End With
AddIt = FTime >= ETime And FTime <= LTime
End If
If AddIt Then
'Problem Verzeichnisse "." und ".." ausschließen, aber alle anderen zulassen (.borland)
AddIt = InStr(.cAlternate, vbNullChar) > 1
If Not AddIt Then
For j = 1 To Len(.cFileName)
Select Case Mid$(.cFileName, j, 1)
Case "."
Case vbNullChar
Exit For
Case Else
AddIt = True
Exit For
End Select
Next
End If
End If
If AddIt Then
FName = Mid$(.cFileName, 1, InStr(.cFileName, vbNullChar) - 1)
If InStr(FName, "?") > 0 Then
'Problem Verzeichnisse mit ungültigen Zeichen "??sortierte Lesezeichen"
FName = Mid$(.cAlternate, 1, InStr(.cAlternate, vbNullChar) - 1)
End If
End If
#If FoundEvents Then
If AddIt Then
FileTimeToSystemTime .ftLastAccessTime, STime
With STime
ATime = DateSerial(.wYear, .wMonth, .wDay) + TimeSerial(.wHour, .wMinute, .wSecond)
End With
FileTimeToSystemTime .ftLastWriteTime, STime
With STime
MTime = DateSerial(.wYear, .wMonth, .wDay) + TimeSerial(.wHour, .wMinute, .wSecond)
End With
FileTimeToSystemTime .ftCreationTime, STime
With STime
CTime = DateSerial(.wYear, .wMonth, .wDay) + TimeSerial(.wHour, .wMinute, .wSecond)
End With
RaiseEvent FoundFolder(Path & FName, .dwFileAttributes, CTime, ATime, MTime, AddIt)
End If
#End If
If AddIt Then
FoundDirs.Add Path & FName
'Sollen wir sortieren?
Select Case SortFilesBy
Case msoSortByFileName
'Pfad
SortDirs.Add Path & FName
Case msoSortByFileType
'Extension, dann Pfad, dann Name
SortDirs.Add fso.GetExtensionName(FName) & Path & FName
Case msoSortByLastModified
'Konvertiere Dateizeit zu Systemzeit
FileTimeToSystemTime .ftLastWriteTime, STime
'Generiere VBA-Datum
With STime
FTime = DateSerial(.wYear, .wMonth, .wDay) + TimeSerial(.wHour, .wMinute, .wSecond)
End With
SortDirs.Add FTime
Case msoSortBySize
SortDirs.Add MakeDecimal(.nFileSizeLow, .nFileSizeHigh)
End Select
End If
End If
End With
#If UniCode Then
Loop Until FindNextFile(hFindFile, VarPtr(hFoundFile)) <> 1
#Else
Loop Until FindNextFile(hFindFile, hFoundFile) <> 1
#End If
FindClose hFindFile
End If
Next
If SearchSubFolders Then
'Suche nach einem Verzeichnis
'Problem "*." findet keine Verzeichnisse die einen Punkt enthalten!
#If UniCode Then
hFindFile = FindFirstFileEx(StrPtr(Path & "*" & vbNullChar), _
FindExInfoStandard&, VarPtr(hFoundFile), FindExSearchLimitToDirectories&, 0&, 0&)
#Else
hFindFile = FindFirstFileEx(Path & "*" & vbNullChar, _
FindExInfoStandard&, hFoundFile, FindExSearchLimitToDirectories&, 0&, 0&)
#End If
If hFindFile <> INVALID_HANDLE_VALUE Then
Do
With hFoundFile
If (.dwFileAttributes And vbDirectory) > 0 Then
'Problem Verzeichnisse "." und ".." ausschließen, aber alle anderen zulassen (.borland)
AddIt = InStr(.cAlternate, vbNullChar) > 1
If Not AddIt Then
'AddIt = Left$(.cFileName, 1) <> "."
For j = 1 To Len(.cFileName)
Select Case Mid$(.cFileName, j, 1)
Case "."
Case vbNullChar
Exit For
Case Else
AddIt = True
Exit For
End Select
Next
End If
If AddIt Then
FName = Mid$(.cFileName, 1, InStr(.cFileName, vbNullChar) - 1)
If InStr(FName, "?") > 0 Then
'Problem Verzeichnisse mit ungültigen Zeichen "??sortierte Lesezeichen"
FName = Mid$(.cAlternate, 1, InStr(.cAlternate, vbNullChar) - 1)
End If
Cancel = False
RaiseEvent BeforeSearchFolder(Path & FName, Cancel)
'Starte rekursive Suche
If Not Cancel Then SearchPrim Path & FName & "\"
End If
End If
End With
#If UniCode Then
Loop Until FindNextFile(hFindFile, VarPtr(hFoundFile)) <> 1
#Else
Loop Until FindNextFile(hFindFile, hFoundFile) <> 1
#End If
FindClose hFindFile
End If
End If
End Sub
Private Sub QuickSortCollection(ByRef Liste As Collection, ByRef Data As Collection, _
Optional ByVal Compare As VbCompareMethod = vbDatabaseCompare, _
Optional ByVal SortOrder As msoSortOrder = msoSortOrderAscending)
'Sortiert eine Collection mit beliebigen Werten, führt eine zweite Collection parallel mit
Const QTHRESH As Long = 9
Dim i As Long, j As Long, C As Integer, Ci As Integer, Cj As Integer
Dim Pivot, Temp
Dim DArr(), LArr()
Dim DoResume As Boolean
Dim Stack(1 To 64) As Long
Dim StackPtr As Long
Dim Start As Long, Ende As Long
'Wir brauchen mind. 2 Elemente
If Liste.Count < 2 Then Exit Sub
'Daten aus der Collection in ein Array übertragen
ReDim LArr(1 To Liste.Count)
ReDim DArr(1 To Liste.Count)
i = 0
For Each Temp In Liste
i = i + 1
LArr(i) = Temp
Next
i = 0
For Each Temp In Data
i = i + 1
DArr(i) = Temp
Next
Start = 1
Ende = UBound(LArr)
If SortOrder = msoSortOrderAscending Then C = 1 Else C = -1
Ci = 1
Stack(StackPtr + 1) = Start
Stack(StackPtr + 2) = Ende
StackPtr = StackPtr + 2
Do
StackPtr = StackPtr - 2
Start = Stack(StackPtr + 1)
Ende = Stack(StackPtr + 2)
If Ende - Start < QTHRESH Then
'Insertionsort
Select Case Compare
Case vbDatabaseCompare
'Zahlen sortieren
If SortOrder = msoSortOrderAscending Then
For j = Start + 1 To Ende
Pivot = LArr(j)
Temp = DArr(j)
For i = j - 1 To Start Step -1
If LArr(i) <= Pivot Then Exit For
LArr(i + 1) = LArr(i)
DArr(i + 1) = DArr(i)
Next
LArr(i + 1) = Pivot
DArr(i + 1) = Temp
Next
Else
For j = Start + 1 To Ende
Pivot = LArr(j)
Temp = DArr(j)
For i = j - 1 To Start Step -1
If LArr(i) >= Pivot Then Exit For
LArr(i + 1) = LArr(i)
DArr(i + 1) = DArr(i)
Next
LArr(i + 1) = Pivot
DArr(i + 1) = Temp
Next
End If
Case vbTextCompare
'Texte sortieren => MatchCase:=False
For j = Start + 1 To Ende
Pivot = LArr(j)
Temp = DArr(j)
For i = j - 1 To Start Step -1
Ci = StrComp(LArr(i), Pivot, Compare)
If Ci <> C Then Exit For
LArr(i + 1) = LArr(i)
DArr(i + 1) = DArr(i)
Next
LArr(i + 1) = Pivot
DArr(i + 1) = Temp
Next
End Select
Else
'QuickSort
i = Start: j = Ende
Pivot = LArr((Start + Ende) \ 2)
Do
Select Case Compare
Case vbDatabaseCompare
'Zahlen sortieren
If SortOrder = msoSortOrderAscending Then
Do While (LArr(i) < Pivot): i = i + 1: Loop
Do While (LArr(j) > Pivot): j = j - 1: Loop
Else
Do While (LArr(i) > Pivot): i = i + 1: Loop
Do While (LArr(j) < Pivot): j = j - 1: Loop
End If
Case vbTextCompare
'Texte sortieren => MatchCase:=False
Ci = StrComp(LArr(i), Pivot, Compare)
Do While (Ci = -C)
i = i + 1
Ci = StrComp(LArr(i), Pivot, Compare)
Loop
Cj = StrComp(LArr(j), Pivot, Compare)
Do While (Cj = C)
j = j - 1
Cj = StrComp(LArr(j), Pivot, Compare)
Loop
End Select
If i <= j Then
If i < j And Not (Ci = 0 And Cj = 0) Then
Temp = DArr(i)
DArr(i) = DArr(j)
DArr(j) = Temp
Temp = LArr(i)
LArr(i) = LArr(j)
LArr(j) = Temp
End If
i = i + 1: j = j - 1
End If
Loop Until i > j
If (Start < j) Then
'QuickSort LArr, Start, j, Compare, SortOrder
Stack(StackPtr + 1) = Start
Stack(StackPtr + 2) = j
StackPtr = StackPtr + 2
End If
If (i < Ende) Then
'QuickSort LArr, i, Ende, Compare, SortOrder
Stack(StackPtr + 1) = i
Stack(StackPtr + 2) = Ende
StackPtr = StackPtr + 2
End If
End If
Loop Until StackPtr = 0
'Collection neu aufbauen
Set Data = Nothing
Set Data = New Collection
For i = 1 To UBound(DArr)
Data.Add DArr(i)
Next
End Sub
Public Function Execute( _
Optional SortBy As msoSortBy = 0, _
Optional SortOrder As msoSortOrder = msoSortOrderAscending, _
Optional AlwaysAccurate As Boolean = True) As Long
'Beginnt die Suche nach den angegebenen Dateien.
'SortBy:
' Die für die Sortierung der zurückgegebenen Dateien verwendete Methode. Dies kann eine der _
folgenden MsoSortBy- Konstanten sein: msoSortbyFileName, msoSortbyFileType, _
msoSortbyLastModified oder msoSortbySize. Ist SortBy = 0 wird nicht sortiert
'SortOrder:
' Die Reihenfolge, in der die zurückgegebenen Dateien sortiert werden sollen. Dies kann eine _
der folgenden MsoSortOrder-Konstanten sein: msoSortOrderAscending oder msoSortOrderDescending.
'AlwaysAccurate:
' Ohne Funktion, nur aus Kompatiblitätsgründen
Dim i As Integer
Dim OldValue64Bit As Long
ReDim fsFileExt(LBound(fsFileName) To UBound(fsFileName))
ReDim fsFileBase(LBound(fsFileName) To UBound(fsFileName))
For i = LBound(fsFileName) To UBound(fsFileName)
fsFileExt(i) = fso.GetExtensionName(fsFileName(i))
fsFileBase(i) = fso.GetBaseName(fsFileName(i))
Next
ClearCollections
SortFilesBy = SortBy
If IsWow64 Then
If Wow64DisableWow64FsRedirection(OldValue64Bit) = 0 Then IsWow64 = False
End If
SearchPrim fsLookIn
If IsWow64 Then Wow64RevertWow64FsRedirection OldValue64Bit
Execute = FoundFiles.Count
Select Case SortBy
Case msoSortByFileName, msoSortByFileType
QuickSortCollection SortFiles, FoundFiles, vbTextCompare, SortOrder
QuickSortCollection SortDirs, FoundDirs, vbTextCompare, SortOrder
Case msoSortByLastModified, msoSortBySize
QuickSortCollection SortFiles, FoundFiles, vbDatabaseCompare, SortOrder
QuickSortCollection SortDirs, FoundDirs, vbDatabaseCompare, SortOrder
End Select
End Function
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.