UBound --> compile error expected: identifier

Hallo mal wieder :smile:

Habe - ich weiss ned ob sich noch wer dran errinnert - die Filesuche aus Excel/VBA in VB5 nun geschrieben, bzw bin ich grad dabei.
Soweit so gut.

Hier der VB5 Coder -->

 Option Explicit
 
 Private Sub Form\_Activate()
 Dim Datum As Date
 Datum = Format(Now, "dd.mm.yyyy")
 txtKW = KalenderWoche(Datum)
 txtDatum = Format(Now, "dd.mm.yyyy hh.mm.ss")
 DTPicker3.Value = Now
 cmdRechnungKopieren.Enabled = False

End Sub
Private Sub cmdShareÖffnen\_Click()
 Dim strDirPath As String
 strDirGesamt = "Z:\test\"
 Shell "explorer.exe /e, " & strDirGesamt, vbNormalFocus
End Sub

Private Sub cmdRechnungSuchen\_Click()
 Dim sInhalt As String
 Dim strDirDate As String
 Dim strSender As String
 Dim strVerzeichnis As String
 Dim pfad1 As String
 Dim pfad2 As String
 Dim Split As Variant
 Dim nDate As Date
 Dim pfad As String
 Dim Suchbegriff As String
 Dim objShell As Variant
 Dim CommandLine As Variant
 Dim objExecObject As Variant
 Dim Filelist As String
 Dim i As Integer
**Dim UBound As String**



 If OptionButton1.Value = True Then
 strVerzeichnis = "Z:\test1"
 End If

 If OptionButton2.Value = True Then
 strVerzeichnis = "Z:\test2"
 End If

 If OptionButton3.Value = True Then
 strVerzeichnis = "Z:\test3"
 txtSenderID = ""
 End If

strDirDate = DTPicker3
strSender = txtSenderID
nDate = Format(DTPicker3, "yymmdd")
strDirDate = nDate
sInhalt = txtSuchBox
pfad1 = strVerzeichnis & "\" & strDirDate & "\" & strSender & "\*.\*"
pfad2 = strVerzeichnis & "\" & "" & "\" '& strSender

If CheckBox1.Value = True Then
pfad = pfad2
Else
pfad = pfad1
End If
Label2 = pfad

Suchbegriff = txtSuchBox
ListBox2.Clear

 If txtSpeicherPfad = "" Then
 MsgBox "Bitte erst Ordner anlegen"
 cmdOrdnerAnlegen.SetFocus
 Else
 If txtSuchBox = "" Then
 txtSuchBox = "\*"

 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)
 Next
 Else
 MsgBox "Datei nicht gefunden"
 txtSuchBox.SetFocus
 End If
 End If
 End If

End Sub

Private Sub cmdRechnungKopieren\_Click()
Dim strDirDate As String
Dim strDirPath As String
Dim strCopyVon As String
Dim strSender As String
Dim pfad As String
Dim i As Long

 nDate = Format(frmTickets.DTPicker3, "yymmdd")
 strDirDate = nDate
 strSender = txtSenderID
 strDirPath = txtSpeicherPfad

 For i = 0 To ListBox2.ListCount - 1
 If ListBox2.Selected(i) = True Then
 strCopyVon = ListBox2.List(i)
 strCopyVonPath = Left(strCopyVon, InStrRev(strCopyVon, "\") - 1)
 strCopyVonFolder = Mid(strCopyVonPath, InStrRev(strCopyVonPath, "\") + 1)

 CreateObject("Scripting.FileSystemObject").CopyFolder strCopyVonPath, strDirPath & "\" & strCopyVonFolder
 End If
 Next i
End Sub
Private Sub cmdOrdnerÖffnen\_Click()
 Dim strDirPath As String
 strDirPath = txtSpeicherPfad
 Shell "explorer.exe /e, " & strDirPath, vbNormalFocus
End Sub
Private Sub CommandButton8\_Click()

Dim Path As String
Dim Pic As String
If ListBox2.ListIndex = -1 Then
 MsgBox "Keine Einträge vorhanden!", vbCritical
 Exit Sub
End If
Path = Left(ListBox2.List(ListBox2.ListIndex), InStrRev(ListBox2.List(ListBox2.ListIndex), "\"))
If Not (FileExists(ListBox2.List(ListBox2.ListIndex))) Then
 MsgBox "BildDatei wurde nicht gefunden!"
 Exit Sub
Else
'Hier die Extension prüfen und ggfls. Meldung anzeigen
 Label65.Caption = Path
 Image1.Picture = LoadPicture(ListBox2.List(ListBox2.ListIndex))
 Shell "explorer.exe /e," & Path, vbNormalFocus
End If
End Sub

Private Function FileExists(sFile As String)
On Error Resume Next
Dim x As Integer
x = GetAttr(sFile)
FileExists = Err.Number = 0
End Function

Private Sub List1\_Click()
 Call LoadImg
End Sub

Private Sub Image1\_Click()
Dim imgBild As String

imgBild = "C:\Dokumente und Einstellungen\rosenmuellerm\Desktop\test.gif"
End Sub

Private Sub Label62\_Click()
txtSenderID.Text = "0\_0"
End Sub

Private Sub ListBox2\_Change()
 cmdRechnungKopieren.Enabled = True
End Sub

Private Sub cmdOrdnerAnlegen\_Click()
Dim strDirPath As String, N As Long, eing
strDirPath = "C:\test\" & txtSenderID & " - " & "KW" & txtKW & " - " & Format(Date, "ddmmyy")
If txtSenderID = "" Then
MsgBox "Bitte Sender\_ID eingeben"
Else
 If Dir(strDirPath, vbDirectory) = "" Then
 MkDir strDirPath
 txtSpeicherPfad = strDirPath
 Else
 While Dir(strDirPath, vbDirectory) ""
 N = N + 1
 strDirPath = "C:\test\" & txtSenderID & "\_" & N & " - " & "KW" & txtKW & " - " & Format(Date, "ddmmyy")
 Wend
 eing = MsgBox("Ordner schon vorhanden - Mit neuer Nummerierung angelegen?", vbOKCancel)
 txtSpeicherPfad = "Ordner nicht angelegt"
 If eing vbOK Then Exit Sub
 txtSpeicherPfad = strDirPath
 MkDir strDirPath
 End If
End If
End Sub
Private Sub DTPicker3\_CallbackKeyDown(ByVal KeyCode As Integer, ByVal Shift As Integer, ByVal CallbackField As String, CallbackDate As Date)
 Dim nDate As Date
End Sub

Private Function KalenderWoche(Datum As Date) As Integer
 Dim tmp As Double
 tmp = DateSerial(Year(Datum + (8 - WeekDay(Datum)) Mod 7 - 3), 1, 1)
 KalenderWoche = (Datum - tmp - 3 + (WeekDay(tmp) + 1) Mod 7) \ 7 + 1
End Function
Private Function Datum\_aus\_Woche(Jahr As Integer, Woche As Integer)
 Dim intTag As Integer, intWoche As Integer
 If Jahr = 0 Then
 Datum\_aus\_Woche = 0
 Exit Function
 End If
 intTag = 1
 intWoche = KalenderWoche(DateSerial(Jahr, 1, 1))
 If intWoche 1 Then
 Do Until KalenderWoche(DateSerial(Jahr, 1, intTag)) = 1
 intTag = intTag + 1
 Loop
 Else
 Do Until KalenderWoche(DateSerial(Jahr, 1, intTag)) 1
 intTag = intTag - 1
 Loop
 intTag = intTag + 1
 End If
 Datum\_aus\_Woche = DateSerial(Jahr, 1, intTag) + (Woche - 1) \* 7
End Function

Sub OptionButton1\_Click()
 If OptionButton1.Value = True Then
 txtSenderID.Text = "1111\_"
 End If
End Sub

Sub OptionButton2\_Click()
 If OptionButton2.Value = True Then
 txtSenderID.Text = "2222\_"
 End If
End Sub

Sub OptionButton3\_Click()
 If OptionButton3.Value = True Then
 txtSenderID.Text = ""
 End If
End Sub

Private Sub txtDate\_Change()
 Dim Zeit1
 Zeit1 = Time
End Sub
Private Sub cmdEnde\_Click()
 Unload frmTickets
End Sub

nun, beid er Suche „Private Sub cmdRechnungSuchen_Click()“ bringt er bei Ubound eben o. g. Fehler --> compile error expected: identifier.

Hat hier jemand ne Idee was ich hier falsch mache. Als was soll UBound deklariert werden?

Gruß Rolf

Hallo Rolf,

Hat hier jemand ne Idee was ich hier falsch mache. Als was
soll UBound deklariert werden?

Du verwendest ‚Ubound‘ als Variablenname. Das geht nicht, weil Ubound eine Funktion ist. Ubound gibt Dir den größtmöglichen Index eines Arrays zurück. Beispiel:

Dim Arr(2 to 33) As Integer
Dim Max As Integer, Min As Integer

Max = Ubound(Arr)
Min = Lbound(Arr)

Dann enthält Max den Wert 33 und Min den Wert 2.

Gruß Rainer

Ebent Ebent,

aber wenn ich UBound nicht als Variable „deklariere“ bringt er Fehler
–> Compile Error: Expected array…

Wo/wie kennzeichne ich UBound als Funktion?

Gruß Rolf

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

Hallo Rolf,

aber wenn ich UBound nicht als Variable „deklariere“ bringt er
Fehler
–> Compile Error: Expected array…

Wo/wie kennzeichne ich UBound als Funktion?

Ubound kannst Du nicht als Funktion kennzeichnen, das ist immer eine.
Das ist eines der Schlüsselwörter, die man eben nicht als Variablennamen verwenden kann, wie Me, To, For, Next …

Die einzige Abhilfe, denk Dir einen anderen Namen für Deine Variable aus. Schlüsselwörter kann man nicht als Variablennamen verwenden.

‚Dim Ubound As …‘ geht einfach nicht, wie auch ‚Dim me As …‘ nicht geht. Ubound ist nur eine Möglichkeit zu erfahren, wie groß ein Array ist.

Gruß Rainer

Hallo Rolf,

ich habe mir Deinen Code noch einmal angesehen, außerhalb der Deklaration verwendest Du UBound ja auch nicht als Variable, sondern richtig.

Daß Du ein Problem bei der verwendung bekommst liegt daran, daß Du Split nicht mit einem Array sondern mit einer variablen verwendest.
Wirf die Zeile ‚Dim Ubound as String‘ einfach weg.

Dein Problem ist:

Dim Filelist As String

Du musst Filelist als Array deklarieren:

Dim Filelist() As String

Dir fehlen nur die beiden Klammern.

Gruß Rainer

Hallo Rainer,

klappt auch nicht leider, hier meldet er mir -->
can’t assign to array

Irgendwie aber auch mal nett, alle Fehlermeldung von VB so der Reihe nach kennenzulernen! :smile:))

Habe jetzt -->

 Dim sInhalt As String
 Dim strDirDate As String
 Dim strSender As String
 Dim strVerzeichnis As String
 Dim pfad1 As String
 Dim pfad2 As String
 Dim Split As Variant
 Dim nDate As Date
 Dim pfad As String
 Dim Suchbegriff As String
 Dim objShell As Variant
 Dim CommandLine As Variant
 Dim objExecObject As Variant
 Dim Filelist() As String
 Dim i As Integer

und hier kommt dann der Fehler -->

 If txtSpeicherPfad = "" Then
 MsgBox "Bitte erst Ordner anlegen"
 cmdOrdnerAnlegen.SetFocus
 Else
 If txtSuchBox = "" Then
 txtSuchBox = "\*"

 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 LBound(Filelist) - 1
 ListBox2.AddItem Filelist(i)
 Next
 Else
 MsgBox "Datei nicht gefunden"
 txtSuchBox.SetFocus
 End If
 End If
 End If

Fehlerzeile hab ich dir bold gemacht.

Gruß Rolf

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

Hallo Rolf,

klappt auch nicht leider, hier meldet er mir -->
can’t assign to array

Irgendwie aber auch mal nett, alle Fehlermeldung von VB so der
Reihe nach kennenzulernen! :smile:))

*gg* ja, VB zeigt immer den ersten Fehler, den es findet. Ist der beseitigt, läuft es weiter bis zum Nächsten. :smile:

Ich verstehe Dich richtig, daß VB bis zu der markierten zeile gelaufen ist und dort den fehler meldet? Welchen Inhalt hat in dem Moment:
Trim(objExecObject.StdOut.ReadAll()) ?
Damit Split funktionieren kann, müsste da etwas stehen wie …

C:\Text\Text1.txt
c:\Test\Text2.txt

Wenn Dir der Debugger das so nicht zeigt, füge mal ein…

Dim Test As String
Test = objExecObject.StdOut.ReadAll()

… dann kannst Du, wenn der Fehler aufgetreten ist, den Mauszeiger auf die Variable ‚Test‘ stellen und deren Inhalt wird als Tooltiptext angezeigt. (Nur falls Du den Debugger noch nicht kennst)

Ich vermute, der String wird leer sein.

Dein Projekt nachzubauen wäre einiges an Arbeit, wenn das nötig ist, dann schreib’ mal eine Liste mit den Steuerelementen, die auf der Form liegen, das ist dann einfacher als den code zu durchforsten und die Namen herauszusuchen.

Gruß Rainer

Servus,

er meldet im Debbuger-Fenster -->
Watch : : Split : : Empty : frmTickets.cmdRechnungSuchen_Click

Scheinbar findet er keine Datei…
Der Pfad stimmt aber, den lass ich mir anzeigen und da befindet sich ein Textfile drin.

Gruß Rolf

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

Hallo Rolf,

Scheinbar findet er keine Datei…
Der Pfad stimmt aber, den lass ich mir anzeigen und da
befindet sich ein Textfile drin.

dann liegt das Problem in dem Pogrammteil, in dem Du die den VBS-Code verwendest. Du hast den zweiten Schritt vor dem Ersten getan.

Bau Dir erst mal eine Funktion, die die Fileliste in einem Textfeld anzeigt und bring erst mal das zum Laufen. Ob und wenn ja was da falsch ist weiß ich nicht, die Funktion, die Du da verwendest habe ich noch nie gesehen. Was Du da in Commandline schreibst, verstehe ich auch nicht Ansatzweise. Scheinbar ist das nicht korrekt.

Gruß Rainer

Hallo,
fast vergessen,

hier die Steuerelemente

5 x textbox - txtDatum, txtKW, txtSenderID, txtSpeicherPfad, txtSuchBox,
1 x dtpicker - DTPicker3
1 x listbox - ListBox2
3 x radiobutton - OptionButton1, OptionButton2, OptionButton3
6 x commandbutton - cmdOrdnerAnlegen, cmdRechnungSuchen, cmdRechnungKopieren, cmdOrdnerÖffnen, cmdShareÖffnen, cmdEnde

Gruß Rolf

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

Hmmm, Hallo,

also grundsätzlich ist das richtig. Da es in Excel 2007 kein Filesearch mehr gibt habe ich es über das Com gelöst.
Das funktioniert auch, also im VBA.
Grundsätzlich möcht ich das ganze aber als StandAlone haben, daher nun auf VB5.

Es geht halt darum das er mir hier Ordner bzw Files nach Textinhalten durchsucht, diese in der Listbox2 anzeigt und dann eben die anderen Funktionen wie kopieren anzeigen etc zulässt.
Thats it :smile:)

Schade, wäre auch zuuuu einfach gewesen, dass hier nur in VB „umzuschreiben“ :frowning:(

Gruß Rolf

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

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