Stringsuche in Datei mit VBA
Dateiinhalte suchen und Dateiname mit Pfad ausgeben
Hallo zusammen,
bin seit geraumer Zeit auf der Suche nach ner Lösung.
Habe einen Suchcode der mir supergut die Dateien findet und auch anzeigt, das Problem ist, das ich in die Suche den korrekten Dateinnamen eingeben muss.
Was ich aber brauche ist das er mit nach Dateiinhalten sucht. Also quasi die Desktopsuche von MS.
Habe es über SearchFile versucht - das klappt auch - nur leider nur in Office 2003. Ab 2007 gibts SearchFile nicht mehr
Hat jemand ne Lösung wie ich unten angegebenen Code so umwandle das er mit die gesamte Datei nach Inhalt nach Textinhalten durchsucht?
Option Explicit
Dim fso As New FileSystemObject
Dim fld As Folder
Private Sub cmdFSuchen_Click()
Dim nDirs As Long, nFiles As Long, lSize As Currency
Dim sDir As String, sSrchString As String
Dim fText As String
ListBox1.Clear
sDir = "c:\test\"
fText = TextBox1
'MousePointer = vbHourglass
Label1.Caption = "Searching " & vbCrLf & UCase(sDir) & "..."
lSize = FindFile(sDir, fText, nDirs, nFiles)
'MousePointer = vbDefault
MsgBox Str(nFiles) & " " & " Dateien mit dem Namen " & sSrchString & " gefunden in" & Str(nDirs) & _
" Verzeichnis", vbInformation
'MsgBox "Total Size = " & lSize & " bytes"
End Sub
Private Function FindFile(ByVal sFol As String, sFile As String, _
nDirs As Long, nFiles As Long) As Currency
Dim tFld As Folder, tFil As File, FileName As String
Dim fText As String
On Error GoTo Catch
Set fld = fso.GetFolder(sFol)
FileName = dir(fso.BuildPath(fld.path, sFile), vbNormal Or _
vbHidden Or vbSystem Or vbReadOnly)
While Len(FileName) <> 0
FindFile = FindFile + FileLen(fso.BuildPath(fld.path, _
FileName))
nFiles = nFiles + 1
ListBox1.AddItem fso.BuildPath(fld.path, dir) ' Load ListBox
FileName = dir() ' Get next file
DoEvents
Wend
Label1 = "Searching " & vbCrLf & fld.path & "..."
nDirs = nDirs + 1
If fld.SubFolders.Count > 0 Then
For Each tFld In fld.SubFolders
DoEvents
FindFile = FindFile + FindFile(tFld.path, sFile, nDirs, nFiles)
Next
End If
Exit Function
Catch: FileName = ""
Resume Next
End Function
Private Sub CommandButton2_Click()
Unload frmOrdnerSuchen
End Sub
Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Dim dir As String
dir = ListBox1
Shell "explorer.exe " & dir, vbNormalFocus
End Sub
Danke und Gruß Manuel
Hallo zusammen,
bin seit geraumer Zeit auf der Suche nach ner Lösung.
Habe einen Suchcode der mir supergut die Dateien findet und auch anzeigt, das Problem ist, das ich in die Suche den korrekten Dateinnamen eingeben muss.
Was ich aber brauche ist das er mit nach Dateiinhalten sucht. Also quasi die Desktopsuche von MS.
Habe es über SearchFile versucht - das klappt auch - nur leider nur in Office 2003. Ab 2007 gibts SearchFile nicht mehr
Hat jemand ne Lösung wie ich unten angegebenen Code so umwandle das er mit die gesamte Datei nach Inhalt nach Textinhalten durchsucht?
Option Explicit
Dim fso As New FileSystemObject
Dim fld As Folder
Private Sub cmdFSuchen_Click()
Dim nDirs As Long, nFiles As Long, lSize As Currency
Dim sDir As String, sSrchString As String
Dim fText As String
ListBox1.Clear
sDir = "c:\test\"
fText = TextBox1
'MousePointer = vbHourglass
Label1.Caption = "Searching " & vbCrLf & UCase(sDir) & "..."
lSize = FindFile(sDir, fText, nDirs, nFiles)
'MousePointer = vbDefault
MsgBox Str(nFiles) & " " & " Dateien mit dem Namen " & sSrchString & " gefunden in" & Str(nDirs) & _
" Verzeichnis", vbInformation
'MsgBox "Total Size = " & lSize & " bytes"
End Sub
Private Function FindFile(ByVal sFol As String, sFile As String, _
nDirs As Long, nFiles As Long) As Currency
Dim tFld As Folder, tFil As File, FileName As String
Dim fText As String
On Error GoTo Catch
Set fld = fso.GetFolder(sFol)
FileName = dir(fso.BuildPath(fld.path, sFile), vbNormal Or _
vbHidden Or vbSystem Or vbReadOnly)
While Len(FileName) <> 0
FindFile = FindFile + FileLen(fso.BuildPath(fld.path, _
FileName))
nFiles = nFiles + 1
ListBox1.AddItem fso.BuildPath(fld.path, dir) ' Load ListBox
FileName = dir() ' Get next file
DoEvents
Wend
Label1 = "Searching " & vbCrLf & fld.path & "..."
nDirs = nDirs + 1
If fld.SubFolders.Count > 0 Then
For Each tFld In fld.SubFolders
DoEvents
FindFile = FindFile + FindFile(tFld.path, sFile, nDirs, nFiles)
Next
End If
Exit Function
Catch: FileName = ""
Resume Next
End Function
Private Sub CommandButton2_Click()
Unload frmOrdnerSuchen
End Sub
Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Dim dir As String
dir = ListBox1
Shell "explorer.exe " & dir, vbNormalFocus
End Sub
Danke und Gruß Manuel
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 98334
Url: https://administrator.de/contentid/98334
Ausgedruckt am: 20.11.2024 um 13:11 Uhr
9 Kommentare
Neuester Kommentar
Hallo Manuel,
lies die Datei doch komplett ein und suche dann in dem Inhalt. Z.B.:
Public Function Search_Content(ByVal sFilename As String, Suchstring) As String
Dim F As Integer
Dim sInhalt As String
' Existiert die Datei ?
If Dir$(sFilename, vbNormal) <> "" Then
' Textdatei im Binärmodus öffnen und gesamten
' Inhalt in einem Rutsch auslesen
F = FreeFile
Open sFilename For Binary As #F
sInhalt = Space$(LOF(F))
Get #F, , sInhalt
Close #F
if instr(sIhnalt,SuchstringThen 'Hier einfach den Suchbegriff in dem Dateiinhalt suchen
msgbox "Gefunden" ' oder was imm Du dann machen willst; evtl Search_Content=True oder so
end if
End if
End Function
Gruß
Ralf
lies die Datei doch komplett ein und suche dann in dem Inhalt. Z.B.:
Public Function Search_Content(ByVal sFilename As String, Suchstring) As String
Dim F As Integer
Dim sInhalt As String
' Existiert die Datei ?
If Dir$(sFilename, vbNormal) <> "" Then
' Textdatei im Binärmodus öffnen und gesamten
' Inhalt in einem Rutsch auslesen
F = FreeFile
Open sFilename For Binary As #F
sInhalt = Space$(LOF(F))
Get #F, , sInhalt
Close #F
if instr(sIhnalt,SuchstringThen 'Hier einfach den Suchbegriff in dem Dateiinhalt suchen
msgbox "Gefunden" ' oder was imm Du dann machen willst; evtl Search_Content=True oder so
end if
End if
End Function
Gruß
Ralf
Hallo manuel5!
Unter CMD gibt es für solche Zwecken "findstr" - und wenn Dich das CMD-Fenster nicht stört, kannst Du diesen Befehl auch von VBA aus nutzen, zB (ungetestet):
Grüße
bastla
Unter CMD gibt es für solche Zwecken "findstr" - und wenn Dich das CMD-Fenster nicht stört, kannst Du diesen Befehl auch von VBA aus nutzen, zB (ungetestet):
Pfad = "c:\test\*.txt"
Suchbegriff = "Dein Text"
Set objShell = CreateObject("WScript.Shell")
Set objExecObject = objShell.Exec("%comspec% /c findstr /m /s /c:""" & Suchbegriff & """ """ & Pfad & """")
i = 1
If Not objExecObject.StdOut.AtEndOfStream Then
FileList = Split(Trim(objExecObject.StdOut.ReadAll()), vbCrLf)
For i = 0 To UBound(FileList) - 1
listbox.AddItem FileList(i)
Next
End If
bastla
Hallo manuel5!
Die Pfadangabe mit der Einschränkung auf den Dateityp ".txt" passt? Falls nicht: "*.*" verwenden ...
Um die Suche ohne Unterscheidung von Klein- und Großbuchstaben durchzuführen, kannst Du zusätzlich noch den Schalter "/i" bei "findstr" verwenden.
Mit dem folgenden Code (inklusive angesprochene Änderungen) wird zur Kontrolle vorweg die Kommandozeile ausgegeben (aus der dafür verwendeten "InputBox" kannst Du sie leicht kopieren und in ein CMD-Fenster einfügen, um sie unmittelbar testen zu können):
Grüße
bastla
Die Pfadangabe mit der Einschränkung auf den Dateityp ".txt" passt? Falls nicht: "*.*" verwenden ...
Um die Suche ohne Unterscheidung von Klein- und Großbuchstaben durchzuführen, kannst Du zusätzlich noch den Schalter "/i" bei "findstr" verwenden.
Mit dem folgenden Code (inklusive angesprochene Änderungen) wird zur Kontrolle vorweg die Kommandozeile ausgegeben (aus der dafür verwendeten "InputBox" kannst Du sie leicht kopieren und in ein CMD-Fenster einfügen, um sie unmittelbar testen zu können):
Pfad = "c:\test\*.*"
Suchbegriff = "Langen"
Set objShell = CreateObject("WScript.Shell")
CommandLine = "%comspec% /c findstr /m /s /i /c:""" & Suchbegriff & """ """ & Pfad & """"
Dummy = InputBox("CommandLine", , CommandLine)
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
ListBox1.AddItem FileList(i)
Next
End If
Grüße
bastla
Hallo manuel5!
Als (sehr unschöner) Workaround fiele mir nur ein, die Dateiliste aus CMD in eine Datei schreiben zu lassen (und diese dann mit dem Script wieder einzulesen), da in diesem Fall "Shell" verwendet werden könnte. Die Commandline müsste dann um eine Umleitung erweitert werden, etwa:
Einzulesen wäre dann aus "%temp%\Dateiliste.txt".
Grüße
bastla
1 - wie bekomm ich das Dos-Shell/Fenster in de Hintergrund - mit hidden schaff ich es ned.
Deswegen der Hinweis in meinem ersten Kommentar ...Als (sehr unschöner) Workaround fiele mir nur ein, die Dateiliste aus CMD in eine Datei schreiben zu lassen (und diese dann mit dem Script wieder einzulesen), da in diesem Fall "Shell" verwendet werden könnte. Die Commandline müsste dann um eine Umleitung erweitert werden, etwa:
CommandLine = "%comspec% /c findstr /m /s /i /c:""" & Suchbegriff & """ """ & Pfad & """ >%temp%\Dateiliste.txt"
2. wie bekomme ich den Ordner auf in welchen die gesuchte Datei steckt?
Dazu musst Du eigentlich nur den Pfad an der Position des letzten enthaltenen "\" abschneiden, also:PathOnly = Left(Pfad, InStrRev(Pfad, "\"))
bastla