UBound --> compile error expected: identifier

Hallo Rolf,

weitesgehend hat dir ja Rainer schon geholfen.
Solltest du es dennoch nicht ans laufen bringen, so schmeisse einfach deine Dateisuche raus und schreibe schnell eine neue. Das ist echt net schwer. Lege diese Suche dazu in eine Klasse und schon ist sie flexibel. Brauchst du sie nochmal, so binde dann einfach die geschriebene Klasse in dein neues Project ein und volla, fertig.

Wie so etwas ausschauen kann, schau :wink:

'Klasse cFindFile

Option Explicit

' Benötigte API´s
Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" \_
 (ByVal lpFileName As String, \_
 lpFindFileData As WIN32\_FIND\_DATA) 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 Declare Function FileTimeToSystemTime Lib "kernel32" \_
 (lpFileTime As FILETIME, \_
 lpSystemTime As SYSTEMTIME) As Long


' Benutzerdefinierte Konstanten
Private Const MAX\_PATH = 260
Private Const MAXDWORD = &HFFFF
Private Const INVALID\_HANDLE\_VALUE = -1
Private Const MyUnhandledError = 9999


' Benutzerdefinierte Typen
Private Type FILETIME
 dwLowDateTime As Long
 dwHighDateTime As Long
End Type

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

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


' Aufzählung für sFileFlag Eigenschaft
Public Enum FileFlag
 FILE\_ATTRIBUTE\_READONLY = &H1
 FILE\_ATTRIBUTE\_HIDDEN = &H2
 FILE\_ATTRIBUTE\_SYSTEM = &H4
 FILE\_ATTRIBUTE\_DIRECTORY = &H10
 FILE\_ATTRIBUTE\_ARCHIVE = &H20
 FILE\_ATTRIBUTE\_NORMAL = &H80
 FILE\_ATTRIBUTE\_TEMPORARY = &H100
 FILE\_ATTRIBUTE\_ALLTYPES = &H1B7
 FILE\_ATTRIBUTE\_ALLTYPES\_WITHOUT\_DIR = &H1A7
End Enum


'lokale Variablen zum Zuweisen der Eigenschaften
Private mvarsSearchpath As String
Private mvarsFileToFind As String
Private mvarsInclSubfolders As Boolean
Private mvarsFileFlag As FileFlag


'RaiseEvent MatchFound[(arg1, arg2, ... , argn)]
Public Event MatchFound(ByVal sFilename As String, \_
 ByVal sFilePath As String, \_
 ByVal sFiledate As Date, \_
 ByVal sFilesize As Long, \_
 ByVal sLastAccess As Date, \_
 ByVal sLastWrite As Date, \_
 ByVal sShortName As String)

'RaiseEvent StopSearch[(arg1)]
Public Event StopSearch(Cancel As Boolean)

Private Sub Class\_Initialize()
 'Die Klasse wird initialisiert.
 sFileFlag = FILE\_ATTRIBUTE\_ALLTYPES
 sInclSubfolders = True
End Sub

Private Sub Class\_Terminate()
 'Die Klasse wird aus dem Speicher entfernt.
End Sub

Public Sub sStartSearch()
 Dim lFileToFind As String, lSearchpath As String, FileName As String
 Dim ShortName As String, DirName As String, DirNames() As String
 Dim DirCount As Integer, nDir As Integer, Cont As Integer, I As Integer
 Dim Filesize As Long, hSearch As Long
 Dim Filedate As Date, LastAccess As Date, LastWrite As Date
 Dim lInclSubfolders As Boolean, bCancel As Boolean
 Dim sDate As SYSTEMTIME
 Dim lFileFlag As FileFlag
 Dim WFD As WIN32\_FIND\_DATA

 On Error GoTo sStartSearchErr

 ' Eigenschaften Property Get in lokale Variablen kopieren
 lFileToFind = sFileToFind
 lFileFlag = sFileFlag
 lSearchpath = sSearchpath
 lInclSubfolders = sInclSubfolders

 ' Initialisieren der Variablen
 If Right(lSearchpath, 1) "\" Then lSearchpath = lSearchpath & "\"
 nDir = 0
 DirCount = 0
 ReDim DirNames(nDir)
 Cont = True
 bCancel = False

 ' Die Suche geht los. Zuerst werden die Subfolders ermittelt
 hSearch = FindFirstFile(lSearchpath & "\*", WFD)
 If hSearch INVALID\_HANDLE\_VALUE Then
 Do While Cont
 ' vbNullChar entfernen
 DirName = Left$(WFD.cFileName, InStr(WFD.cFileName, vbNullChar) - 1)

 ' Prüfen, ob DirName auch wirklich ein Subfolder ist
 If (DirName ".") And (DirName "..") Then
 If (WFD.dwFileAttributes And vbDirectory) = FileFlag.FILE\_ATTRIBUTE\_DIRECTORY Then

 ' Subfolder ins loakale Array speichern
 DirNames(nDir) = DirName

 ' Schleifenzähler erhöhen
 DirCount = DirCount + 1
 nDir = nDir + 1

 ' Lokales Array neu dimensionieren
 ReDim Preserve DirNames(nDir)
 End If
 End If

 ' Nächster Subfolder ermitteln
 Cont = FindNextFile(hSearch, WFD)

 ' Geben wir der Methode ein wenig Zeit zum Atmen
 DoEvents
 Loop
 Cont = FindClose(hSearch)
 End If

 ' Jetzt werden die zu findenden Dateien ermittelt
 hSearch = FindFirstFile(lSearchpath & lFileToFind, WFD)
 Cont = True
 If hSearch INVALID\_HANDLE\_VALUE Then
 While Cont
 ' vbNullChar entfernen
 FileName = Left$(WFD.cFileName, InStr(WFD.cFileName, vbNullChar) - 1)

 ' Prüfen, ob FileName ungleich . und .. ist
 If (FileName ".") And (FileName "..") Then
 ' Stimmt das FileAttribut mit Eigenschaft sFileFlag überein
 If (WFD.dwFileAttributes Or lFileFlag) = lFileFlag Then

 ' Dateigröße ermitteln
 Filesize = (WFD.nFileSizeHigh \* MAXDWORD) + WFD.nFileSizeLow

 ' Dateidatum/Zeit ermitteln
 FileTimeToSystemTime WFD.ftCreationTime, sDate
 With sDate
 Filedate = CDate(.wDay & "." & .wMonth & "." & .wYear \_
 & " " & .wHour & ":" & .wMinute & ":" & .wSecond)
 End With

 ' LastAccess ermitteln
 FileTimeToSystemTime WFD.ftLastAccessTime, sDate
 With sDate
 LastAccess = CDate(.wDay & "." & .wMonth & "." & .wYear \_
 & " " & .wHour & ":" & .wMinute & ":" & .wSecond)
 End With

 ' LastWrite ermitteln
 FileTimeToSystemTime WFD.ftLastWriteTime, sDate
 With sDate
 LastWrite = CDate(.wDay & "." & .wMonth & "." & .wYear \_
 & " " & .wHour & ":" & .wMinute & ":" & .wSecond)
 End With

 ' ShortName 8.3 ermitteln
 ShortName = Left$(WFD.cAlternate, InStr(WFD.cAlternate, vbNullChar) - 1)

 ' Und jetzt den Event aufrufen um die Dateiinformationen zu übergeben
 RaiseEvent MatchFound(FileName, lSearchpath, Filedate, Filesize, \_
 LastAccess, LastWrite, ShortName)
 End If
 End If

 ' Nächste Datei ermitteln
 Cont = FindNextFile(hSearch, WFD)

 ' Geben wir der Methode ein wenig Zeit zum Atmen
 DoEvents
 Wend
 ' Suche abgeschlossen
 Cont = FindClose(hSearch)
 End If

 ' Sollen die Subfolders durchsucht werden?
 If lInclSubfolders Then
 ' Prüfen, ob im aktuellen Folder weitere Subfolder sind
 If nDir \> 0 Then
 ' Rekursiver Aufruf der Methode mit Übergabe eines neuen Subfolders
 For I = 0 To nDir - 1
 ' Event StopSearch aufrufen und prüfen ob Abbruch
 ' durch Benutzer erfolgte
 RaiseEvent StopSearch(bCancel)
 If bCancel Then Exit Sub

 ' neuer Suchpfad an Property Let sSearchpath übergeben
 sSearchpath = lSearchpath & DirNames(I)
 ' neue Suche starten...
 sStartSearch
 Next I
 End If
 End If
Exit Sub

sStartSearchErr:
 RaiseError MyUnhandledError, "cFindFile:sStartSearch Method" \_
 , "Fehler bei sStartSearch"
End Sub

' Eigenschaft cFindFile.sFileFlag setzen
Public Property Let sFileFlag(ByVal vData As FileFlag)
 On Error GoTo sFileFlagLetErr
 mvarsFileFlag = vData
Exit Property

sFileFlagLetErr:
 RaiseError MyUnhandledError, "cFindFile:sFileFlag Property Let" \_
 , "Fehler bei sFileFlag Property Let"
End Property

' Eigenschaft cFindFile.sFileFlag lesen
Public Property Get sFileFlag() As FileFlag
 On Error GoTo sFileFlagGetErr
 sFileFlag = mvarsFileFlag
Exit Property

sFileFlagGetErr:
 RaiseError MyUnhandledError, "cFindFile:sFileFlag Property Get" \_
 , "Fehler bei sFileFlag Property Get"
End Property

