![]() |
Volltextsuche mit Delphi
Hallo zusammen,
ich bin ein "fast" Neuling in Delphi. :) Habe vor eine "Volltextsuche" mit Delphi zu programmieren, das Dateien mit der Endung (.pas und .dfm) durchsucht. Und zwar soll in diesen Dateien nach Wörtern im Quelltext gesucht werden die ich über ein EditField eingebe. Hat da jemand ein paar Tipps oder vielleicht sogar ein Beispiel, was man da am besten benutzt. Danke schonmal für eure Hilfe Balosh |
AW: Volltextsuche mit Delphi
Willst du das zum lernen machen?
Falls du nur da was haben willst, installier dir GExperts. Dort gibts eine gute suche. Wenn du da was lernen willst, schau dir den Quellcode von GExpert an dieser stelle an. |
AW: Volltextsuche mit Delphi
Zitat:
![]() Aber .dfm Dateien müssen nicht zwangsläufig als Text gespeichert sein... Da wäre dann ein bisschen mehr Arbeit nötig... Mavarik |
AW: Volltextsuche mit Delphi
Wohl eher PosEx. Und ggf. AnsiLowerCase. TStringList class. String. Wenn man mit PosEx einen Substring gefunden hat kann man z.B. überprüfen ob die Stellen links und rechts davon gewisse Kriterien erfüllen, z.B. ein Leerzeichen sind.
|
AW: Volltextsuche mit Delphi
Zitat:
|
AW: Volltextsuche mit Delphi
Zitat:
Gruß K-H |
AW: Volltextsuche mit Delphi
Zitat:
|
AW: Volltextsuche mit Delphi
Die mögliche Problematik mit DFMs ignoriere ich mal und beantworte die Frage mal allgemein:
- [Datei finden] Du suchst die Dateien mit FindFirst/FindNext - [Datei öffnen] Die gefundenen Dateien lädst du dann per LoadFromFile in eine TStringlist (z.B.) - [Datei durchsuchen] Innerhalb dieser Stringlist suchst du nun das Suchwort per pos() oder/und posEx() - Je nachdem ob in der durchsuchten Datei das Suchwort enthalten ist oder nicht wird die Datei als Ergebnis aufgelistet. |
AW: Volltextsuche mit Delphi
Schon mal
![]() Nebenbei: Keines der hier vorgestellten Vorschläge hat etwas mit ![]() "Suche in Dateien" kommt dem dann schon etwas näher. |
AW: Volltextsuche mit Delphi
Vielen Dank für die vielen Ratschläge und Tipps. Einige helfen mir sehr viel weiter. Gerne könnt hier weiterhin Ratschläge, Tipps und Beispiele nennen. Je mehr desto besser.
Zitat:
Gruß Balosh |
AW: Volltextsuche mit Delphi
Auf was muss man denn alles achten wenn man die Suche komplett auf Unicode machen will? Ist es zu empfehlen oder eher nicht? (Ist nur mal so ein Gedanke) :)
|
AW: Volltextsuche mit Delphi
So habe nun in etwa das Grundgerüst. Ist zwar noch lang keine richtige Volltextsuche aber es ist ein Anfang.
Wenn jemandem Fehler auffallen oder paar Verbesserungsvorschläge hat als her damit. Meine nächste Hürde wo ich nehmen will ist die Checkbox so zu integrieren, dass wenn sie markiert ist auch die Unterordner mit einbezogen werden. So wie ich das bisher gemacht habe funktioniert es nicht wirklich.
Code:
unit Volltextsuche;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, FileCtrl, System.IOUtils , Vcl.Buttons; type TMainSuche = class(TForm) cbSuche: TComboBox; lblSuche: TLabel; cbZiel: TComboBox; lblZiel: TLabel; btnZiel: TButton; BBstart: TBitBtn; ListBox1: TListBox; CheckBox1: TCheckBox; procedure btnZielClick(Sender: TObject); procedure BBstartClick(Sender: TObject); procedure ListBox1DblClick(Sender: TObject); private { Private-Deklarationen } procedure FileSearch(const PathName, FileName : string; const InDir : boolean); public { Public-Deklarationen } end; var MainSuche: TMainSuche; OverrideCbBAdr: boolean = false; implementation {$R *.dfm} uses FileInfo; procedure TMainSuche.FileSearch(const PathName: string; const FileName: string; const InDir: Boolean); var Rec : TSearchRec; Path : string; begin Path := IncludeTrailingBackslash(PathName); if FindFirst (Path + FileName, faAnyFile - faDirectory, Rec) = 0 then try repeat Listbox1.Items.Add(Path + Rec.Name); until FindNext (Rec) <> 0; finally FindClose (Rec); end; end; procedure TMainSuche.btnZielClick(Sender: TObject); var Directory: string; begin Directory := 'C:\'; if SelectDirectory('Bitte ein Verzeichnis wählen.','',Directory) then begin if not OverrideCbBAdr then begin OverridecbBAdr := true; cbZiel.Items.Insert(0,''); end; cbZiel.Items.Delete(0); cbZiel.Items.Insert(0,Directory); cbZiel.ItemIndex := 0; end; end; procedure TMainSuche.BBstartClick(Sender: TObject); begin ListBox1.Clear; FileSearch(cbZiel.Text, cbSuche.Text, CheckBox1.State in [cbChecked]); end; procedure TMainSuche.ListBox1DblClick(Sender: TObject); var SelectedFile : string; Rec : TSearchRec; frInfo : TfrFileInfo; begin SelectedFile := ListBox1.Items.Strings[ListBox1.ItemIndex]; if FindFirst (SelectedFile, faAnyFile, Rec) = 0 then begin frinfo := TfrFileInfo.Create(Self); try frInfo.lblFile.Caption := SelectedFile; frInfo.lblName.Caption := Rec.Name; frInfo.lblSize.Caption := Format('%d bytes', [Rec.Size]); frInfo.lblModified.Caption := DateToStr(fileDatetoDateTime(Rec.Time)); frInfo.lblShortName.Caption := Rec.FindData.cAlternateFileName; frInfo.ShowModal; finally frInfo.Free; end; FindClose(Rec) end; end; end. |
AW: Volltextsuche mit Delphi
Habe nun die Checkbox mit eingebaut aber wenn ich das Programm ausführe und die Checkbox markiere kommt ein Speicher Fehler:
=>Erste Gelegenheit für Exception bei $77060FB2. Exception-Klasse $C0000005 mit Meldung 'access violation at 0x77060fb2: write of address 0x74e4ddf5'. Prozess Suche.exe (5336)<= ich habe keine Ahnung was den Fehler verursacht. Hier auch mal der geänderte Code mit der Checkbox:
Code:
procedure TMainSuche.FileSearch(const PathName, FileName: string);
var Rec : TSearchRec; Path : string; begin if Checkbox1.Checked = true then begin Path := IncludeTrailingBackSlash(PathName); try repeat if ((Rec.attr and faDirectory) = faDirectory) then FileSearch(Path, Rec.Name); until FindNext(Rec) <> 0; finally FindClose (Rec); end; end else begin Path := IncludeTrailingBackslash(PathName); if FindFirst (Path + FileName, faAnyFile - faDirectory, Rec) = 0 then begin try repeat Listbox1.Items.Add(Path + Rec.Name); until FindNext (Rec) <> 0; finally FindClose (Rec); end; end; end; end; |
AW: Volltextsuche mit Delphi
Wenn CheckBox1.Checked dann machst du kein FindFirst, greifst aber schon mal auf das nicht initialisierte Rec.attr zu -> *peng*.
|
AW: Volltextsuche mit Delphi
Ich würde nur den Code der sich zwischen den beiden Versionen unterscheidet in der Fallunterscheidung getrennt verwenden.
In der 1. Bedingung fehlt das FindFirst()
Delphi-Quellcode:
reicht
if Checkbox1.Checked then
|
AW: Volltextsuche mit Delphi
@ baumina
stimmt kein Wunder das es da crashed. Zitat:
|
AW: Volltextsuche mit Delphi
Du hast 2 fast identische Schleifen. Es sollte ja auch mit einer gehen.
|
AW: Volltextsuche mit Delphi
Mhh Ok habe jetzt die Schleifen abgeändert aber nun bringt er mir kein Ergebnis mehr.
Code:
Hab ich da wieder ein Logikfehler drin und ich sehe ihn nicht bzw. einen Anfänger Fehler?
procedure TMainSuche.FileSearch(const PathName, FileName: string);
var Rec : TSearchRec; Path : string; begin if FindFirst (Path + FileName, faAnyFile - faDirectory, Rec) = 0 then if Checkbox1.Checked = true then begin Path := IncludeTrailingBackSlash(PathName); try repeat if ((Rec.attr and faDirectory) = faDirectory) then FileSearch(Path, Rec.Name); until FindNext(Rec) <> 0; finally FindClose (Rec); end; end else begin Path := IncludeTrailingBackslash(PathName); begin try repeat Listbox1.Items.Add(Path + Rec.Name); until FindNext (Rec) <> 0; finally FindClose (Rec); end; end; end; end; |
AW: Volltextsuche mit Delphi
Wenn du im FindFirst keine Verzeichnisse suchst, wirst du natürlich auch keine finden.
|
AW: Volltextsuche mit Delphi
Immer noch zuviel doppelt.
Delphi-Quellcode:
procedure TMainSuche.FileSearch(const PathName, FileName: string);
var Rec : TSearchRec; Path : string; begin Path := IncludeTrailingBackSlash(PathName); try if FindFirst (Path + FileName, faAnyFile, Rec) = 0 then begin repeat if ((Rec.attr and faDirectory) = faDirectory) then begin if Checkbox1.Checked then FileSearch(Path, Rec.Name) end else Listbox1.Items.Add(Path + Rec.Name); until FindNext(Rec) <> 0; finally FindClose (Rec); end; end; |
AW: Volltextsuche mit Delphi
Code:
So bin ich wieder am Anfang und er sucht nur Dateien im Ordner, er soll aber wenn die Checkbox aktiviert ist auch die Unterordner mit einbeziehen.
procedure TMainSuche.FileSearch(const PathName, FileName: string);
var Rec : TSearchRec; Path : string; begin Path := IncludeTrailingBackSlash(PathName); try if FindFirst (Path + FileName, faAnyFile, Rec) = 0 then begin repeat if ((Rec.attr and faDirectory) = faDirectory) then begin if Checkbox1.Checked then FileSearch(Path, Rec.Name) end else Listbox1.Items.Add(Path + Rec.Name); until FindNext(Rec) <> 0; finally FindClose (Rec); end; end; |
AW: Volltextsuche mit Delphi
Das liegt aber eher an Deinem Aufruf auf die Unterordner:
Müsste
Delphi-Quellcode:
lauten.
FileSearch(Path+Rec.Name, Filename);
|
AW: Volltextsuche mit Delphi
Delphi-Quellcode:
So funktioniert es
procedure TMainSuche.FileSearch(const PathName, FileName: string); var Rec : TSearchRec; Path: string; begin Path := IncludeTrailingBackSlash(PathName); try if FindFirst (Path + FileName, faAnyFile, Rec) = 0 then begin repeat if ((Rec.attr and faDirectory) = faDirectory) then begin if Checkbox1.Checked then begin if (Rec.Name <> '.') and (Rec.Name <> '..') then FileSearch( Path+Rec.Name , FileName); end; end else Listbox1.Items.Add(Path + Rec.Name); until FindNext(Rec) <> 0; end; finally FindClose (Rec); end; end; |
AW: Volltextsuche mit Delphi
Zitat:
|
AW: Volltextsuche mit Delphi
Liste der Anhänge anzeigen (Anzahl: 2)
Bei mir funktioniert der Code
|
AW: Volltextsuche mit Delphi
Ok das ist merkwürdig. Dann liegt der Fehler wohl an einer anderen Prozedur im Gesamtcode bei mir. Nur wo das ist nun die Frage.:?
|
AW: Volltextsuche mit Delphi
Also ich finde nirgends etwas was verhindern könnte dass das Programm nicht richtig läuft hier mal den kompletten Code:
Code:
Findet ihr da etwas?
unit Volltextsuche;
interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ComCtrls, FileCtrl, System.IOUtils , Vcl.Buttons; type TMainSuche = class(TForm) cbSuche: TComboBox; lblSuche: TLabel; cbZiel: TComboBox; lblZiel: TLabel; btnZiel: TButton; BBstart: TBitBtn; ListBox1: TListBox; CheckBox1: TCheckBox; BitBtn1: TBitBtn; procedure btnZielClick(Sender: TObject); procedure BBstartClick(Sender: TObject); procedure BitBtn1Click(Sender: TObject); private { Private-Deklarationen } procedure FileSearch(const PathName, FileName : string); public { Public-Deklarationen } end; var MainSuche: TMainSuche; OverrideCbBAdr: boolean = false; implementation {$R *.dfm} uses FileInfo; procedure TMainSuche.FileSearch(const PathName, FileName: string); var Rec : TSearchRec; Path: string; begin Path := IncludeTrailingBackSlash(PathName); try if FindFirst (Path + FileName, faAnyFile, Rec) = 0 then begin repeat if ((Rec.attr and faDirectory) = faDirectory) then begin if Checkbox1.Checked then begin if (Rec.Name <> '.') and (Rec.Name <> '..') then FileSearch( Path+Rec.Name , FileName); end; end else Listbox1.Items.Add(Path + Rec.Name); until FindNext(Rec) <> 0; end; finally FindClose (Rec); end; end; procedure TMainSuche.BitBtn1Click(Sender: TObject); begin ListBox1.Clear; end; procedure TMainSuche.btnZielClick(Sender: TObject); var Directory: string; begin Directory := 'C:\'; if SelectDirectory('Bitte ein Verzeichnis wählen.','',Directory) then begin if not OverrideCbBAdr then begin OverridecbBAdr := true; cbZiel.Items.Insert(0,''); end; cbZiel.Items.Delete(0); cbZiel.Items.Insert(0,Directory); cbZiel.ItemIndex := 0; end; end; procedure TMainSuche.BBstartClick(Sender: TObject); begin ListBox1.Clear; FileSearch(cbZiel.Text, cbSuche.Text); end; end. |
AW: Volltextsuche mit Delphi
Zu was die Zwischenspeicherung des Pfades in einer ComboBox? Wenn schon, warum dann kein Label oder Edit? (es wird ja immer in den 1. Eintrag geschrieben)
|
AW: Volltextsuche mit Delphi
nee, das geht ja auch nicht!
Angenommen Du suchst in
Code:
nach
C:\
Code:
dann sucht Deine Routine in
*.sql
Code:
namch einer Datei die die Bedingung
C:\
Code:
erfüllt, da dies nicht der Fall ist (höchstwahrscheinlich) verabschiedet sich Deine Suche gleich wieder.
*.sql
wenn Du rekursiv suchen willst, dann mußt Du auf jeden Fall die (möglichen) Verzeichnisse
Delphi-Quellcode:
extra behandeln.
if Checkbox1.Checked then
begin if (Rec.Name <> '.') and (Rec.Name <> '..') then FileSearch( Path+Rec.Name , FileName); end; Übrigens ist der Rückbezug auf eine andere Komponente des Forms nicht unbedingt der Weisheit letzer Schluß. Besser wäre es der Procedure gleich ein
Delphi-Quellcode:
mitzugeben!
recursiv:boolean
Gruß K-H |
AW: Volltextsuche mit Delphi
Habe das Problem mit dem Unterordner wie folgt gelöst. :)
Code:
Das auskommentierte ist der alte Befehl und das direkt darunter der neue. Und so beachtet das Programm dann auch die Unterordner. Ich halte euch weiter auf dem laufenden bzw. falls weitere Probleme auftauchen melde ich mich hier. Danke für eure bisherige Hilfe.
procedure TMainSuche.FileSearch(const PathName, FileName: string);
var Rec : TSearchRec; Path: string; begin Path := IncludeTrailingBackSlash(PathName); try //if FindFirst (Path + FileName, faDirectory, Rec) = 0 then if FindFirst (Path+'*', faAnyFile, Rec) = 0 then begin |
AW: Volltextsuche mit Delphi
Jetzt noch
Delphi-Quellcode:
Dann wird die Maske für dateien wieder beachtet.
if MatchesMask( Rec.Name, FileName) then
Listbox1.Items.Add(Path + Rec.Name); |
AW: Volltextsuche mit Delphi
Zitat:
Was meinst du damit, versteh ich nicht ganz? Was soll MatchesMask genau bringen? Kenne das nur flüchtig. EDIT: Frage hat sich erledigt. :) Danke für den Hinweis. |
AW: Volltextsuche mit Delphi
Du hast ja im FindFirst angegeben, dass alle Dateien gefunden werden sollen. MatchesMask überprüft nun ob der Dateiname zur Suchmaske passt.
|
AW: Volltextsuche mit Delphi
Ich glaub du bist hier in dem Unterforum falsch?
Eine Volltextsuche, die es schon in der Delphi-IDE gibt, bzw. Eine, welche du dort einbauen willst, das wäre hier richtig, aber wenn du nur ein Suchprogramm in Delphi/Pascal schreiben willst, also das hat mit der IDE nichts zu tun. PS: DFMs durchsuchen, auch wenn es sie immer seltener gibt, da Delphi bereits seit längerem Diese standardmäßig im Textformat abspeichert, aber dennoch kann es vorkommen, daß du eventuell auf eine Binärversion stößt und Diese müsstest du somit zuerst binär einlesen (TStream) und kannst sie dann mit ![]() |
AW: Volltextsuche mit Delphi
Zitat:
Nun zu meiner Frage bzw. Problem Habe das Programm jetzt soweit am laufen das es die Unterordner und Dateien anzeigt. Nun will ich aber noch dass das Programm in den Dateien nach Wörter (Strings) sucht. Dazu habe ich noch eine zusätzlich Combobo in das Formular "eingebaut". Nun meine Frage wie kombiniere ich die Zwei Aufgaben (Suche nach Dateien und Suche In Dateien). Habe schon etwas angefangen (auskommentiert) aber komme nun nicht weiter:
Code:
Stimmt das was ich bisher eingeben habe (ich weiß ist nicht viel)?
procedure TMainSuche.FileSearch(const PathName, FileName: string);
var Rec : TSearchRec; Path: string; { *sl: TStringList;* } { *i: Integer;* } begin Path := IncludeTrailingBackSlash(PathName); try { *sl := TStringList.Create;* } { *sl.LoadFromFile(Path);*} if FindFirst (Path + '*', faAnyFile, Rec) = 0 then begin repeat if (Rec.attr in [faDirectory, (faDirectory+faArchive)]) then begin if Checkbox1.Checked then begin if (Rec.Name <> '.') and (Rec.Name <> '..') then FileSearch( Path+Rec.Name , FileName); end; end else if MatchesMask( Rec.Name, FileName) then Listbox1.Items.Add(Path + Rec.Name); until FindNext(Rec) <> 0; end; finally FindClose (Rec); end; end; |
AW: Volltextsuche mit Delphi
Was soll denn
Zitat:
|
AW: Volltextsuche mit Delphi
Es entspricht Folgendem
Delphi-Quellcode:
aber gemeint ist bestimmt eigentlich Jenes
//if (Rec.attr = faDirectory) or (Rec.attr = (faDirectory + faArchive)) then
if (Rec.attr = faDirectory) or (Rec.attr = (faDirectory or faArchive)) then
Delphi-Quellcode:
//if faDirectory in Rec.attr then
if Rec.attr and faDirectory <> 0 then Attribute/Bits per Addition zu verbinden ist schonmal falsch, denn das macht man per OR, vorallem da einige der Konstanten mehrere Bits umfassen. Dateinamen suchen (notfalls Alle), wenn Dateiname gefunden, dann jede Datei nacheinander in die StringListe laden und dort drinnen suchen. |
AW: Volltextsuche mit Delphi
Dachte ich mir auch schon, aber da vorherige Versionen den "üblichen" Binärvergleich mit faDirectory hatten und das nun geändert wurde, frage ich lieber mal nach.
|
AW: Volltextsuche mit Delphi
Zitat:
Aber das ist keine Antwort auf meine Frage. :) |
AW: Volltextsuche mit Delphi
Statt einfach nur die Datei der ListBox hinzuzufügen, musst Du sie halt vorher öffnen und nach dem String durchsuchen. Das würde ich aber eher in eine eigene Funktion verfrachten, sonst wird das zu unübersichtlich.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:29 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz