manuel5
Goto Top

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 face-sad

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

Content-Key: 98334

Url: https://administrator.de/contentid/98334

Printed on: April 23, 2024 at 20:04 o'clock

Member: RDiller
RDiller Oct 02, 2008 at 12:08:29 (UTC)
Goto Top
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
Member: manuel5
manuel5 Oct 02, 2008 at 12:34:59 (UTC)
Goto Top
Hi Ralf,

danke erstmal. Das Problem ist hier, ich versuche hundert von Ordner (in welchen Dateien drinsind (*.txt)) nach einer Nummer (welche in einer oder auch mehrern der Datein sich bfindet) zu durchsuchen. Wenn er die Nummer dann gefunden hat, soll er mit in einer Listbox den Pfad + Dateinamen anzeigen.

Das mit der Listbox und Pfad und so das alles is kein Problem. Nur soll er mir eben diese Nummern finden (kann aber auch alphanummerisch sein face-sad((( )

Habe deinen mal etwas "angepasst" - aber er zeigt mir garnuescht an - auch keinen Fehler.

Private Sub CommandButton1_Click()
Dim sfilename As String
Dim suchstring As String

Dim F As Integer
Dim sInhalt As String
sInhalt = txtSFile
sfilename = "c:\test"
' 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, suchstring) Then 'Hier einfach den Suchbegriff in dem Dateiinhalt suchen
listbox.AddItem sfilename ' oder was imm Du dann machen willst; evtl Search_Content=True oder so
End If
End If

End Sub

Er soll also quasi Ordner mit Unterordner durchsuchen.
Heisst ich hinterlege nur den ungefähren Pfad "c:\test" und darunter sind noch einige Unterordner.

in listbox1.additem soll er mr eben den gesamten Pfad anzeigen.

Gruß Manuel
Member: bastla
bastla Oct 02, 2008 at 14:23:07 (UTC)
Goto Top
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):
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
Grüße
bastla
Member: manuel5
manuel5 Oct 02, 2008 at 14:49:19 (UTC)
Goto Top
Hallo Bastla,

hab mit cmd kein Problem, nur zum Ergebnis solls kommen face-smile

Tuts aber leider noch nicht.

Private Sub CommandButton1_Click()
Dim sInhalt As String
sInhalt = txtSFile
Pfad = "c:\test\*.txt"
Suchbegriff = "Langen"
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
ListBox1.AddItem FileList(i)
Next
End If

End Sub

Da "zuckt" nur kurz das Dos-Fenster hoch - aba finden tuts mir noch nichts.

Gruß Manuel
Member: bastla
bastla Oct 02, 2008 at 15:25:39 (UTC)
Goto Top
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):
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
Member: manuel5
manuel5 Oct 02, 2008 at 17:08:22 (UTC)
Goto Top
JAWOHL!

Ett löfft!

face-smile
Aber sowas von - super!

Danke - super !

Gruß Manuel
Member: manuel5
manuel5 Oct 03, 2008 at 09:51:05 (UTC)
Goto Top
Hallo bastla,

noch ne ups zwei Fragen -->

1 - wie bekomm ich das Dos-Shell/Fenster in de Hintergrund - mit hidden schaff ich es ned.

2. wie bekomme ich den Ordner auf in welchen die gesuchte Datei steckt?

Habe ja -->

Private Sub ListBox1_DblClick(ByVal Cancel As MSForms.ReturnBoolean)
Dim pfad As String
pfad = ListBox1
Shell "explorer.exe " & pfad, vbNormalFocus

End Sub

hier macht er mir die Datei selber auf, was ich aber brauch ist das er mit den Ordner aufmacht.
Die Listbox füllt er mir mit ->

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
ListBox1.AddItem FileList(i)
Next
Else
ListBox1.AddItem "Datei nicht gefunden"
End If

Hast du ne Idee?

Gruß Manuel
Member: bastla
bastla Oct 03, 2008 at 12:30:01 (UTC)
Goto Top
Hallo manuel5!

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"  
Einzulesen wäre dann aus "%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, "\"))  
Grüße
bastla
Member: manuel5
manuel5 Oct 03, 2008 at 15:41:49 (UTC)
Goto Top
face-smile

Ok, ist im Prinzip ja kein Problem, wenn s vorne ist.

Das mit dem Pathonly....hätt ich schon so versucht - bei mir gings ned da ich.....hmmm....irgendwo was falsch hatte - jetzt futzt es aber.

Somit danke ich dir recht herzlich für deine Geduld und Hilfe

Gruß Manuel