' Eigenschaft cFindFile.sInclSubFolders setzen
Public Property Let sInclSubfolders(ByVal vData As Boolean)
 On Error GoTo sInclSubfoldersLetErr
 mvarsInclSubfolders = vData
Exit Property

sInclSubfoldersLetErr:
 RaiseError MyUnhandledError, "cFindFile:sInclSubfolders Property Let" \_
 , "Fehler bei sInclSubfolders Property Let"
End Property

' Eigenschaft cFindFile.sInclSubFolders lesen
Public Property Get sInclSubfolders() As Boolean
 On Error GoTo sInclSubfoldersGetErr
 sInclSubfolders = mvarsInclSubfolders
Exit Property

sInclSubfoldersGetErr:
 RaiseError MyUnhandledError, "cFindFile:sInclSubfolders Property Get" \_
 , "Fehler bei sInclSubfolders Property Get"
End Property

' Eigenschaft cFindFile.sFileToFind setzen
Public Property Let sFileToFind(ByVal vData As String)
 On Error GoTo sFileToFindLetErr
 mvarsFileToFind = vData
Exit Property

sFileToFindLetErr:
 RaiseError MyUnhandledError, "cFindFile:sFileToFind Property Let" \_
 , "Fehler bei sFileToFind Property Let"
End Property

' Eigenschaft cFindFile.sFileToFind lesen
Public Property Get sFileToFind() As String
 On Error GoTo sFileToFindGetErr
 sFileToFind = mvarsFileToFind
Exit Property

sFileToFindGetErr:
 RaiseError MyUnhandledError, "cFindFile:sFileToFind Property Get" \_
 , "Fehler bei sFileToFind Property Get"
End Property

' Eigenschaft cFindFile.sSearchpath setzen
Public Property Let sSearchpath(ByVal vData As String)
 On Error GoTo sSearchpathLetErr
 mvarsSearchpath = vData
Exit Property

sSearchpathLetErr:
 RaiseError MyUnhandledError, "cFindFile:sSearchpath Property Let" \_
 , "Fehler bei sSearchpath Property Let"
End Property

' Eigenschaft cFindFile.sSearchpath lesen
Public Property Get sSearchpath() As String
 On Error GoTo sSearchpathGetErr
 sSearchpath = mvarsSearchpath
Exit Property

sSearchpathGetErr:
 RaiseError MyUnhandledError, "cFindFile:sSearchpath Property Get" \_
 , "Fehler bei sSearchpath Property Get"
End Property

' Error Object setzen und an den Client übergeben
Private Sub RaiseError(ErrorNumber As Long, Source As String, strErrorText As String)
 Err.Raise ErrorNumber, Source, strErrorText
End Sub

Um die Klasse zu verwenden, brauchst du nur noch wenige Zeilen Source. Da die Suche nun in einer Klasse ausgelagert ist, ist es ja ein Object und hat somit Eigenschaften und kann Ereignisse auslösen, welche dies auch macht :wink:

Also wie gesagt, aufrufen oder starten tust du die Suche via

Option Explicit

'Auf der Form liegen drei Steuerelemente:
'Command1
'Command2
'List1
 
' Klasse mit Ereignissen!
Private WithEvents nSearch As cFindFile
 
' Für Abbruch-Button
Private bCancel As Boolean

Private Sub Form\_Load()
 ' Klasse instanzieren
 Set nSearch = New cFindFile
 Command1.Caption = "Suchen"
 Command2.Caption = "Abbrechen"
End Sub

' Suchvorgang starten
Private Sub Command1\_Click()
 List1.Clear ' Listbox loschen
 bCancel = False ' Abbruchbedingung setzen
 
 With nSearch
 .sSearchpath = "C:\" ' Suchpfad
 .sFileToFind = "\*.ini" ' Suchnamen
 .sFileFlag = FILE\_ATTRIBUTE\_ALLTYPES ' Dateiattribute
 .sInclSubfolders = True ' Subdirs durchsuchen
 
 ' Suche starten
 Screen.MousePointer = 13
 .sStartSearch
 Screen.MousePointer = 0
 End With
End Sub

' Suchvorgang abbrechen!
Private Sub Command2\_Click() 
 
 bCancel = True ' Abbruchbedingung setzen!
End Sub

'Ereignis stellt uns die Klasse bereit :wink:
Private Sub nSearch\_MatchFound(ByVal sFilename As String, \_
 ByVal sFilePath As String, \_
 ByVal sFiledate As Date, \_
 ByVal sFilesize As Long, \_
 ByVal sLastAccess As Date, \_
 ByVal sLastWrite As Date, \_
 ByVal sShortName As String)
 
 ' Listbox mit dem letzten Suchergebnis füllen
 List1.AddItem sFilePath & sFilename
 DoEvents
End Sub

'Auch das Ereignis stellt uns die Klasse zur Verfügung :smile:
Private Sub nSearch\_StopSearch(Cancel As Boolean)
 ' Wurde Stop gedrückt, dann Cancel für den 
 ' Suchabbruch setzen
 If bCancel Then Cancel = bCancel
 DoEvents
End Sub

Schaut vorerst nach viel Arbeit aus, ist es aber nicht und wie du siehst, ist sie nicht nur schnell, sondern auch arg felxibel :smile:
Auch kannst du hier schon deine Ergebnisse verarbeiten, obwohl die Suche nicht beendet ist. Auch kannst du diese vorzeitig abbrechen etc. :smile:

MfG Alex

[Steuerelementeliste als Kommentar eingefügt]

Hallo Alex,

danke, das sieht toll aus und ist zumindest für mich übersichtlicher als das Scripting, weil da immer die Intellisense nicht anspringt und ich immer im Nebel stochern muss.

@Rainer, waere das evtl. etwas für die FAQ ?

Ich denke ja, aber …

Wenn ja, dann teste es aber vorher mal bitte :smile:

… dieser Empfehlung werde ich erst folgen. :smile:

Gruß Rainer

Moin moin Anno repektive Alex :smile:),

danke dir, wie ich unten schon mal erwähnt habe habe ich es schon befürchtet, dass ich hier ned einfach den Code mit n paar kleineren Änderungen ins VB5 übernhemen kann/darf :smile:.

Da ich aber noch 2 Wochen Urlaub hab, werd ich mir dem annehmen und deine Suche einarbeiten.

Puh…:smile:))

Gruß Rolf

Hallo Rolf,

weitesgehend hat dir ja Rainer schon geholfen.
Solltest du es dennoch nicht ans laufen bringen, so schmeisse
einfach deine Dateisuche raus und schreibe schnell eine neue.
Das ist echt net schwer. Lege diese Suche dazu in eine Klasse
und schon ist sie flexibel. Brauchst du sie nochmal, so binde
dann einfach die geschriebene Klasse in dein neues Project ein
und volla, fertig.

Wie so etwas ausschauen kann, schau :wink:

'Klasse cFindFile

Option Explicit

’ Benötigte API´s
Private Declare Function FindFirstFile Lib „kernel32“ Alias
„FindFirstFileA“ _
(ByVal lpFileName As String, _
lpFindFileData As WIN32_FIND_DATA) 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 Declare Function FileTimeToSystemTime Lib „kernel32“ _
(lpFileTime As FILETIME, _
lpSystemTime As SYSTEMTIME) As Long

’ Benutzerdefinierte Konstanten
Private Const MAX_PATH = 260
Private Const MAXDWORD = &HFFFF
Private Const INVALID_HANDLE_VALUE = -1
Private Const MyUnhandledError = 9999

’ Benutzerdefinierte Typen
Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type

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

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

’ Aufzählung für sFileFlag Eigenschaft
Public Enum FileFlag
FILE_ATTRIBUTE_READONLY = &H1
FILE_ATTRIBUTE_HIDDEN = &H2
FILE_ATTRIBUTE_SYSTEM = &H4
FILE_ATTRIBUTE_DIRECTORY = &H10
FILE_ATTRIBUTE_ARCHIVE = &H20
FILE_ATTRIBUTE_NORMAL = &H80
FILE_ATTRIBUTE_TEMPORARY = &H100
FILE_ATTRIBUTE_ALLTYPES = &H1B7
FILE_ATTRIBUTE_ALLTYPES_WITHOUT_DIR = &H1A7
End Enum

'lokale Variablen zum Zuweisen der Eigenschaften
Private mvarsSearchpath As String
Private mvarsFileToFind As String
Private mvarsInclSubfolders As Boolean
Private mvarsFileFlag As FileFlag

'RaiseEvent MatchFound[(arg1, arg2, … , argn)]
Public Event MatchFound(ByVal sFilename As String, _
ByVal sFilePath As String, _
ByVal sFiledate As Date, _
ByVal sFilesize As Long, _
ByVal sLastAccess As Date, _
ByVal sLastWrite As Date, _
ByVal sShortName As String)

'RaiseEvent StopSearch[(arg1)]
Public Event StopSearch(Cancel As Boolean)

Private Sub Class_Initialize()
'Die Klasse wird initialisiert.
sFileFlag = FILE_ATTRIBUTE_ALLTYPES
sInclSubfolders = True
End Sub

Private Sub Class_Terminate()
'Die Klasse wird aus dem Speicher entfernt.
End Sub

Public Sub sStartSearch()
Dim lFileToFind As String, lSearchpath As String, FileName
As String
Dim ShortName As String, DirName As String, DirNames() As
String
Dim DirCount As Integer, nDir As Integer, Cont As Integer,
I As Integer
Dim Filesize As Long, hSearch As Long
Dim Filedate As Date, LastAccess As Date, LastWrite As Date
Dim lInclSubfolders As Boolean, bCancel As Boolean
Dim sDate As SYSTEMTIME
Dim lFileFlag As FileFlag
Dim WFD As WIN32_FIND_DATA

On Error GoTo sStartSearchErr

’ Eigenschaften Property Get in lokale Variablen kopieren
lFileToFind = sFileToFind
lFileFlag = sFileFlag
lSearchpath = sSearchpath
lInclSubfolders = sInclSubfolders

’ Initialisieren der Variablen
If Right(lSearchpath, 1) „“ Then lSearchpath =
lSearchpath & „“
nDir = 0
DirCount = 0
ReDim DirNames(nDir)
Cont = True
bCancel = False

’ Die Suche geht los. Zuerst werden die Subfolders
ermittelt
hSearch = FindFirstFile(lSearchpath & „*“, WFD)
If hSearch INVALID_HANDLE_VALUE Then
Do While Cont
’ vbNullChar entfernen
DirName = Left$(WFD.cFileName, InStr(WFD.cFileName,
vbNullChar) - 1)

’ Prüfen, ob DirName auch wirklich ein Subfolder ist
If (DirName „.“) And (DirName „…“)
Then
If (WFD.dwFileAttributes And vbDirectory) =
FileFlag.FILE_ATTRIBUTE_DIRECTORY Then

’ Subfolder ins loakale Array speichern
DirNames(nDir) = DirName

’ Schleifenzähler erhöhen
DirCount = DirCount + 1
nDir = nDir + 1

’ Lokales Array neu dimensionieren
ReDim Preserve DirNames(nDir)
End If
End If

’ Nächster Subfolder ermitteln
Cont = FindNextFile(hSearch, WFD)

’ Geben wir der Methode ein wenig Zeit zum Atmen
DoEvents
Loop
Cont = FindClose(hSearch)
End If

’ Jetzt werden die zu findenden Dateien ermittelt
hSearch = FindFirstFile(lSearchpath & lFileToFind, WFD)
Cont = True
If hSearch INVALID_HANDLE_VALUE Then
While Cont
’ vbNullChar entfernen
FileName = Left$(WFD.cFileName, InStr(WFD.cFileName,
vbNullChar) - 1)

’ Prüfen, ob FileName ungleich . und … ist
If (FileName „.“) And (FileName
„…“) Then
’ Stimmt das FileAttribut mit Eigenschaft
sFileFlag überein
If (WFD.dwFileAttributes Or lFileFlag) = lFileFlag
Then

’ Dateigröße ermitteln
Filesize = (WFD.nFileSizeHigh * MAXDWORD) +
WFD.nFileSizeLow

’ Dateidatum/Zeit ermitteln
FileTimeToSystemTime WFD.ftCreationTime, sDate
With sDate
Filedate = CDate(.wDay & „.“ & .wMonth & „.“
& .wYear _
& " " & .wHour & „:“ & .wMinute & „:“ &
.wSecond)
End With

’ LastAccess ermitteln
FileTimeToSystemTime WFD.ftLastAccessTime,
sDate
With sDate
LastAccess = CDate(.wDay & „.“ & .wMonth &
„.“ & .wYear _
& " " & .wHour & „:“ & .wMinute & „:“ &
.wSecond)
End With

’ LastWrite ermitteln
FileTimeToSystemTime WFD.ftLastWriteTime, sDate
With sDate
LastWrite = CDate(.wDay & „.“ & .wMonth &
„.“ & .wYear _
& " " & .wHour & „:“ & .wMinute & „:“ &
.wSecond)
End With

’ ShortName 8.3 ermitteln
ShortName = Left$(WFD.cAlternate,
InStr(WFD.cAlternate, vbNullChar) - 1)

’ Und jetzt den Event aufrufen um die
Dateiinformationen zu übergeben
RaiseEvent MatchFound(FileName, lSearchpath,
Filedate, Filesize, _
LastAccess, LastWrite,
ShortName)
End If
End If

’ Nächste Datei ermitteln
Cont = FindNextFile(hSearch, WFD)

’ Geben wir der Methode ein wenig Zeit zum Atmen
DoEvents
Wend
’ Suche abgeschlossen
Cont = FindClose(hSearch)
End If

’ Sollen die Subfolders durchsucht werden?
If lInclSubfolders Then
’ Prüfen, ob im aktuellen Folder weitere Subfolder sind
If nDir > 0 Then
’ Rekursiver Aufruf der Methode mit Übergabe eines
neuen Subfolders
For I = 0 To nDir - 1
’ Event StopSearch aufrufen und prüfen ob Abbruch
’ durch Benutzer erfolgte
RaiseEvent StopSearch(bCancel)
If bCancel Then Exit Sub

’ neuer Suchpfad an Property Let sSearchpath
übergeben
sSearchpath = lSearchpath & DirNames(I)
’ neue Suche starten…
sStartSearch
Next I
End If
End If
Exit Sub

sStartSearchErr:
RaiseError MyUnhandledError, „cFindFile:sStartSearch
Method“ _
, „Fehler bei sStartSearch“
End Sub

’ Eigenschaft cFindFile.sFileFlag setzen
Public Property Let sFileFlag(ByVal vData As FileFlag)
On Error GoTo sFileFlagLetErr
mvarsFileFlag = vData
Exit Property

sFileFlagLetErr:
RaiseError MyUnhandledError, „cFindFile:sFileFlag Property
Let“ _
, „Fehler bei sFileFlag Property Let“
End Property

’ Eigenschaft cFindFile.sFileFlag lesen
Public Property Get sFileFlag() As FileFlag
On Error GoTo sFileFlagGetErr
sFileFlag = mvarsFileFlag
Exit Property

sFileFlagGetErr:
RaiseError MyUnhandledError, „cFindFile:sFileFlag Property
Get“ _
, „Fehler bei sFileFlag Property Get“
End Property

’ Eigenschaft cFindFile.sInclSubFolders setzen
Public Property Let sInclSubfolders(ByVal vData As Boolean)
On Error GoTo sInclSubfoldersLetErr
mvarsInclSubfolders = vData
Exit Property

sInclSubfoldersLetErr:
RaiseError MyUnhandledError, „cFindFile:sInclSubfolders
Property Let“ _
, „Fehler bei sInclSubfolders Property Let“
End Property

’ Eigenschaft cFindFile.sInclSubFolders lesen
Public Property Get sInclSubfolders() As Boolean
On Error GoTo sInclSubfoldersGetErr
sInclSubfolders = mvarsInclSubfolders
Exit Property

sInclSubfoldersGetErr:
RaiseError MyUnhandledError, „cFindFile:sInclSubfolders
Property Get“ _
, „Fehler bei sInclSubfolders Property Get“
End Property

’ Eigenschaft cFindFile.sFileToFind setzen
Public Property Let sFileToFind(ByVal vData As String)
On Error GoTo sFileToFindLetErr
mvarsFileToFind = vData
Exit Property

sFileToFindLetErr:
RaiseError MyUnhandledError, „cFindFile:sFileToFind
Property Let“ _
, „Fehler bei sFileToFind Property Let“
End Property

’ Eigenschaft cFindFile.sFileToFind lesen
Public Property Get sFileToFind() As String
On Error GoTo sFileToFindGetErr
sFileToFind = mvarsFileToFind
Exit Property

sFileToFindGetErr:
RaiseError MyUnhandledError, „cFindFile:sFileToFind
Property Get“ _
, „Fehler bei sFileToFind Property Get“
End Property

’ Eigenschaft cFindFile.sSearchpath setzen
Public Property Let sSearchpath(ByVal vData As String)
On Error GoTo sSearchpathLetErr
mvarsSearchpath = vData
Exit Property

sSearchpathLetErr:
RaiseError MyUnhandledError, „cFindFile:sSearchpath
Property Let“ _
, „Fehler bei sSearchpath Property Let“
End Property

’ Eigenschaft cFindFile.sSearchpath lesen
Public Property Get sSearchpath() As String
On Error GoTo sSearchpathGetErr
sSearchpath = mvarsSearchpath
Exit Property

sSearchpathGetErr:
RaiseError MyUnhandledError, „cFindFile:sSearchpath
Property Get“ _
, „Fehler bei sSearchpath Property Get“
End Property

’ Error Object setzen und an den Client übergeben
Private Sub RaiseError(ErrorNumber As Long, Source As String,
strErrorText As String)
Err.Raise ErrorNumber, Source, strErrorText
End Sub

Um die Klasse zu verwenden, brauchst du nur noch wenige Zeilen
Source. Da die Suche nun in einer Klasse ausgelagert ist, ist
es ja ein Object und hat somit Eigenschaften und kann
Ereignisse auslösen, welche dies auch macht :wink:

Also wie gesagt, aufrufen oder starten tust du die Suche via

Option Explicit

’ Klasse mit Ereignissen!
Private WithEvents nSearch As cFindFile

’ Für Abbruch-Button
Private bCancel As Boolean

Private Sub Form_Load()
’ Klasse instanzieren
Set nSearch = New cFindFile
End Sub

’ Suchvorgang starten
Private Sub Command1_Click()
List1.Clear ’ Listbox loschen
bCancel = False ’ Abbruchbedingung setzen

With nSearch
.sSearchpath = „C:“ ’ Suchpfad
.sFileToFind = „*.ini“ ’ Suchnamen
.sFileFlag = FILE_ATTRIBUTE_ALLTYPES ’ Dateiattribute
.sInclSubfolders = True ’ Subdirs durchsuchen

’ Suche starten
Screen.MousePointer = 13
.sStartSearch
Screen.MousePointer = 0
End With
End Sub

