Delphi-PRAXiS
Seite 1 von 2  1 2      

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 Strings in ListView vergleichen (https://www.delphipraxis.net/75030-strings-listview-vergleichen.html)

Onkelrossie 13. Aug 2006 01:27


Strings in ListView vergleichen
 
Abend alle zusammen,
ich habe gerade eine Denkblockade. :wall:
Ich möchte aus einem ListView die Strings einer Spalte vergleichen und den Spaltenindex der Position
wo ein sich von dem vorherigen Sting unterscheidender neuer String anfängt in eine StringList adden.
Das klappt auch schon ganz gut bis zum ersten "Unterschied" aber ich weiss wie gesagt gerade nicht weiter
wie ich ab dem ersten "Unterschied" dann weiter vergleiche und in die StringList adde.
Hier mal Auszug wo ich gerade bin.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  i:integer;
  sl: TStringList;
begin
  sl:= TStringList.Create;
  for i := 0 to ListView1.Items.Count - 1 do
  if not (ListView1.Items[i].SubItems[2] = ListView1.Items[i+1].SubItems[2]) then
  break;
  sl.Add(IntToStr(i+1));
end;
Vieleicht findet sich ja noch zu so später Stunde jemand der mir schnell weiter helfen kann. :)


HG
Onkelrossie

marabu 13. Aug 2006 08:19

Re: Strings in ListView vergleichen
 
Guten Morgen,

vielleicht musst du noch eine Kleinigkeit anpassen, aber vom Prinzip her sollte es so funktionieren:

Delphi-Quellcode:
procedure ExtractGroups(li: TListItems; index: Word; s: TStrings);
var
  i: Integer;
  sGroup, sTest: String;
begin
  s.Clear;
  sGroup := '';
  for i := 0 to Pred(li.Count) do
  begin
    sTest := IfThen(index = 0, li[i].Caption, li[i].SubItems[Pred(index)]);
    if (i = 0) or (sTest <> sGroup) then
    begin
      sGroup := sTest;
      s.Values[sGroup] := IntToStr(i);
    end;
  end;
end;

procedure TDemoForm.GroupsButtonClick(Sender: TObject);
begin
  ExtractGroups(ListView.Items, ValueListEditor.Strings);
end;
Grüße vom marabu

Sascha L 13. Aug 2006 09:32

Re: Strings in ListView vergleichen
 
Hallo onkelrossie,

Ich frage mich, wieso du ein break nutzt? Damit fliegst du komplett aus der for-schleife raus. Du willst aber doch weiterhin vergleichen. Warum machst du es nicht so:

Delphi-Quellcode:
1
procedure TForm1.Button1Click(Sender: TObject);
var
  i:integer;
  sl: TStringList;
begin
  sl:= TStringList.Create;
  for i := 0 to ListView1.Items.Count - 1 do begin
    if not (ListView1.Items[i].SubItems[2] = ListView1.Items[i+1].SubItems[2]) then
      sl.Add(IntToStr(i+1));
  end;
end;

Hawkeye219 13. Aug 2006 09:57

Re: Strings in ListView vergleichen
 
Hallo marabu!

Zitat:

Zitat von marabu
Delphi-Quellcode:
sTest := IfThen(index = 0, li[i].Caption, li[i].SubItems[Pred(index)]);

Kommt es hier nicht zu einer Bereichsverletzung, falls index den Wert 0 enthält? Vor dem Aufruf der Funktion IfThen werden doch immer alle Argumente ausgewertet.

Gruß Hawkeye

marabu 13. Aug 2006 16:17

Re: Strings in ListView vergleichen
 
Hallo Hawkeye,

du machst deinem nick alle Ehre - natürlich hast du Recht. Es sind sogar noch weitere Fehler vorhanden, da ich die Prozedur recht kurzentschlossen beim Posten noch verallgemeinert habe: der Hinweis auf die Unit StrUtils (wegen IfThen) fehlt und im Aufrufbeispiel habe ich den Parameter index gar nicht bedient. Hier der korrigierte Code:

Delphi-Quellcode:
procedure ExtractGroups(li: TListItems; index: Word; s: TStrings);
var
  i: Integer;
  sGroup, sTest: String;
begin
  s.Clear;
  sGroup := '';
  for i := 0 to Pred(li.Count) do
  begin
    if index = 0
      then sTest := li[i].Caption
      else sTest := li[i].SubItems[Pred(index)];
    if (i = 0) or (sTest <> sGroup) then
    begin
      sGroup := sTest;
      s.Values[sGroup] := IntToStr(i);
    end;
  end;
end;

procedure TDemoForm.ButtonClick(Sender: TObject);
begin
  ExtractGroups(ListView.Items, 3, ValueListEditor.Strings);
end;
Aber immernoch geht es nur ums Prinzip - Prüfungen fehlen und eine implizite Voraussetzung sind sortierte Spaltenwerte.

Freundliche Grüße vom marabu

Onkelrossie 14. Aug 2006 17:09

Re: Strings in ListView vergleichen
 
Hallo,
danke erstmal für deine Vorschläge, Marabu! Ich werde sie gleich einmal testen und dann Antwort geben.

Zitat:

Zitat von Sascha L
Hallo onkelrossie,
Ich frage mich, wieso du ein break nutzt? Damit fliegst du komplett aus der for-schleife raus. Du willst aber doch weiterhin vergleichen. Warum machst du es nicht so:

Delphi-Quellcode:
1
procedure TForm1.Button1Click(Sender: TObject);
var
  i:integer;
  sl: TStringList;
begin
  sl:= TStringList.Create;
  for i := 0 to ListView1.Items.Count - 1 do begin
    if not (ListView1.Items[i].SubItems[2] = ListView1.Items[i+1].SubItems[2]) then //Exception
      sl.Add(IntToStr(i+1));
  end;
end;

Das hatte ich auch schon versucht aber ich bekam dann eine Exception in der Zeile die ich oben markiert habe, da der Listenindex übersprungen wird. Wie gesagt es war auch schon spät in der Nacht und ich konnte nicht mehr klar Denken. Wenn ich den Code jetzt so sehe dann ist mir klar das es ListView1.Items.Count - 2 heisen muss da ich ja auch immer beim vergleichen eine zeile dazu addiere. Ich habs nun auf ListView1.Items.Count - 2 geändert und schon gings. :)

HG
Onkelrossie

_frank_ 14. Aug 2006 18:25

Re: Strings in ListView vergleichen
 
Delphi-Quellcode:
  for i := 0 to ListView1.Items.Count - 1 do
und
Delphi-Quellcode:
if not (ListView1.Items[i].SubItems[2] = ListView1.Items[i+1].SubItems[2]) then //Exception
passen nicht zusammen, denn im letzten durchlauf greifst du so auf
Delphi-Quellcode:
ListView1.Items[ListView1.Items.Count].SubItems[2]
zu, was zu der Exception führt...mach die schleife bis -2 dann sollte es gehen

Gruß Frank

C.Schoch 14. Aug 2006 18:27

Re: Strings in ListView vergleichen
 
Hi,
So vergleichst du aber nur den vorherigen String mit dem nächsten und nicht jeden String mit jedem in der Liste.

@Frank
Steht doch schon im vorherigen Post.

Onkelrossie 15. Aug 2006 03:18

Re: Strings in ListView vergleichen
 
Morgen,
@C.Schock, genau das wollte ich auch nur.
@_frank_, das habe ich doch schon geschrieben.
@Marabu, dein Code funktionierte bei mir nach ein paar änderungen auch wunderbar.

Danke nochmal an alle die geholfen haben.


HG
Onkelrossie

Onkelrossie 15. Aug 2006 23:17

Re: Strings in ListView vergleichen
 
Abend zusammen,
ich stehe schon wieder vor einem Problem. :gruebel:
ich habe nun wie oben beschrieben ein ListView in dem ich eine Spalte auf Unterschiede durchlaufe bzw. den Index wo ein neuer Wert anfängt in eine StringList speichere. Jetzt wollte ich die Spalte paralell daneben auf Gleichheit prüfen.

z.B.
Delphi-Quellcode:
SubItem1 | SubItem2  //Die Spalte "SubItem2" Definiert die Gruppe
---------|--------- 
gleich  | a      } 
gleich  | a      } Gruppe1(SubItem1 = vollständig)
gleich  | a      } 
         |
gleich  | b      } 
ungleich | b      } Gruppe2(SubItem1 <> vollständig)
ungleich | b      }
SubItem2 durchlaufe ich ja schon wie beschrieben mit diesem Code womit ich den Index bekomme wo eine neue Gruppe anfängt:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  i:integer;
  sl: TStringList;
begin
  sl:= TStringList.Create;
  for i := 0 to ListView1.Items.Count - 2 do
  if not (ListView1.Items[i].SubItems[2] = ListView1.Items[i+1].SubItems[2]) then
  sl.Add(IntToStr(i+1));
end;
Jetzt wollte ich, das auf Basis dieses Codes SubItem1 durchlaufen wird und den Index des letzten Items der jeweiligen Gruppe zurrück gibt, deren Items den Wert "gleich" haben. Solange in einer Gruppe noch ein wert namens "Ungleich" ist soll garnix passieren. Bis jetzt habe ich es wieder so weit hin bekommen das es mit der ersten Gruppe klappt. Aber danach scheint irgendwo was falsch zu laufen in den For Schleifen.
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  i, idx, c :integer;
  sl, slok: TStringList;
begin
  sl:= TStringList.Create;
  for i := 0 to ListView1.Items.Count - 2 do
  if not (ListView1.Items[i].SubItems[2] = ListView1.Items[i+1].SubItems[2]) then
  sl.Add(IntToStr(i+1));
  for idx := 0 to sl.Count - 2 do
  begin
    for I := StrToInt(sl.Strings[idx]) to StrToInt(sl.Strings[idx + 1]) do
    begin
      if Listview1.Items[i].SubItems[2] = 'gleich' then c := c + 1;          //hier wusste ich nicht mehr so richtig wie ich weiter
      if c = StrToInt(sl.Strings[idx + 1]) then slok.add(sl.Strings[idx + 1]; //machen sollte und dabei ist das raus gekomen
    end;
  end;
end;
Ich hoffe ich konnte mein Problem verdeutlichen und es findet sich jemand der mir helfen kann.
Danke schonmal im vorraus an alle die sich die Zeit nehmen eine Lösung zu finden.


HG
Onkelrossie


Alle Zeitangaben in WEZ +1. Es ist jetzt 14:39 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz