Autor |
Beitrag |
Sahroma
Beiträge: 66
Erhaltene Danke: 1
Delphi 10 Seattle, Delphi 10.1 Berlin
|
Verfasst: Do 28.05.15 09:06
Hallo zusammen,
ich habe ein Programm geschrieben das *.dfm, *.pas und *.txt Dateien durchsucht nach Wörtern die ich in eine TEdit Box eintrage. Funktioniert auch alles ohne Probleme nur habe ich mit den *.dfm Dateien Probleme, erstens weil diese ja Umbrüche haben und Umlaute (ä,ü usw) umwaltet in z.B #230. Ich versuche schon seit mehreren Wochen dies hin zubekommen habe auch schon das Internet durchforstet aber nichts gefunden. Ihr seit jetzt meine letzte Hoffnung.
Hier mal den Code von der Suche:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62:
| procedure TVolltextsuche.FindMyFiles; var LFiles: TStringDynArray; LStrs: TStringList; LValue: string; i : Integer; begin LFiles := TDirectory.GetFiles(ebPfad.Text,'*.txt',TSearchOption.soAllDirectories,BuildDirectoryFilterPredicate(ebSuche.Text)); lbErgebnis.Items.BeginUpdate; try for LValue in LFiles do begin lbErgebnis.Items.Add(LValue); end; finally lbErgebnis.Items.EndUpdate; end; LFiles := TDirectory.GetFiles(ebPfad.Text,'*.dfm',TSearchOption.soAllDirectories,BuildDirectoryFilterPredicate(ebSuche.Text)); lbErgebnis.Items.BeginUpdate; try for LValue in LFiles do begin lbErgebnis.Items.Add(LValue); end; finally lbErgebnis.Items.EndUpdate; end; LFiles := TDirectory.GetFiles(ebPfad.Text,'*.pas',TSearchOption.soAllDirectories,BuildDirectoryFilterPredicate(ebSuche.Text)); lbErgebnis.Items.BeginUpdate; try for LValue in LFiles do begin lbErgebnis.Items.Add(LValue); end; finally lbErgebnis.Items.EndUpdate; end; end;
function TVolltextsuche.BuildDirectoryFilterPredicate(ASearchText: string): TDirectory.TFilterPredicate; begin Result := function(const Path: string; const SearchRec: TSearchRec): Boolean begin Result := ContentContainsText(PrepareContentForSearch(GetContentFromFile(TPath.Combine(Path, SearchRec.Name))), ASearchText); end; end;
function TVolltextsuche.GetContentFromFile(const AFilename: string): string; begin Result := TFile.ReadAllText(AFilename); end;
function TVolltextsuche.PrepareContentForSearch(const AContent: string): string; begin Result := AContent; end;
function TVolltextsuche.ContentContainsText(const AContent: string; const ASearchText: string): Boolean; begin Result := AContent.Contains(ASearchText); end; |
Habt ihr da Vorschläge wie ich die Umbrüche vor der Suche aus der Datei temporär entferne und das die Suche die codierten Umlaute beachtet? Danke schonmal für eure Hilfe.
Grüße
Sahroma
Zuletzt bearbeitet von Sahroma am Do 28.05.15 15:37, insgesamt 1-mal bearbeitet
|
|
Stundenplan
Beiträge: 128
Erhaltene Danke: 32
Win 7
Delphi 7 Pers., C# (VS 2010 Express)
|
Verfasst: Do 28.05.15 13:48
Warum auch immer du Umbrüche entfernen willst - StringReplace sollte treue Dienste leisten: Ersetze einfach alle #13 und alle #10 durch Leerstrings.
Genauso kannst du auch Umlaute behandeln.
|
|
Sahroma
Beiträge: 66
Erhaltene Danke: 1
Delphi 10 Seattle, Delphi 10.1 Berlin
|
Verfasst: Do 28.05.15 13:56
Stundenplan hat folgendes geschrieben : | Warum auch immer du Umbrüche entfernen willst - StringReplace sollte treue Dienste leisten: Ersetze einfach alle #13 und alle #10 durch Leerstrings.
Genauso kannst du auch Umlaute behandeln. |
An StringReplace habe ich auch schon gedacht aber irgendwie krieg ich den Code nicht richtig gebacken. Warum ich Umbrüche entfernen will ist eine lange Geschichte. Soweit ich weiß funktioniert StringReplace doch nur mit StringList o.ä. und nicht mit normalen Strings oder StringArrays wie es bei mir der Fall ist oder habe ich da etwas falsch verstanden?
Programmiere mit Delphi noch nicht so lange, entschuldigt also gegebenenfalls dumme Fragen.
|
|
Stundenplan
Beiträge: 128
Erhaltene Danke: 32
Win 7
Delphi 7 Pers., C# (VS 2010 Express)
|
Verfasst: Do 28.05.15 14:02
Doch, StringReplace nimmt einzelne Strings und verarbeitet diese.
Bsp.: result := StringReplace(AContent, #13, '', [rfReplaceAll]);
Damit ersetzt du in AContent den Char #13 durch einen Leerstring; rfReplaceAll bestimmt, dass alle Vorkommnisse ausgetauscht werden.
|
|
Sahroma
Beiträge: 66
Erhaltene Danke: 1
Delphi 10 Seattle, Delphi 10.1 Berlin
|
Verfasst: Do 28.05.15 14:13
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| LFiles := TDirectory.GetFiles(ebPfad.Text,'*.dfm',TSearchOption.soAllDirectories,BuildDirectoryFilterPredicate(ebSuche.Text)); lbErgebnis.Items.BeginUpdate; try for LValue in LFiles do begin LValue := StringReplace(LValue,'''+', '', [rfReplaceAll]); LValue := StringReplace(LValue,'''', '', [rfReplaceAll]); LValue := StringReplace(LValue,#13#10, '', [rfReplaceAll]); lbErgebnis.Items.Add(LValue); end; finally lbErgebnis.Items.EndUpdate; end; |
Habe es mal so eingefügt aber wenn ich dann den Compiler starte, kommt die Meldung: "Der linken Seite kann nichts zugewiesen werden". Stelle ich mich da jetzt nur doof an?
|
|
SMO
Beiträge: 120
Erhaltene Danke: 18
D2005 Personal
|
Verfasst: Do 28.05.15 15:08
For-Schleifenvariablen sind in der Tat Read-Only.
Entweder so:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| var i: Integer;
for i := Low(LFiles) to High(LFiles) do begin LValue := LFiles[i]; LValue := StringReplace(LValue,'''+', '', [rfReplaceAll]); end; |
oder so:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| var temp: string;
for LValue in LFiles do begin temp := LValue; temp := StringReplace(temp,'''+', '', [rfReplaceAll]); end; |
|
|
Sahroma
Beiträge: 66
Erhaltene Danke: 1
Delphi 10 Seattle, Delphi 10.1 Berlin
|
Verfasst: Do 28.05.15 15:24
Danke für die Infos. Habe die zweite Möglichkeit von SMO ausprobiert aber es will immer noch nicht so wie es sein soll. Er ignoriert den StringReplace komplett.
Hier mal den kompletten Code vom Programm mit allen Buttons usw. vielleicht findet ihr da ein Fehler was das verhindert. Ich bin mit meinem Latein komplett am Ende.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150:
| unit Volltext;
interface
uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, System.Types, Vcl.StdCtrls, Vcl.ExtCtrls, Vcl.ComCtrls, Vcl.FileCtrl, System.IOUtils, System.Masks, Winapi.ShellAPI, Vcl.Buttons;
type TVolltextsuche = class(TForm) lbErgebnis: TListBox; btnStart: TButton; btnLöschen: TButton; ebSuche: TEdit; btnSucheN: TButton; FormPanel: TPanel; lblSucheT: TLabel; lblSucheP: TLabel; ebPfad: TEdit; procedure btnSucheNClick(Sender: TObject); procedure btnLöschenClick(Sender: TObject); procedure btnStartClick(Sender: TObject); procedure lbErgebnisClick(Sender: TObject); private procedure FindMyFiles; function GetContentFromFile(const AFilename: string): string; function PrepareContentForSearch(const AContent: string): string; function ContentContainsText(const AContent, ASearchText: string): Boolean; function BuildDirectoryFilterPredicate(ASearchText: string): TDirectory.TFilterPredicate; public end;
var Volltextsuche: TVolltextsuche; OverrideCbBAdr: Boolean = False; implementation
{$R *.dfm} procedure TVolltextsuche.FindMyFiles; var LFiles: TStringDynArray; LStrs: TStringList; LValue: string; dfmstring : string; begin LFiles := TDirectory.GetFiles(ebPfad.Text,'*.txt',TSearchOption.soAllDirectories,BuildDirectoryFilterPredicate(ebSuche.Text)); lbErgebnis.Items.BeginUpdate; try for LValue in LFiles do begin lbErgebnis.Items.Add(LValue); end; finally lbErgebnis.Items.EndUpdate; end; LFiles := TDirectory.GetFiles(ebPfad.Text,'*.dfm',TSearchOption.soAllDirectories,BuildDirectoryFilterPredicate(ebSuche.Text)); lbErgebnis.Items.BeginUpdate; try for LValue in LFiles do begin dfmstring := LValue; dfmstring := StringReplace(dfmstring,'''+', '', [rfReplaceAll]); dfmstring := StringReplace(dfmstring,'''', '', [rfReplaceAll]); dfmstring := StringReplace(dfmstring,#13#10, '', [rfReplaceAll]); lbErgebnis.Items.Add(dfmstring); end; finally lbErgebnis.Items.EndUpdate; end; LFiles := TDirectory.GetFiles(ebPfad.Text,'*.pas',TSearchOption.soAllDirectories,BuildDirectoryFilterPredicate(ebSuche.Text)); lbErgebnis.Items.BeginUpdate; try for LValue in LFiles do begin lbErgebnis.Items.Add(LValue); end; finally lbErgebnis.Items.EndUpdate; end; end;
function TVolltextsuche.BuildDirectoryFilterPredicate(ASearchText: string): TDirectory.TFilterPredicate; begin Result := function(const Path: string; const SearchRec: TSearchRec): Boolean begin Result := ContentContainsText(PrepareContentForSearch(GetContentFromFile(TPath.Combine(Path, SearchRec.Name))), ASearchText); end; end;
function TVolltextsuche.GetContentFromFile(const AFilename: string): string; begin Result := TFile.ReadAllText(AFilename); end;
procedure TVolltextsuche.lbErgebnisClick(Sender: TObject); var i: Integer; begin for i := 0 to lbErgebnis.Items.Count -1 do begin if lbErgebnis.Selected[i] then ShellExecute(Handle, 'open', PChar('notepad'), PChar(lbErgebnis.Items.Strings[i]), nil, SW_SHOW); end; end;
function TVolltextsuche.PrepareContentForSearch(const AContent: string): string; begin Result := AContent; end;
function TVolltextsuche.ContentContainsText(const AContent: string; const ASearchText: string): Boolean; begin Result := AContent.Contains(ASearchText); end;
procedure TVolltextsuche.btnLöschenClick(Sender: TObject); begin lbErgebnis.Clear; end;
procedure TVolltextsuche.btnStartClick(Sender: TObject); begin FindMyFiles; end;
procedure TVolltextsuche.btnSucheNClick(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; ebPfad.Text:= ''; end; ebPfad.Text := Directory; end; end;
end. |
|
|
Stundenplan
Beiträge: 128
Erhaltene Danke: 32
Win 7
Delphi 7 Pers., C# (VS 2010 Express)
|
Verfasst: Do 28.05.15 16:00
Momentan wendest du die Replaces ja auch auf die Dateinamen an; ich nehme an, der Replace-Code gehört in PrepareContentForSearch?
Für diesen Beitrag haben gedankt: Sahroma
|
|
Sahroma
Beiträge: 66
Erhaltene Danke: 1
Delphi 10 Seattle, Delphi 10.1 Berlin
|
Verfasst: Fr 29.05.15 07:44
|
|
Sahroma
Beiträge: 66
Erhaltene Danke: 1
Delphi 10 Seattle, Delphi 10.1 Berlin
|
Verfasst: Do 11.06.15 08:57
Programm läuft nun ohne Probleme. Nun bin ich dabei noch ein paar Zusatzfunktionen einzufügen. Bisher habe ich eine EditBox wo mir die Anzahl der gefundenen Treffer anzeigt. Würde aber gerne noch eine zusätzlich Editbox einbauen wo mir die Anzahl ALLER Ergebnisse ausgibt (also wie viele Dateien er insgesamt durchsucht hat). Bekomme das aber irgendwie nicht gebacken. Könnt ihr mir da weiterhelfen?
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46:
| procedure TVolltextsuche.FindMyFiles; var LFiles: TStringDynArray; LValue: string; Treffer: Integer; begin pb1.Min := 0; pb1.Max := 80; pb1.Step := 20; Treffer := 0; pb1.StepIt; LFiles := TDirectory.GetFiles(ebPfad.Text,'*.txt',TSearchOption.soAllDirectories,BuildDirectoryFilterPredicate(ebSuche.Text)); lbErgebnis.Items.BeginUpdate; try for LValue in LFiles do begin lbErgebnis.Items.Add(LValue); end; finally lbErgebnis.Items.EndUpdate; end; pb1.StepIt; LFiles := TDirectory.GetFiles(ebPfad.Text,'*.dfm',TSearchOption.soAllDirectories,BuildDirectoryFilterPredicate(ebSuche.Text)); lbErgebnis.Items.BeginUpdate; try for LValue in LFiles do begin lbErgebnis.Items.Add(LValue); end; finally lbErgebnis.Items.EndUpdate; end; pb1.StepIt; LFiles := TDirectory.GetFiles(ebPfad.Text,'*.pas',TSearchOption.soAllDirectories,BuildDirectoryFilterPredicate(ebSuche.Text)); lbErgebnis.Items.BeginUpdate; try for LValue in LFiles do begin lbErgebnis.Items.Add(LValue); end; finally lbErgebnis.Items.EndUpdate; end; pb1.StepIt; ebGTreffer.Text := IntToStr(lbErgebnis.Items.Count); end; |
ebGTreffer = Editboxname für gefundene Treffer. Eine zusätzliche Editbox soll wie bereits beschrieben noch ALLE Ergebnisse während der Suche ausgeben.
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Do 11.06.15 09:47
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|
Sahroma
Beiträge: 66
Erhaltene Danke: 1
Delphi 10 Seattle, Delphi 10.1 Berlin
|
Verfasst: Do 11.06.15 10:03
|
|
baumina
Beiträge: 305
Erhaltene Danke: 61
Win 7
Delphi 10.2 Tokyo Enterprise
|
Verfasst: Do 11.06.15 10:15
GetFiles ohne Editfeld-Suchkriterien aufrufen und gefundene Anzahl ausgeben.
Für diesen Beitrag haben gedankt: Sahroma
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Do 11.06.15 12:08
- Nachträglich durch die Entwickler-Ecke gelöscht -
Für diesen Beitrag haben gedankt: Sahroma
|
|
Sahroma
Beiträge: 66
Erhaltene Danke: 1
Delphi 10 Seattle, Delphi 10.1 Berlin
|
Verfasst: Do 11.06.15 15:06
Danke euch beiden. Habe bauminas Variante genommen und funktioniert genau so wie ich es mir gedacht habe.
|
|
Sahroma
Beiträge: 66
Erhaltene Danke: 1
Delphi 10 Seattle, Delphi 10.1 Berlin
|
Verfasst: Fr 12.06.15 14:03
Ich weiß ich gehe euch mit meinen dummen Fragen auf die Nerven, aber leider arbeite ich mit Delphi noch nicht so lange.
Mein Suchergebnis gebe ich ja in einer ListBox aus, nun habe ich die Anweisung das ich es in ein TListView ausgebe soll. Habe damit noch überhaupt keine Erfahrung. Habe bisher 4 Spalten in die ListView Box eingefügt (Name der Datei, Ordner wo die Datei liegt, Größe der Datei und Typ (pas oder dfm oder txt). Ich habe aber absolut keine Ahnung wie ich das Suchergebnis so zerteile das die Inhalte der jeweiligen Spalten auch stimme? Bisher bekam ich nur den kompletten Pfad in der Namens Spalte ausgegeben.
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 12.06.15 20:52
- Nachträglich durch die Entwickler-Ecke gelöscht -
Für diesen Beitrag haben gedankt: Sahroma
|
|
Sahroma
Beiträge: 66
Erhaltene Danke: 1
Delphi 10 Seattle, Delphi 10.1 Berlin
|
Verfasst: Fr 19.06.15 14:44
Und wieder ist ein Problem aufgetreten bzw. ich stehe auf dem Schlauch. Habe nun ein MemoFeld im Formular drin mit einer Checkbox. Wenn die Checkbox markiert ist soll bei der Suche die im Memofeld eingetragen Ordner von der Suche ausgeschlossen werden. Ich sitze hier wie in Anfänger der das erst mal programmiert. Mir fällt einfach nicht ein wie ich das umsetze. Bitte helft mir auf die Sprünge.
|
|
Frühlingsrolle
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Fr 19.06.15 17:22
- Nachträglich durch die Entwickler-Ecke gelöscht -
|
|