’ Suchvorgang abbrechen!
Private Sub Command2_Click()

bCancel = True ’ Abbruchbedingung setzen!
End Sub

'Ereignis stellt uns die Klasse bereit :wink:
Private Sub nSearch_MatchFound(ByVal sFilename As String, _
ByVal sFilePath As String, _
ByVal sFiledate As Date, _
ByVal sFilesize As Long, _
ByVal sLastAccess As Date, _
ByVal sLastWrite As Date, _
ByVal sShortName As String)

’ Listbox mit dem letzten Suchergebnis füllen
List1.AddItem sFilePath & sFilename
DoEvents
End Sub

'Auch das Ereignis stellt uns die Klasse zur Verfügung :smile:
Private Sub nSearch_StopSearch(Cancel As Boolean)
’ Wurde Stop gedrückt, dann Cancel für den
’ Suchabbruch setzen
If bCancel Then Cancel = bCancel
DoEvents
End Sub

Schaut vorerst nach viel Arbeit aus, ist es aber nicht und wie
du siehst, ist sie nicht nur schnell, sondern auch arg
felxibel :smile:
Auch kannst du hier schon deine Ergebnisse verarbeiten, obwohl
die Suche nicht beendet ist. Auch kannst du diese vorzeitig
abbrechen etc. :smile:

MfG Alex

@Rainer, waere das evtl. etwas für die FAQ ?
Wenn ja, dann teste es aber vorher mal bitte :smile:

Sodala - erster Zwischenbericht,

habe ne Klasse „cFindFile“ erstellt - hier habe ich

'Klasse cFindFile

Option Explicit

' Benötigte API´s
Private Declare Function FindFirstFile Lib "kernel32" Alias "FindFirstFileA" \_
 (ByVal lpFileName As String, \_
 lpFindFileData As WIN32\_FIND\_DATA) 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 Declare Function FileTimeToSystemTime Lib "kernel32" \_
 (lpFileTime As FILETIME, \_
 lpSystemTime As SYSTEMTIME) As Long


' Benutzerdefinierte Konstanten
Private Const MAX\_PATH = 260
Private Const MAXDWORD = &HFFFF
Private Const INVALID\_HANDLE\_VALUE = -1
Private Const MyUnhandledError = 9999


' Benutzerdefinierte Typen
Private Type FILETIME
 dwLowDateTime As Long
 dwHighDateTime As Long
End Type

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

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


' Aufzählung für sFileFlag Eigenschaft
Public Enum FileFlag
 FILE\_ATTRIBUTE\_READONLY = &H1
 FILE\_ATTRIBUTE\_HIDDEN = &H2
 FILE\_ATTRIBUTE\_SYSTEM = &H4
 FILE\_ATTRIBUTE\_DIRECTORY = &H10
 FILE\_ATTRIBUTE\_ARCHIVE = &H20
 FILE\_ATTRIBUTE\_NORMAL = &H80
 FILE\_ATTRIBUTE\_TEMPORARY = &H100
 FILE\_ATTRIBUTE\_ALLTYPES = &H1B7
 FILE\_ATTRIBUTE\_ALLTYPES\_WITHOUT\_DIR = &H1A7
End Enum


'lokale Variablen zum Zuweisen der Eigenschaften
Private mvarsSearchpath As String
Private mvarsFileToFind As String
Private mvarsInclSubfolders As Boolean
Private mvarsFileFlag As FileFlag


'RaiseEvent MatchFound[(arg1, arg2, ... , argn)]
Public Event MatchFound(ByVal sFilename As String, \_
 ByVal sFilePath As String, \_
 ByVal sFiledate As Date, \_
 ByVal sFilesize As Long, \_
 ByVal sLastAccess As Date, \_
 ByVal sLastWrite As Date, \_
 ByVal sShortName As String)

'RaiseEvent StopSearch[(arg1)]
Public Event StopSearch(Cancel As Boolean)

Private Sub Class\_Initialize()
 'Die Klasse wird initialisiert.
 sFileFlag = FILE\_ATTRIBUTE\_ALLTYPES
 sInclSubfolders = True
End Sub

Private Sub Class\_Terminate()
 'Die Klasse wird aus dem Speicher entfernt.
End Sub

' Klasse mit Ereignissen!
Private WithEvents nSearch As cFindFile
 
' Für Abbruch-Button
Private bCancel As Boolean

eingefügt (bitte berichtigt mich wenns falsch is)

und dann meine Form mit 2 x Command und eine Listbox

Option Explicit



Public Sub sStartSearch()
 Dim lFileToFind As String, lSearchpath As String, FileName As String
 Dim ShortName As String, DirName As String, DirNames() As String
 Dim DirCount As Integer, nDir As Integer, Cont As Integer, I As Integer
 Dim Filesize As Long, hSearch As Long
 Dim Filedate As Date, LastAccess As Date, LastWrite As Date
 Dim lInclSubfolders As Boolean, bCancel As Boolean
 Dim sDate As SYSTEMTIME
 Dim lFileFlag As FileFlag
 Dim WFD As WIN32\_FIND\_DATA

 On Error GoTo sStartSearchErr

 ' Eigenschaften Property Get in lokale Variablen kopieren
 lFileToFind = sFileToFind
 lFileFlag = sFileFlag
 lSearchpath = sSearchpath
 lInclSubfolders = sInclSubfolders

 ' Initialisieren der Variablen
 If Right(lSearchpath, 1) "\" Then lSearchpath = lSearchpath & "\"
 nDir = 0
 DirCount = 0
 ReDim DirNames(nDir)
 Cont = True
 bCancel = False

 ' Die Suche geht los. Zuerst werden die Subfolders ermittelt
 hSearch = FindFirstFile(lSearchpath & "\*", WFD)
 If hSearch INVALID\_HANDLE\_VALUE Then
 Do While Cont
 ' vbNullChar entfernen
 DirName = Left$(WFD.cFileName, InStr(WFD.cFileName, vbNullChar) - 1)

 ' Prüfen, ob DirName auch wirklich ein Subfolder ist
 If (DirName ".") And (DirName "..") Then
 If (WFD.dwFileAttributes And vbDirectory) = FileFlag.FILE\_ATTRIBUTE\_DIRECTORY Then

 ' Subfolder ins loakale Array speichern
 DirNames(nDir) = DirName

 ' Schleifenzähler erhöhen
 DirCount = DirCount + 1
 nDir = nDir + 1

 ' Lokales Array neu dimensionieren
 ReDim Preserve DirNames(nDir)
 End If
 End If

 ' Nächster Subfolder ermitteln
 Cont = FindNextFile(hSearch, WFD)

 ' Geben wir der Methode ein wenig Zeit zum Atmen
 DoEvents
 Loop
 Cont = FindClose(hSearch)
 End If

 ' Jetzt werden die zu findenden Dateien ermittelt
 hSearch = FindFirstFile(lSearchpath & lFileToFind, WFD)
 Cont = True
 If hSearch INVALID\_HANDLE\_VALUE Then
 While Cont
 ' vbNullChar entfernen
 FileName = Left$(WFD.cFileName, InStr(WFD.cFileName, vbNullChar) - 1)

 ' Prüfen, ob FileName ungleich . und .. ist
 If (FileName ".") And (FileName "..") Then
 ' Stimmt das FileAttribut mit Eigenschaft sFileFlag überein
 If (WFD.dwFileAttributes Or lFileFlag) = lFileFlag Then

 ' Dateigröße ermitteln
 Filesize = (WFD.nFileSizeHigh \* MAXDWORD) + WFD.nFileSizeLow

 ' Dateidatum/Zeit ermitteln
 FileTimeToSystemTime WFD.ftCreationTime, sDate
 With sDate
 Filedate = CDate(.wDay & "." & .wMonth & "." & .wYear \_
 & " " & .wHour & ":" & .wMinute & ":" & .wSecond)
 End With

 ' LastAccess ermitteln
 FileTimeToSystemTime WFD.ftLastAccessTime, sDate
 With sDate
 LastAccess = CDate(.wDay & "." & .wMonth & "." & .wYear \_
 & " " & .wHour & ":" & .wMinute & ":" & .wSecond)
 End With

 ' LastWrite ermitteln
 FileTimeToSystemTime WFD.ftLastWriteTime, sDate
 With sDate
 LastWrite = CDate(.wDay & "." & .wMonth & "." & .wYear \_
 & " " & .wHour & ":" & .wMinute & ":" & .wSecond)
 End With

 ' ShortName 8.3 ermitteln
 ShortName = Left$(WFD.cAlternate, InStr(WFD.cAlternate, vbNullChar) - 1)

 ' Und jetzt den Event aufrufen um die Dateiinformationen zu übergeben
 RaiseEvent MatchFound(FileName, lSearchpath, Filedate, Filesize, \_
 LastAccess, LastWrite, ShortName)
 End If
 End If

 ' Nächste Datei ermitteln
 Cont = FindNextFile(hSearch, WFD)

 ' Geben wir der Methode ein wenig Zeit zum Atmen
 DoEvents
 Wend
 ' Suche abgeschlossen
 Cont = FindClose(hSearch)
 End If

 ' Sollen die Subfolders durchsucht werden?
 If lInclSubfolders Then
 ' Prüfen, ob im aktuellen Folder weitere Subfolder sind
 If nDir \> 0 Then
 ' Rekursiver Aufruf der Methode mit Übergabe eines neuen Subfolders
 For I = 0 To nDir - 1
 ' Event StopSearch aufrufen und prüfen ob Abbruch
 ' durch Benutzer erfolgte
 RaiseEvent StopSearch(bCancel)
 If bCancel Then Exit Sub

 ' neuer Suchpfad an Property Let sSearchpath übergeben
 sSearchpath = lSearchpath & DirNames(I)
 ' neue Suche starten...
 sStartSearch
 Next I
 End If
 End If
Exit Sub

sStartSearchErr:
 RaiseError MyUnhandledError, "cFindFile:sStartSearch Method" \_
 , "Fehler bei sStartSearch"
End Sub

' Eigenschaft cFindFile.sFileFlag setzen
Public Property Let sFileFlag(ByVal vData As FileFlag)
 On Error GoTo sFileFlagLetErr
 mvarsFileFlag = vData
Exit Property

sFileFlagLetErr:
 RaiseError MyUnhandledError, "cFindFile:sFileFlag Property Let" \_
 , "Fehler bei sFileFlag Property Let"
End Property

' Eigenschaft cFindFile.sFileFlag lesen
Public Property Get sFileFlag() As FileFlag
 On Error GoTo sFileFlagGetErr
 sFileFlag = mvarsFileFlag
Exit Property

sFileFlagGetErr:
 RaiseError MyUnhandledError, "cFindFile:sFileFlag Property Get" \_
 , "Fehler bei sFileFlag Property Get"
End Property

' Eigenschaft cFindFile.sInclSubFolders setzen
Public Property Let sInclSubfolders(ByVal vData As Boolean)
 On Error GoTo sInclSubfoldersLetErr
 mvarsInclSubfolders = vData
Exit Property

sInclSubfoldersLetErr:
 RaiseError MyUnhandledError, "cFindFile:sInclSubfolders Property Let" \_
 , "Fehler bei sInclSubfolders Property Let"
End Property

' Eigenschaft cFindFile.sInclSubFolders lesen
Public Property Get sInclSubfolders() As Boolean
 On Error GoTo sInclSubfoldersGetErr
 sInclSubfolders = mvarsInclSubfolders
Exit Property

sInclSubfoldersGetErr:
 RaiseError MyUnhandledError, "cFindFile:sInclSubfolders Property Get" \_
 , "Fehler bei sInclSubfolders Property Get"
End Property

' Eigenschaft cFindFile.sFileToFind setzen
Public Property Let sFileToFind(ByVal vData As String)
 On Error GoTo sFileToFindLetErr
 mvarsFileToFind = vData
Exit Property

sFileToFindLetErr:
 RaiseError MyUnhandledError, "cFindFile:sFileToFind Property Let" \_
 , "Fehler bei sFileToFind Property Let"
End Property

' Eigenschaft cFindFile.sFileToFind lesen
Public Property Get sFileToFind() As String
 On Error GoTo sFileToFindGetErr
 sFileToFind = mvarsFileToFind
Exit Property

sFileToFindGetErr:
 RaiseError MyUnhandledError, "cFindFile:sFileToFind Property Get" \_
 , "Fehler bei sFileToFind Property Get"
End Property

' Eigenschaft cFindFile.sSearchpath setzen
Public Property Let sSearchpath(ByVal vData As String)
 On Error GoTo sSearchpathLetErr
 mvarsSearchpath = vData
Exit Property

sSearchpathLetErr:
 RaiseError MyUnhandledError, "cFindFile:sSearchpath Property Let" \_
 , "Fehler bei sSearchpath Property Let"
End Property

' Eigenschaft cFindFile.sSearchpath lesen
Public Property Get sSearchpath() As String
 On Error GoTo sSearchpathGetErr
 sSearchpath = mvarsSearchpath
Exit Property

sSearchpathGetErr:
 RaiseError MyUnhandledError, "cFindFile:sSearchpath Property Get" \_
 , "Fehler bei sSearchpath Property Get"
End Property

' Error Object setzen und an den Client übergeben
Private Sub RaiseError(ErrorNumber As Long, Source As String, strErrorText As String)
 Err.Raise ErrorNumber, Source, strErrorText
End Sub

Option Explicit
 


Private Sub Form\_Load()
 ' Klasse instanzieren
 Set nSearch = New cFindFile
End Sub

' Suchvorgang starten
Private Sub Command1\_Click()
'Dim nSearch As Variant
 List1.Clear ' Listbox loschen
 'bCancel = False ' Abbruchbedingung setzen
 
 With nSearch
 .sSearchpath = "Z:\test1\" ' Suchpfad
 .sFileToFind = "\*.\*" ' Suchnamen
 .sFileFlag = FILE\_ATTRIBUTE\_ALLTYPES ' Dateiattribute
 .sInclSubfolders = True ' Subdirs durchsuchen
 
 ' Suche starten
 Screen.MousePointer = 13
 .sStartSearch
 Screen.MousePointer = 0
 End With
End Sub

' Suchvorgang abbrechen!
Private Sub Command2\_Click()
 
 bCancel = True ' Abbruchbedingung setzen!
End Sub

'Ereignis stellt uns die Klasse bereit :wink:
Private Sub nSearch\_MatchFound(ByVal sFilename As String, \_
 ByVal sFilePath As String, \_
 ByVal sFiledate As Date, \_
 ByVal sFilesize As Long, \_
 ByVal sLastAccess As Date, \_
 ByVal sLastWrite As Date, \_
 ByVal sShortName As String)
 
 ' Listbox mit dem letzten Suchergebnis füllen
 List1.AddItem sFilePath & sFilename
 DoEvents
End Sub

'Auch das Ereignis stellt uns die Klasse zur Verfügung :smile:
Private Sub nSearch\_StopSearch(Cancel As Boolean)
 ' Wurde Stop gedrückt, dann Cancel für den
 ' Suchabbruch setzen
 If bCancel Then Cancel = bCancel
 DoEvents
End Sub

In der Klasse bringt er mir den Fehler --> Compile error – Invalid attribute in Sub or Funktion.
Und zwar in dieser Zeile --> Private WithEvents nSearch As cFindFile

Warum kennt er die Sub ned?

Gruß Rolf

Hallo Rolf,

weitesgehend hat dir ja Rainer schon geholfen.
Solltest du es dennoch nicht ans laufen bringen, so schmeisse
einfach deine Dateisuche raus und schreibe schnell eine neue.
Das ist echt net schwer. Lege diese Suche dazu in eine Klasse
und schon ist sie flexibel. Brauchst du sie nochmal, so binde
dann einfach die geschriebene Klasse in dein neues Project ein
und volla, fertig.

Wie so etwas ausschauen kann, schau :wink:

'Klasse cFindFile

Option Explicit

’ Benötigte API´s
Private Declare Function FindFirstFile Lib „kernel32“ Alias
„FindFirstFileA“ _
(ByVal lpFileName As String, _
lpFindFileData As WIN32_FIND_DATA) 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 Declare Function FileTimeToSystemTime Lib „kernel32“ _
(lpFileTime As FILETIME, _
lpSystemTime As SYSTEMTIME) As Long

’ Benutzerdefinierte Konstanten
Private Const MAX_PATH = 260
Private Const MAXDWORD = &HFFFF
Private Const INVALID_HANDLE_VALUE = -1
Private Const MyUnhandledError = 9999

’ Benutzerdefinierte Typen
Private Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type

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

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

’ Aufzählung für sFileFlag Eigenschaft
Public Enum FileFlag
FILE_ATTRIBUTE_READONLY = &H1
FILE_ATTRIBUTE_HIDDEN = &H2
FILE_ATTRIBUTE_SYSTEM = &H4
FILE_ATTRIBUTE_DIRECTORY = &H10
FILE_ATTRIBUTE_ARCHIVE = &H20
FILE_ATTRIBUTE_NORMAL = &H80
FILE_ATTRIBUTE_TEMPORARY = &H100
FILE_ATTRIBUTE_ALLTYPES = &H1B7
FILE_ATTRIBUTE_ALLTYPES_WITHOUT_DIR = &H1A7
End Enum

'lokale Variablen zum Zuweisen der Eigenschaften
Private mvarsSearchpath As String
Private mvarsFileToFind As String
Private mvarsInclSubfolders As Boolean
Private mvarsFileFlag As FileFlag

'RaiseEvent MatchFound[(arg1, arg2, … , argn)]
Public Event MatchFound(ByVal sFilename As String, _
ByVal sFilePath As String, _
ByVal sFiledate As Date, _
ByVal sFilesize As Long, _
ByVal sLastAccess As Date, _
ByVal sLastWrite As Date, _
ByVal sShortName As String)

'RaiseEvent StopSearch[(arg1)]
Public Event StopSearch(Cancel As Boolean)

Private Sub Class_Initialize()
'Die Klasse wird initialisiert.
sFileFlag = FILE_ATTRIBUTE_ALLTYPES
sInclSubfolders = True
End Sub

Private Sub Class_Terminate()
'Die Klasse wird aus dem Speicher entfernt.
End Sub

Public Sub sStartSearch()
Dim lFileToFind As String, lSearchpath As String, FileName
As String
Dim ShortName As String, DirName As String, DirNames() As
String
Dim DirCount As Integer, nDir As Integer, Cont As Integer,
I As Integer
Dim Filesize As Long, hSearch As Long
Dim Filedate As Date, LastAccess As Date, LastWrite As Date
Dim lInclSubfolders As Boolean, bCancel As Boolean
Dim sDate As SYSTEMTIME
Dim lFileFlag As FileFlag
Dim WFD As WIN32_FIND_DATA

On Error GoTo sStartSearchErr

’ Eigenschaften Property Get in lokale Variablen kopieren
lFileToFind = sFileToFind
lFileFlag = sFileFlag
lSearchpath = sSearchpath
lInclSubfolders = sInclSubfolders

’ Initialisieren der Variablen
If Right(lSearchpath, 1) „“ Then lSearchpath =
lSearchpath & „“
nDir = 0
DirCount = 0
ReDim DirNames(nDir)
Cont = True
bCancel = False

’ Die Suche geht los. Zuerst werden die Subfolders
ermittelt
hSearch = FindFirstFile(lSearchpath & „*“, WFD)
If hSearch INVALID_HANDLE_VALUE Then
Do While Cont
’ vbNullChar entfernen
DirName = Left$(WFD.cFileName, InStr(WFD.cFileName,
vbNullChar) - 1)

’ Prüfen, ob DirName auch wirklich ein Subfolder ist
If (DirName „.“) And (DirName „…“)
Then
If (WFD.dwFileAttributes And vbDirectory) =
FileFlag.FILE_ATTRIBUTE_DIRECTORY Then

’ Subfolder ins loakale Array speichern
DirNames(nDir) = DirName

’ Schleifenzähler erhöhen
DirCount = DirCount + 1
nDir = nDir + 1

’ Lokales Array neu dimensionieren
ReDim Preserve DirNames(nDir)
End If
End If

’ Nächster Subfolder ermitteln
Cont = FindNextFile(hSearch, WFD)

’ Geben wir der Methode ein wenig Zeit zum Atmen
DoEvents
Loop
Cont = FindClose(hSearch)
End If

’ Jetzt werden die zu findenden Dateien ermittelt
hSearch = FindFirstFile(lSearchpath & lFileToFind, WFD)
Cont = True
If hSearch INVALID_HANDLE_VALUE Then
While Cont
’ vbNullChar entfernen
FileName = Left$(WFD.cFileName, InStr(WFD.cFileName,
vbNullChar) - 1)

’ Prüfen, ob FileName ungleich . und … ist
If (FileName „.“) And (FileName
„…“) Then
’ Stimmt das FileAttribut mit Eigenschaft
sFileFlag überein
If (WFD.dwFileAttributes Or lFileFlag) = lFileFlag
Then

’ Dateigröße ermitteln
Filesize = (WFD.nFileSizeHigh * MAXDWORD) +
WFD.nFileSizeLow

’ Dateidatum/Zeit ermitteln
FileTimeToSystemTime WFD.ftCreationTime, sDate
With sDate
Filedate = CDate(.wDay & „.“ & .wMonth & „.“
& .wYear _
& " " & .wHour & „:“ & .wMinute & „:“ &
.wSecond)
End With

’ LastAccess ermitteln
FileTimeToSystemTime WFD.ftLastAccessTime,
sDate
With sDate
LastAccess = CDate(.wDay & „.“ & .wMonth &
„.“ & .wYear _
& " " & .wHour & „:“ & .wMinute & „:“ &
.wSecond)
End With

’ LastWrite ermitteln
FileTimeToSystemTime WFD.ftLastWriteTime, sDate
With sDate
LastWrite = CDate(.wDay & „.“ & .wMonth &
„.“ & .wYear _
& " " & .wHour & „:“ & .wMinute & „:“ &
.wSecond)
End With

’ ShortName 8.3 ermitteln
ShortName = Left$(WFD.cAlternate,
InStr(WFD.cAlternate, vbNullChar) - 1)

’ Und jetzt den Event aufrufen um die
Dateiinformationen zu übergeben
RaiseEvent MatchFound(FileName, lSearchpath,
Filedate, Filesize, _
LastAccess, LastWrite,
ShortName)
End If
End If

’ Nächste Datei ermitteln
Cont = FindNextFile(hSearch, WFD)

’ Geben wir der Methode ein wenig Zeit zum Atmen
DoEvents
Wend
’ Suche abgeschlossen
Cont = FindClose(hSearch)
End If

’ Sollen die Subfolders durchsucht werden?
If lInclSubfolders Then
’ Prüfen, ob im aktuellen Folder weitere Subfolder sind
If nDir > 0 Then
’ Rekursiver Aufruf der Methode mit Übergabe eines
neuen Subfolders
For I = 0 To nDir - 1
’ Event StopSearch aufrufen und prüfen ob Abbruch
’ durch Benutzer erfolgte
RaiseEvent StopSearch(bCancel)
If bCancel Then Exit Sub

’ neuer Suchpfad an Property Let sSearchpath
übergeben
sSearchpath = lSearchpath & DirNames(I)
’ neue Suche starten…
sStartSearch
Next I
End If
End If
Exit Sub

sStartSearchErr:
RaiseError MyUnhandledError, „cFindFile:sStartSearch
Method“ _
, „Fehler bei sStartSearch“
End Sub

’ Eigenschaft cFindFile.sFileFlag setzen
Public Property Let sFileFlag(ByVal vData As FileFlag)
On Error GoTo sFileFlagLetErr
mvarsFileFlag = vData
Exit Property

sFileFlagLetErr:
RaiseError MyUnhandledError, „cFindFile:sFileFlag Property
Let“ _
, „Fehler bei sFileFlag Property Let“
End Property

’ Eigenschaft cFindFile.sFileFlag lesen
Public Property Get sFileFlag() As FileFlag
On Error GoTo sFileFlagGetErr
sFileFlag = mvarsFileFlag
Exit Property

sFileFlagGetErr:
RaiseError MyUnhandledError, „cFindFile:sFileFlag Property
Get“ _
, „Fehler bei sFileFlag Property Get“
End Property

’ Eigenschaft cFindFile.sInclSubFolders setzen
Public Property Let sInclSubfolders(ByVal vData As Boolean)
On Error GoTo sInclSubfoldersLetErr
mvarsInclSubfolders = vData
Exit Property

sInclSubfoldersLetErr:
RaiseError MyUnhandledError, „cFindFile:sInclSubfolders
Property Let“ _
, „Fehler bei sInclSubfolders Property Let“
End Property

’ Eigenschaft cFindFile.sInclSubFolders lesen
Public Property Get sInclSubfolders() As Boolean
On Error GoTo sInclSubfoldersGetErr
sInclSubfolders = mvarsInclSubfolders
Exit Property

sInclSubfoldersGetErr:
RaiseError MyUnhandledError, „cFindFile:sInclSubfolders
Property Get“ _
, „Fehler bei sInclSubfolders Property Get“
End Property

’ Eigenschaft cFindFile.sFileToFind setzen
Public Property Let sFileToFind(ByVal vData As String)
On Error GoTo sFileToFindLetErr
mvarsFileToFind = vData
Exit Property

sFileToFindLetErr:
RaiseError MyUnhandledError, „cFindFile:sFileToFind
Property Let“ _
, „Fehler bei sFileToFind Property Let“
End Property

’ Eigenschaft cFindFile.sFileToFind lesen
Public Property Get sFileToFind() As String
On Error GoTo sFileToFindGetErr
sFileToFind = mvarsFileToFind
Exit Property

sFileToFindGetErr:
RaiseError MyUnhandledError, „cFindFile:sFileToFind
Property Get“ _
, „Fehler bei sFileToFind Property Get“
End Property

’ Eigenschaft cFindFile.sSearchpath setzen
Public Property Let sSearchpath(ByVal vData As String)
On Error GoTo sSearchpathLetErr
mvarsSearchpath = vData
Exit Property

sSearchpathLetErr:
RaiseError MyUnhandledError, „cFindFile:sSearchpath
Property Let“ _
, „Fehler bei sSearchpath Property Let“
End Property

’ Eigenschaft cFindFile.sSearchpath lesen
Public Property Get sSearchpath() As String
On Error GoTo sSearchpathGetErr
sSearchpath = mvarsSearchpath
Exit Property

sSearchpathGetErr:
RaiseError MyUnhandledError, „cFindFile:sSearchpath
Property Get“ _
, „Fehler bei sSearchpath Property Get“
End Property

’ Error Object setzen und an den Client übergeben
Private Sub RaiseError(ErrorNumber As Long, Source As String,
strErrorText As String)
Err.Raise ErrorNumber, Source, strErrorText
End Sub

Um die Klasse zu verwenden, brauchst du nur noch wenige Zeilen
Source. Da die Suche nun in einer Klasse ausgelagert ist, ist
es ja ein Object und hat somit Eigenschaften und kann
Ereignisse auslösen, welche dies auch macht :wink:

Also wie gesagt, aufrufen oder starten tust du die Suche via

Option Explicit

’ Klasse mit Ereignissen!
Private WithEvents nSearch As cFindFile

’ Für Abbruch-Button
Private bCancel As Boolean

Private Sub Form_Load()
’ Klasse instanzieren
Set nSearch = New cFindFile
End Sub

’ Suchvorgang starten
Private Sub Command1_Click()
List1.Clear ’ Listbox loschen
bCancel = False ’ Abbruchbedingung setzen

With nSearch
.sSearchpath = „C:“ ’ Suchpfad
.sFileToFind = „*.ini“ ’ Suchnamen
.sFileFlag = FILE_ATTRIBUTE_ALLTYPES ’ Dateiattribute
.sInclSubfolders = True ’ Subdirs durchsuchen

’ Suche starten
Screen.MousePointer = 13
.sStartSearch
Screen.MousePointer = 0
End With
End Sub

’ Suchvorgang abbrechen!
Private Sub Command2_Click()

bCancel = True ’ Abbruchbedingung setzen!
End Sub

'Ereignis stellt uns die Klasse bereit :wink:
Private Sub nSearch_MatchFound(ByVal sFilename As String, _
ByVal sFilePath As String, _
ByVal sFiledate As Date, _
ByVal sFilesize As Long, _
ByVal sLastAccess As Date, _
ByVal sLastWrite As Date, _
ByVal sShortName As String)

’ Listbox mit dem letzten Suchergebnis füllen
List1.AddItem sFilePath & sFilename
DoEvents
End Sub

'Auch das Ereignis stellt uns die Klasse zur Verfügung :smile:
Private Sub nSearch_StopSearch(Cancel As Boolean)
’ Wurde Stop gedrückt, dann Cancel für den
’ Suchabbruch setzen
If bCancel Then Cancel = bCancel
DoEvents
End Sub

Schaut vorerst nach viel Arbeit aus, ist es aber nicht und wie
du siehst, ist sie nicht nur schnell, sondern auch arg
felxibel :smile:
Auch kannst du hier schon deine Ergebnisse verarbeiten, obwohl
die Suche nicht beendet ist. Auch kannst du diese vorzeitig
abbrechen etc. :smile:

MfG Alex

@Rainer, waere das evtl. etwas für die FAQ ?
Wenn ja, dann teste es aber vorher mal bitte :smile:

Hi Alex,

erster Test erfolgreich, läuft! :smile:

Aber das Oroginal hat sollte etwas anderes tun.

Der Code soll alle Dateien nach einem bestimmten Inhalt durchsuchen und die dann auflisten. Es ging um den Inhalt der Dateien, nicht um die Dateinamen. Excel kann das scheinbar, verwunderlich ist das nicht, Windows kann das ja auch. Wie das mit VB geht weiß ich nicht.

Gruß Rainer

1 Like

Hallo Alex,

ich habe noch ein paar Zeilen Kommentar eingefügt.

Dein Beitrag ist jetzt FAQ:3000 . :smile:

Danke!

Gruß Rainer

Jep, es passt :smile:
Hab den FAQ-Beitrag genommen - jetzt funtzt es.

Danke an Rainer und Anno resp. Alex :wink:

Gruß Rolf

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Noch ne kleine Frage dazu…
die Suche scheint ja nur nach Filenamen zu sichen aber nicht nach File-Inhalten.

Ist hier eine Inhaltssuche/rekursive Suche überhaupt möglich?

Gruß Rolf

Hallo Rolf,

Sodala - erster Zwischenbericht,

Na dann schauen wir einmal :smile:

habe ne Klasse „cFindFile“ erstellt - hier habe ich
eingefügt (bitte berichtigt mich wenns falsch is)

Ja und da liegt schon der erste Fehler!

Kopiere Dir einfach den Code der Klasse. Den ganzen! Erstelle dir eine neue Klasse. Nenne Sie cFindFile und trage dort den Source ein. Mehr nicht! Die Klasse lässt du nun so! Wie ich anhand deines Postings gelesen habe, hast du nicht alles der Klasse kopiert und teilweise dortrein Code kopiert der net darein gehört, wie zum Bsp. das WithEvents. Aber dazu später mehr :wink:

und dann meine Form mit 2 x Command und eine Listbox

Option Explicit



> Public Sub sStartSearch()

Hier habe ich den Rest der Sub mal gelöscht, denn diese Sub gehört in die Klasse und stellt damit die Methode sStartSearch da, die wir später aufrufen!


> ' Eigenschaft cFindFile.sFileFlag setzen  
> Public Property Let sFileFlag(ByVal vData As FileFlag)  
> On Error GoTo sFileFlagLetErr  
> mvarsFileFlag = vData  
> Exit Property  
>   
> sFileFlagLetErr:  
> RaiseError MyUnhandledError, "cFindFile:sFileFlag Property  
> Let" \_  
> , "Fehler bei sFileFlag Property Let"  
> End Property

Auch saemtliche Eigenschaften gehören in die Klasse!

Ich denke mal hier ist der Source der Form?




> Option Explicit




> Private Sub Form\_Load()  
> Set nSearch = New cFindFile 'Richtig, hier erstellen wir eine Instanz der Klasse  
> End Sub  
>   
> ' Suchvorgang starten  
> Private Sub Command1\_Click()  
> 'Dim nSearch As Variant  
> List1.Clear ' Listbox loschen  
> 'bCancel = False ' Abbruchbedingung setzen  
>   
> With nSearch  
> .sSearchpath = "Z:\test1\" ' Suchpfad  
> .sFileToFind = "\*.\*" ' Suchnamen  
> .sFileFlag = FILE\_ATTRIBUTE\_ALLTYPES ' Dateiattribute  
> .sInclSubfolders = True ' Subdirs durchsuchen  
>   
> ' Suche starten  
> Screen.MousePointer = 13  
> .sStartSearch 'Hier starten wir die Methode  
> Screen.MousePointer = 0  
> End With  
> End Sub  
>   
> ' Suchvorgang abbrechen!  
> Private Sub Command2\_Click()  
>   
> bCancel = True ' Abbruchbedingung setzen!  
> End Sub  
>   
> 'Ereignis stellt uns die Klasse bereit :wink:  
> Private Sub nSearch\_MatchFound(ByVal sFilename As String, \_  
> ByVal sFilePath As String, \_  
> ByVal sFiledate As Date, \_  
> ByVal sFilesize As Long, \_  
> ByVal sLastAccess As Date, \_  
> ByVal sLastWrite As Date, \_  
> ByVal sShortName As String)  
>   
> ' Listbox mit dem letzten Suchergebnis füllen  
> List1.AddItem sFilePath & sFilename  
> DoEvents  
> End Sub  
>   
> 'Auch das Ereignis stellt uns die Klasse zur Verfügung :smile:  
> Private Sub nSearch\_StopSearch(Cancel As Boolean)  
> ' Wurde Stop gedrückt, dann Cancel für den  
> ' Suchabbruch setzen  
> If bCancel Then Cancel = bCancel  
> DoEvents  
> End Sub

In der Klasse bringt er mir den Fehler --> Compile error –
Invalid attribute in Sub or Funktion.
Und zwar in dieser Zeile --> Private WithEvents
nSearch As cFindFile

Das ist vollkommen richtig! Mit der Zeile machst du nichts weiter wie

Dimensoniere mir die Variable nSearch als als cFindFile und stelle mir deren Ereignisse zur Verfügung! Mit dem Aufruf von Set nSearch … instanzierst du dann die Klasse und nSearch zeigt nicht mehr auf Nothing.
Das aber wiederrum gehört in die Form und nicht in die Klasse!

Ich denke mal du hast da ein kleines missverstaendnis Rolf.

Du hast doch dein Project. Das lässt du so wie es ist. Nur die Suche wirfst du bei dir raus.Dann klickst du rechts im Projectmapppen Explorer ( Dort wo du neue Formulare einfügen kannst oder halt im Menu) auf Neu -> Klassenmodul. Daraufhin erstellt dir VB ein neues Klassenmodul.In dem Eigenschaftsfenster bennenst du dieses nach cFindFile um. Danach kopierst du dir dort den Source der Klasse rein. Danach speicherst du dein Project ab. In deinem Formular dann wo du die Suche brauchst, kopierst du dir dann den Source für die Form rein. Danach findest du bei deinen Objecten, dort wo auch die Textboxen, Labels etc. sind ein neues Object Names nSearch. Wenn du dies makierst kannst du nun die Ereignisse auswaehlen die dir die Klasse bereitsstellt :smile:

Weisst du nun wie ich das meine?
Ich bin leider bis zum 25.1.09 net daheim und habe kein VB zur Hand. Aber ich denke mal das wenn du es nicht hinbekommst du dein Project auch mal fix zu Rainer schicken kannst und er pflegt dir dann sicherlich die Klasse ein, welches ja keine 5 Minuten dauert :smile:

Alternativ poste mal bitte den Source Code Deiner Form und den deiner Klasse, getrennt so das man genau erkennt wie du was geschrieben hast:smile: Dann kann ich dir auch übers Forum helfen :smile:

Ich wünsche euch allen noch einen guten Rutsch ins neue Jahr :smile:

MfG Alex

Gruß Rolf

1 Like

Sorry Anno,

war hier zu fix mit dem rumheulen :smile:)

Mittlerweile funtzt es. Nur wie oben beschrieben, ist es leider keine Inhaltssuche sondern ne Dateisuche. So funktioniert es und er findet mir auch alle Files die ich in den Ordnern haben. Nur leider eben nicht den Dateiinhalt.

Die Excelsuche konnte das über das Shell…
Jetzt bin ich am „checken“ :smile:)) wie ich das einbau, das er mir nach Dateiinhalten sucht.
Ansonsten ist dein Code genial! Und auch leicht verständlich. Habe nur wir gesagt zufrüh rumgeheult! :smile:))

Gruß Rolf

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Rolf,

die Suche sucht nur nach Dateinamen. Aber die Suche löst ja das Event MatchFound aus! Dies mach dir zu nutzen. Das File was du da bekommst öffne einfach, lese den Inhalt ein und suche nach der Zeichenfolge. Wird sie gefunden, so trage das File in die Liste ein, wird es nicht gefunden, so verwerfe die Daten einfach. Alternativ, kannst du die Klasse mit einer Eigenschaft erweiteren und dann implementieren das das gefundene File nach einen gewissen Inhalt durchsucht wird :smile:

Wenn ich Anfang naechstes Jahr mal Zeit habe, werde ich die Klasse mal erweitern und dann hier posten, sofern das kein anderer macht :wink:

MfG Alex

Hallo Rolf,

Ist hier eine Inhaltssuche/rekursive Suche überhaupt möglich?

wenn ich Alex so lese … ohne die Datei zu öffnen wohl nicht.
Aber dazu eine kleine Funktion zu schreiben ist ja kein Problem. Vorschlag mit Anwendungsbeispiel:

Private Declare Function PathFileExists Lib "shlwapi.dll" \_
 Alias "PathFileExistsA" (ByVal pszPath As String) As Long

Private Sub Command1\_Click()
 Me.Caption = CheckInhalt("C:\Test.txt", "Probe")
End Sub

Private Function CheckInhalt(ByVal Datei As String, ByVal SuchString As String) As Boolean
 Dim Bytes As Long, ff As Integer, Txt As String
 If PathFileExists(Datei) Then
 Bytes = FileLen(Datei)
 Txt = Space(Bytes)
 ff = FreeFile
 Open Datei For Binary As #ff
 Get #ff, , Txt
 Close #ff
 If InStr(Txt, SuchString) Then
 CheckInhalt = True
 Else
 CheckInhalt = False
 End If
 Else
 CheckInhalt = False
 End If
End Function

Gruß Rainer

Moin, moin und n gutes Neues mal in die Runde,

also dein Code schaut gut aus. Nur soll er mir die Caption als Variable erkennen.

Habe

pfad = strVerzeichnis & "\" & strDirDate & "\" & strSender & "\" & "\*.\*"

und

sInhalt = txtSuchBox

(txtSuchBox - da geb ich den gesuchten String ein)

Me.Caption = CheckInhalt(pfad, sInhalt)

So sollte es doch funtzten oder? Hier finder er aber nichts. Wenn ich

CheckInhalt("C:\Test.txt", "Probe")

meldet er True - also die Datei hab ich erstellt auf C: :smile:), bei der „Variblen“ meldet er mir False, obwohl die Datei mit dem Inhalt - welchen ich ihm ja in der Suchbox angeben habe.

Gruß Rolf

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Moin Rolf,

Nur soll er mir die Caption als Variable erkennen.

? Das ist verschieden interpretierbar.

pfad = strVerzeichnis & „“ & strDirDate & „“ & strSender & „“ & „*.*“
sInhalt = txtSuchBox

Me.Caption = CheckInhalt(pfad, sInhalt)

So sollte es doch funtzten oder? Hier finder er aber nichts.

Beim Code in dieser Form kannst du keine Jokerzeichen benutzen

Klappt:

Private Sub Command1\_Click()
 Me.Caption = CheckInhalt("C:\test.txt", "Probe")
End Sub


Klappt nicht:

Private Sub Command1\_Click()
 Me.Caption = CheckInhalt("C:\*.\*", "Probe")
End Sub

Gruß
Reinhard

Servus Reinhard,

schade, der „Pfad“ muss variabel sein.
Sonst bringt es mir nichts :frowning:
Versuche es mal über fso

Set fso = CreateObject("Scripting.FileSystemObject")
Quelle = pfad
Typ = LCase("txt")
Suchbegriff = txtSuchBox

For Each File In fso.GetFolder(Quelle).Files
 If LCase(fso.GetExtensionName(File.Name)) = Typ Then
 inhalt = fso.OpenTextFile(File).ReadAll
 If InStr(1, inhalt, Suchbegriff, vbTextCompare) Then
 'ausgabe.WriteLine File.Name
 ListBox2.AddItem File.Name
 End If
 End If
Next

Das scheint mir schon fast hinzuhauen. Er findet zumindest in dem Verzeichnis was ich im über pfad angeben die txt-Files.
Nur den Inhalt noch nicht wirklich…Das Jahr fängt ja echt klasse an :smile:)))

Gruß Rolf

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Moin Rolf,

Ich wünsche auch allen ein schönes Neues …! :smile:
Reinhard war ja schneller als ich, ich muss trotzdem noch mal fragen.

Nur soll er mir die Caption als Variable erkennen.

Me.Caption ist eine Eigenschaft der Form, daraus kannst Du keine Variable machen. Aber natürlich kannst Du an die Stelle eine variable schreiben oder Das Ergebnis auswerten, dazu ist der boolsche Wert ja da.

Habe

pfad = strVerzeichnis & „“ & strDirDate & „“ &
strSender & „“ & „*.*“

und

sInhalt = txtSuchBox

(txtSuchBox - da
geb ich den gesuchten String ein)

Me.Caption = CheckInhalt(pfad, sInhalt)

So sollte es doch funtzten oder?

Ja, das soll gehen.

Hier finder er aber nichts.

Dann liegt das Problem am Inhalt der Variablen.
In Pfad muss ein tatsächlicher Pfad zu einer Datei stehen und in sInhalt ein String, der in der Datei zu finden ist.

Setze einen Stoppunkt und sieht nach, was in Deinen Variablen steht.
Du kannst ja erst mal wieder „C:\Test.Txt“ und „Probe“ hineinschreiben.

Im Moment musst Du dabei auch auf Groß-, Kleinschreibung achten. Wenn Du das nicht möchtest, dann bau in der Funktion UCase() oder LCase() in den Code ein.

In Deinem Programm wendest Du die Funktion nach der Klasse von Alex an, da kommt in ‚Pfad‘ dann der Pfad, der in die Listbox geschrieben werden soll.

Etwa …

If CheckInhalt(pfad, sInhalt) 
 List1.additem pfad 
End If

Hat Reinhard Recht und Du verwendest Sterne im Pfad oder im Suchstring? Da hat Reinhard natürlich Recht, das funktioniert nicht.

Gruß Rainer

schade, der „Pfad“ muss variabel sein.

Hallo Rolf,

ist er doch, im Code von Alex.

Der Code ist starr, mache ihn erst mal flexibel indem du in der Form einige Textfelder anlegst. In diese Textfelder trägst du zur Laufzeit dann die Parameter.

Im Code dann diese Stelle so abändern:

.sSearchpath = Textbox1 ’ Suchpfad
.sFileToFind = Textbox2 ’ Suchnamen
.sFileFlag = FILE_ATTRIBUTE_ALLTYPES ’ Dateiattribute
.sInclSubfolders = Textbox3 ’ Subdirs durchsuchen

In der Prozedur nSearch_MatchFound(…)
hast du ja vor dieser Codezeile

List1.AddItem sFilePath & sFilename

mittels des Codes von Rainer die Möglichkeit nur die dateien auflisten zu lassen die im Inhalt deinen Suchbegriff haben.

z.B. so

if CheckInhalt(sFilePath & sFilename, textbox4)=true then
 List1.AddItem sFilePath & sFilename
end if

Der Code von Alex ist schon für den Ausbau vorgesehen, so könntest du auch nach Dateigrößen, dateidatümern u.ä. suchen lassen.

PS: Was issen mit meiner Nachfrage zu Excel?

Gruß
Reinhard

2 Like

Servus Reinhard,

hier der Shell vom Excel -->

 If txtSpeicherPfad = "" Then
 MsgBox "Bitte Ordner anlegen"
 cmdOrdnerAnlegen.SetFocus
 Else
 If txtSuchBox = "" Then
 txtSuchBox = "\*"
 'txtSuchBox.SetFocus
 Else
 Set objShell = CreateObject("WScript.Shell")
 CommandLine = "%comspec% /c findstr /m /s /i /c:""" & Suchbegriff & """ """ & pfad & """ "

Set objExecObject = objShell.Exec(CommandLine)
 If Not objExecObject.StdOut.AtEndOfStream Then
 Filelist = Split(Trim(objExecObject.StdOut.ReadAll()), vbCrLf)
 For i = 0 To UBound(Filelist) - 1
 ListBox2.AddItem Filelist(i)
 Label54 = Filelist(i)
 Next
 Else
 MsgBox "Datei nicht gefunden"
 txtSuchBox.SetFocus
 End If
 End If
 End If

End Sub

Wenn du willst kann ich dir das gesamte Excel (mir Form etc…)zur Verfügung stellen.

Deinen Code bau ich mal ein und meld mich gleich wieder :smile:)

Gruß Rolf

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Hallo Reinhard,

In der Prozedur nSearch_MatchFound(…)
hast du ja vor dieser Codezeile

List1.AddItem sFilePath & sFilename

mittels des Codes von Rainer die Möglichkeit nur die dateien
auflisten zu lassen die im Inhalt deinen Suchbegriff haben.

danke für die Hilfe, genau so war’s gemeint! :smile:

Gruß Rainer

Servus Reinhard,

nun bringt er mir nen Type mismatch bei -->

'Ereignis stellt uns die Klasse bereit
Private Sub nSearch\_MatchFound(ByVal sFilename As String, \_
 ByVal sFilePath As String, \_
 ByVal sFiledate As Date, \_
 ByVal sFilesize As Long, \_
 ByVal sLastAccess As Date, \_
 ByVal sLastWrite As Date, \_
 ByVal sShortName As String)
 Dim txtSuchBox As String
 Dim CheckInhalt As Variant
 Dim Suchbegriff As String
 'Listbox mit dem letzten Suchergebnis füllen
 Suchbegriff = txtSuchBox

If CheckInhalt(sFilePath & sFilename, Suchbegriff) = True Then
 ListBox2.AddItem sFilePath & sFilename
 Else
 MsgBox "nix da"
End If
 DoEvent

Ich glaub ich überspring das Jahr…so wie das anfängt! Mann mann mann :smile:))))

Gruß Rolf

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]