Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Stringgrid, in bestimmter Spalte nach String suchen... (https://www.delphipraxis.net/38520-stringgrid-bestimmter-spalte-nach-string-suchen.html)

Budda 20. Jan 2005 13:20


Stringgrid, in bestimmter Spalte nach String suchen...
 
Hallo,

ich möchte in einem Stringgrid in einer bestimmten Spalte nach einem String suchen und diesen ersetzen bzw. um genau zu sein möchte ich mehrere verschiedene Strings suchen und diese je nach String durch eine Zahl ersetzen.

Konnte dazu bisher nichts finden, die Befehle wären zu einem Interessant oder auch gerne nen Code Beispiel.


Gruß
Budda

shmia 20. Jan 2005 13:50

Re: Stringgrid, in bestimmter Spalte nach String suchen...
 
Das StringGrid bietet seine Daten über 3 (Array-) Properties an: Cells[], Rows[] und Cols[].
Da du in einer Spalte suchen willst ist das Property Cols[] das Richtige.
Beispiel:
Delphi-Quellcode:
var
   spalte : TStrings;
   p : integer;
begin
   spalte := StringGrid1.cols[2]; // die 3. Spalte
   
   p := spalte.IndexOf('rot'); // suche nach "rot"
   if p >= 0 then
      spalte[p] := 'grün';    // ersetzen

end;
Stellt sich nur noch die Frage wozu die ganzen Ersetzungen.
Möglicherweise sollte man dein Problem ganz anderst lösen.

yankee 20. Jan 2005 14:25

Re: Stringgrid, in bestimmter Spalte nach String suchen...
 
So zum Beispiel:
Delphi-Quellcode:
var i:integer;
with mystringgrid do
begin
    for i:=0 to RowCount-1 do
    begin
        if Cells[SPALTE, i] =mystring then Cells[SPALTE, i] :='mynumber';
//----oder----//
        Cells[SPALTE, i] :=replace(Cells[SPALTE,i],'mystring','mynumber'); //bin mir nicht sicher, ob der Aufruf richtig ist...
    end;

end;

Budda 21. Jan 2005 15:30

Re: Stringgrid, in bestimmter Spalte nach String suchen...
 
Zitat:

Zitat von shmia
Das StringGrid bietet seine Daten über 3 (Array-) Properties an: Cells[], Rows[] und Cols[].
Da du in einer Spalte suchen willst ist das Property Cols[] das Richtige.
Beispiel:
Delphi-Quellcode:
var
   spalte : TStrings;
   p : integer;
begin
   spalte := StringGrid1.cols[2]; // die 3. Spalte
   
   p := spalte.IndexOf('rot'); // suche nach "rot"
   if p >= 0 then
      spalte[p] := 'grün';    // ersetzen

end;
Stellt sich nur noch die Frage wozu die ganzen Ersetzungen.
Möglicherweise sollte man dein Problem ganz anderst lösen.

Hallo,
muss ich danach das Stringgrid aktualisieren damit ich die Änderung sehe? Denn so sehe ich nichts.
Und kann ich nachdem ich das Stringgrid geändert habe diese als Tabstop getrennte txt Speichern?

Gruß
Budda

yankee 21. Jan 2005 15:49

Re: Stringgrid, in bestimmter Spalte nach String suchen...
 
Zitat:

Zitat von shmia
p := spalte.IndexOf('rot'); // suche nach "rot"
end;

Du bist aber schon ein bißchen JavaScript geschädigt, oder :shock:
Nee, nicht ernst gemeint, mal im Ernst. In Delphi ist das wie ich unten geschrieben habe pos(substring, string);

EDIT: quote-Tags korrogiert

EDIT2: ich habe mir das nochmal genauer durchgelesen. Das macht echt so den Anschein, asl hättest du ein bißchen zuvile Javascript geproggt.
Zitat:

Zitat von shmia
spalte := StringGrid1.cols[2]; // die 3. Spalte

Hier kopierst du gerade die komplette Spalte nochmal. Das ist doch totale RAM-Verschwendung. Und CPU-Verschwendung eignlch auch.
Zitat:

Zitat von shmia
p := spalte.IndexOf('rot'); // suche nach "rot"
if p >= 0 then
spalte[p] := 'grün'; // ersetzen
Warum nicht gleich

Delphi-Quellcode:
if spalte.IndexOf('rot') >=0 then spalte[p] := 'grün';
spalte.IndexOf('rot') <-- Wieso ist hier eigentlich kein array?? Also das mit strings?
Ähm, bitte noch bedenken, dass man das dann noch wegen der Syntax umschreiben muss:
Delphi-Quellcode:
if pos('rot',spalte.strings[i]) >=0 then spalte[p] := 'grün';
Naja, ich weiß nicht, mir fällt da noch 'ne ganze Menge auf, ich bin jetzt erstmal was verwirrt.

shmia 21. Jan 2005 17:50

Re: Stringgrid, in bestimmter Spalte nach String suchen...
 
Zitat:

Zitat von yankee
Zitat:

Zitat von shmia
p := spalte.IndexOf('rot'); // suche nach "rot"
end;

Du bist aber schon ein bißchen JavaScript geschädigt, oder :shock:

Nö, das ist doch korrekter Delphi Code.
Also spalte ist eine Stringliste, und mit der Methode [TStrings.]IndexOf erspare ich mir
eine Schleife über alle Strings in der Liste.
In der Variablen p wird die Position des Strings in der Liste gespeichert.
Wenn man nur einen Teilstring suchen möchte, dann kann man IndexOf natürlich nicht gebrauchen.
Zitat:

Zitat von yankee
EDIT2: ich habe mir das nochmal genauer durchgelesen. Das macht echt so den Anschein, asl hättest du ein bißchen zuvile Javascript geproggt.
Zitat:

Zitat von shmia
spalte := StringGrid1.cols[2]; // die 3. Spalte

Hier kopierst du gerade die komplette Spalte nochmal. Das ist doch totale RAM-Verschwendung. Und CPU-Verschwendung eignlch auch.

Hier wird nicht kopiert, sondern spalte ist ein Objektzeiger.
Über dieses TStrings-Objekt greife ich direkt auf die Zellen einer Spalte des StringGrids zu.
Wenn du's nicht glaubst, dann versuche mal das:
Delphi-Quellcode:
procedure TForm1.BitBtn1Click(Sender: TObject);
var
   spalte : TStrings;
   i : Integer;
begin
   spalte := StringGrid1.cols[1]; // die 2. SPALTE

   // wird jetzt mit Inhalten befüllt
   for i := 0 to spalte.Count-1 do
   begin
      spalte[i] := IntToStr(i)+ ' Hallo';
   end;
   // beachte, dass das Objekt spalte weder mit Create erzeugt,
   // noch mit Free zerstört wird

   // auch ein Refresh des Grid ist nicht nötig !
end;

yankee 21. Jan 2005 19:30

Re: Stringgrid, in bestimmter Spalte nach String suchen...
 
0ok, ich glaube dir...
nur müsstest du dann nicht das Teil auch als TStringList deklaruieren?

Budda 24. Jan 2005 07:48

Re: Stringgrid, in bestimmter Spalte nach String suchen...
 
Hallo,

habe meinen Fehler nun gefunden. Das geht jetzt schonmal vom Prinzip her.
Allerdings muss ich für jede fundstelle den Button drücken sprich wenn ich ihn drücke ersetzt er den ersten Fund in der Spalte und hört dann auf so das ich für den nächsten Fund wieder auf den Button klicken muss.

Gruß
Budda

Thanatos81 24. Jan 2005 08:05

Re: Stringgrid, in bestimmter Spalte nach String suchen...
 
Dann versuch es doch mal so:

Delphi-Quellcode:
var
   spalte : TStrings;
   p : integer;
begin
  repeat
    spalte := StringGrid1.cols[2]; // die 3. Spalte
   
    p := spalte.IndexOf('rot'); // suche nach "rot"
    if p >= 0 then
       spalte[p] := 'grün';    // ersetzen
  until p < 0;
end;
IndexOf gibt -1 zurück, falls keine Fundstelle vorliegt. Ansonsten halt die Nr des Eintrages.
Kleiner 0 nur um auf Nummer sicher zu gehen, man weiß ja nie, ob alles so klappt, wie es soll :-D

Thanatos81 24. Jan 2005 08:21

Re: Stringgrid, in bestimmter Spalte nach String suchen...
 
Hatte ganz übersehen, dass du speuichern wolltest...
Delphi-Quellcode:
procedure TForm1.speichern;
var t : TextFile;
    c,r : integer;
begin
  AssignFile(t,'c:\stringgrid.txt');
  Rewrite(t);
  for r := 0 to StringGrid1.RowCount-1 do
    begin
      for c := 0 to StringGrid1.ColCount-1 do
        begin        
          Write(t,StringGrid1.Cells[c,r]+';'); //kenne ASCII für Tab gerade nicht,
                                                //deswegen ; zum Trennen
        end;
      Writeln(t,''); //neue Zeile
    end;
  CloseFile(t);
end;

Budda 24. Jan 2005 09:01

Re: Stringgrid, in bestimmter Spalte nach String suchen...
 
Hallo,

danke, das funktioniert. Nur beim Speichern tu ich mich noch schwer.
Wenn ich das so wie du geschrieben hast mache macht er eine Endlosgroße txt datei bis der Rechner abschmiert :)

Schaut man nachträglich in die txt findet man folgendes vor:
Zitat:

0,0;1,0;2,0;3,0;4,0;5,0;6,0;7,0;8,0;9,0;10,0;11,0; 12,0;13,0;14,0;15,0;16,0;17,0
Das ist jetzt nur ein Auszug davon :)
Und das steht auf keinen Fall in der Tabelle ^^

Gruß
Budda

Thanatos81 24. Jan 2005 10:18

Re: Stringgrid, in bestimmter Spalte nach String suchen...
 

Uuups!
Sorry!


Die Zeile
Delphi-Quellcode:
StringGrid1.Cells[c,r] := IntToStr(c)+','+IntToStr(r);
muss raus. Hatte ich zu Testzwecken genommen, um irgendetwas in der Textdatei stehen zu haben...

Aber warum er bei dir ne endlosgroße Textdatei schreibt, versteh ich nicht.

Wieviele Spalten und Zeilen hast du denn? Erhöhst du die dynamisch zur Laufzeit?

Sollte aber eigentlich irrevlevant sein, denn deswegen lass ich ja extra bis RowCount-1 bzw. ColCount-1 laufen, damit man nicht für jede Änderung der Spalten-/Zeilenanzahl der Quelltext ändern muss.

Budda 24. Jan 2005 13:22

Re: Stringgrid, in bestimmter Spalte nach String suchen...
 
Hallo,

habe die Zeile rausgenommen und das Programm gekillt nachdem die textdatei bei 3 MB war :)

Ich fülle das Stringgrid mit einer Textdatei die 1,3MB gross ist.
Das Sind dann 8 Spalten und 6000 Zeilen.

Wenn ich das dann speicher ist der ganze Rechner lahm ohne ende und die Auslagerungsdatei wächst ^^
Wie gesagt bei na 3 MB grossen txt datei dann abgebrochen wobei sich diese auch nicht öffnen lässt, wieder Systemhänger.

Gruß
Budda

Thanatos81 24. Jan 2005 14:29

Re: Stringgrid, in bestimmter Spalte nach String suchen...
 
Das ist aber wirklich seltsam. Wie füllst du das StringGrid denn? Manuell oder lässt du füllen?
Und wieviele Spalten und Zeilen werden dir zur Laufzeit im StringGrid angezeigt?

Falls du kein Problem damit hast, den Quelltext öffentlich zu machen, würde ich mir gerne mal das Formular und die unit ansehen, in der du das machst.

Budda 24. Jan 2005 14:53

Re: Stringgrid, in bestimmter Spalte nach String suchen...
 
Hallo,

das hier ist die Procedure zum einlesen:
Code:
procedure ReadTabFile(FN: TFileName; FieldSeparator: Char; SG: TStringGrid);
var
  i: Integer;
  S: string;
  T: string;
  Colonne, ligne: Integer;
  Les_Strings: TStringList;
  CountCols: Integer;
  CountLines: Integer;
  TabPos: Integer;
  StartPos: Integer;
  InitialCol: Integer;
begin
  Les_Strings := TStringList.Create;
  try
    Les_Strings.LoadFromFile(FN);

    CountLines := Les_Strings.Count + SG.FixedRows;

    T := Les_Strings[0];
    for i := 0 to Length(T) - 1 do Inc(CountCols, Ord(IsDelimiter(FieldSeparator, T, i)));
    Inc(CountCols, 1 + SG.FixedCols);

    if CountLines > SG.RowCount then SG.RowCount := CountLines;
    if CountCols > SG.ColCount then SG.ColCount := CountCols;

    InitialCol := SG.FixedCols - 1;
    Ligne := SG.FixedRows - 1;

    for i := 0 to Les_Strings.Count - 1 do
    begin
      Colonne := InitialCol;
      Inc(Ligne);
      StartPos := 1;
      S := Les_Strings[i];
      TabPos := Pos(FieldSeparator, S);
      repeat
        Inc(Colonne);
        SG.Cells[Colonne, Ligne] := Copy(S, StartPos, TabPos - 1);
        S := Copy(S, TabPos + 1, 999);
        TabPos := Pos(FieldSeparator, S);
      until TabPos = 0;
    end;
  finally
    Les_Strings.Free;
  end;
end;
Macht dann 8 Spalten und 6002 Zeilen :)

Gruß
Budda

Thanatos81 25. Jan 2005 09:21

Re: Stringgrid, in bestimmter Spalte nach String suchen...
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi!

Hab gestern noch zu tun gehabt, deswegen hab ich mich jetzt erst rangesetzt. Fehler hab ich auch schon gefunden. Bei dem Quelltext, den du zum Einlesen verwendest, wird ColCount am Anfang nicht auf 0 gesetzt.
Deswegen hast du nämlich eben nicht 8 Spalten sondern ??? Spalten, je nachdem was in der Speicherzelle vorher drin stand. Bei mir waren mehr als 44.000 ;-). Wobei alles ab Spalte 9 leere Spalten waren...
Pack einfach
Delphi-Quellcode:
ColCount := 0;
nach
Delphi-Quellcode:
Les_Strings.LoadFromFile(FN);
.

Hab auch mal ein Beispielprojekt angefügt, kannste dir ja mal anschauen. Da hab ich die Speichern-Prozedur auch an deine Lesen-Prozedur angepasst.

MfG,
Thana

P.S.: Wo hast du den diesen englisch/französisch Mix her? Hab erst mal nen Schreck bekommen bei "Les_Strings". :shock: Irgendwie mag ich die Sprache nicht, liegt wohl an meiner Ex-Französisch-Lehrerin :x

Thanatos81 25. Jan 2005 09:53

Re: Stringgrid, in bestimmter Spalte nach String suchen...
 
Hab mir das ersetzen gerade noch mal angeschaut. Du könntest alternativ auch folgendes verwenden:
Delphi-Quellcode:
var
   spalte : TStrings;
begin
  spalte := StringGrid1.cols[2]; // die 3. Spalte
  StringReplace(spalte.Text,'grün','rot',[rfReplaceAll])
end;
Musst mal ausprobieren, was schneller ist. Bei obigem Code könntest du [rfReplaceAll] auch durch [rfReplaceAll,rfIgnoreCase] ersetzen, dann wäre Groß-/Kleinschreibung irrelevant. Er würde also nicht nur "grün" ersetzen, sondern auch "Grün", "gRün", "GRün", "grÜn" usw.

[edit1]
Allerdings würde bei dieser Variante auch ersetzt, wenn mehr in der Zelle steht. Also würde "Der Baum ist grün" zu "Der Baum ist rot".
[/edit1]

Budda 25. Jan 2005 13:16

Re: Stringgrid, in bestimmter Spalte nach String suchen...
 
Hallo,

werde das gleich mal testen, schonmal besten Dank :)

Wenn ich das:

Code:
var
   spalte : TStrings;
begin
  spalte := StringGrid1.cols[2]; // die 3. Spalte
  StringReplace(spalte.Text,'grün','rot',[rfReplaceAll])
end;
so abändere:
Code:
var
   spalte : TStrings;
begin
  spalte := StringGrid1.cols[2]; // die 3. Spalte
  StringReplace(spalte.Text,'grün','rot',[rfReplaceAll])
  StringReplace(spalte.Text,'blau','gelb',[rfReplaceAll])
end;
Ersetzt er dann auch noch andere Strings?
In der Spalte müssen nämliche verschieden Strings gesucht und ersetzt werden.

Gruß
Budda

Thanatos81 25. Jan 2005 13:32

Re: Stringgrid, in bestimmter Spalte nach String suchen...
 
Jupp, macht er. Das benutzen wir bei der Ansteuerung eines Druckers über RS232-Schnittstelle, sollte eigentlich schön fix gehen :???:

Budda 27. Jan 2005 08:37

Re: Stringgrid, in bestimmter Spalte nach String suchen...
 
Besten dank.
Jetzt speichert er und das auch schön schnell.
Allerdings hab ich das Problem das der Sauhund :) die letzte Spalte nicht ins StringGrid einliesst.
Ne Idee wo es da hakt? Vorgestern ging das noch ^^

Gruß
Budda


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:41 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