Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Code wird nicht ausgeführt - warum? (erledigt, danke an Popov) (https://www.delphipraxis.net/179611-code-wird-nicht-ausgefuehrt-warum-erledigt-danke-popov.html)

d7user1 19. Mär 2014 18:55


Code wird nicht ausgeführt - warum? (erledigt, danke an Popov)
 
hallo. ich habe momentan ein ganz seltsames problem. so etwas habe ich noch nie erlebt.

ich habe eine form mit einer listview. die items sind mit checkboxen versehen.
parallel gibt es eine stringlist in welcher die selben "werte" zu finden sind.

in einem ListView1MouseUp() ist nun folgende schleife enthalten:
Delphi-Quellcode:
Item := ListView1.GetItemAt(X, Y);
// ...
for i := 0 to WerteListe.Count - 1 do
      begin
       if ItemGefunden(Item, i) then begin
        break;
       end;
      end;
der funktion ItemGefunden wird "i" übergeben und in der funnktion gibt es dann soetwas wie
Delphi-Quellcode:
{* ... *}Zeile := WerteListe.Strings[i];
in der weteren ausfhrung wird einfach nur geguckt ob dieser wert "Zeile" ein "_" als erstes zeichen hat oder nicht.
wenn ja, wird es entfernt anderenfalls wird es hinzugefügt:

Delphi-Quellcode:
if WerteListe.Strings[i][1] = '_' then
      WerteListe.Strings[i] := Copy(WerteListe.Strings[i], 2, Length(WerteListe.Strings[i]))
     else
      WerteListe.Strings[i] := '_' + WerteListe.Strings[i];
und genau da ist das seltsame problem:

wenn ich alles so belasse wird der code niemals ausgeführt bzw. die liste WerteListe wird niemals geupdatet.
wenn ich aber vor dem if ein
Delphi-Quellcode:
showmessage();
setze wird die if-bedingung abgerabritet und die liste WerteListe ändert sich.

aber ohne showmessage() funktioniert es nicht, warum?
ich kann showmessage() auch in
Delphi-Quellcode:
ListView1MouseUp()
unter die for-schleife packen, dann funktioniert es auch.
aber ohne showmessage() ändert sich nichts.

ich habe schon daran gedacht dass das vielleicht etwas mit dem abarbeten der messages zu tun haben könnte, aber da kenne ich mich nicht aus.

Der schöne Günther 19. Mär 2014 19:10

AW: Code wird nicht ausgeführt - warum?
 
Ich glaube ein Minimalbeispiel dass man bei sich ausführen kann würde die Sache viel einfacher machen.

Spontan hätte ich gesagt dass der Code (natürlich) sehr wohl ausgeführt wird, nur nie grafisch auf der Form dargestellt wird da du an irgendwelchen Strings bastelst ohne dass der Listview etwas davon mitbekommt. Wenn jetzt einmal eine Messagebox drübergelegt wird muss sich der Listview neu zeichnen und tut das dann (mit den aktuellen Strings).

d7user1 19. Mär 2014 19:14

AW: Code wird nicht ausgeführt - warum?
 
ein beispiel kann ich leider nicht anhängen da mein code an vielen ecken und enden mit vielen weiteren dingen verknüpft ist.

es ist lediglich eine stringlist mit ein paar werten und dieselben werte sind in der listview grafisch dargestellt.
checke ich jetzt listview-1 dann sollte in der stringlist eigentlich item-1 ein "_" vorangestellt bekommen. mehr passiert hier nicht.

aber warum so etwas einfaches nicht funktioniert weiß ich nicht.

das schlimme ist dass es bis gestern noch funktioniert hat und jetzt ohne änderungen an der logik funktioniert es nicht mehr.


grob kann man sagen dass die stringlist nicht angerührt wird wenn kein showmessage auftaucht.

Popov 19. Mär 2014 19:31

AW: Code wird nicht ausgeführt - warum?
 
Was verstehst du unter "nicht ausgeführt" (sorry für den Fall, dass du es geschrieben hast und ich es übersehen habe)?
  1. Das Programm startet, aber das Ergebnis ist falsch?
  2. Das Programm bricht mit einer Fehlermeldung?
  3. Das Programm startet überhaupt nicht?

//Edit

Wie passt
Delphi-Quellcode:
if ItemGefunden(Item, i) then begin
in die Funktion? Was macht es da? Item ist vom Typ TListItem. So wie ich das sehen, bewegst du die Maus über ListView und je nachdem von wo du es ausführst, führt es bei jeder Masusbewegung pro Pixel deine Funktion aus? Ist das korrekt?

In dem Codeteil aus der Funktion taucht Item nicht auf.

Der schöne Günther 19. Mär 2014 19:36

AW: Code wird nicht ausgeführt - warum?
 
Zitat:

Zitat von d7user1 (Beitrag 1252599)
ein beispiel kann ich leider nicht anhängen da mein code an vielen ecken und enden mit vielen weiteren dingen verknüpft ist.

es ist lediglich eine stringlist mit ein paar werten und dieselben werte sind in der listview grafisch dargestellt.

Die Situation wie du sie schilderst lässt viel zu viel Raum für Interpretationen und Abweichungen ("Davor dann noch ein if" ...).

Ich weiß nicht, ob ich da auf einem zu hohen Ross sitze. Aber ich finde, man sollte sich die drei Minuten Mühe machen, ein Minimalbeispiel für die Leute, die das Problem finden sollen, zu erstellen.

himitsu 19. Mär 2014 19:41

AW: Code wird nicht ausgeführt - warum?
 
Zitat:

Delphi-Quellcode:
 WerteListe.Strings[i][1]

Was wird wohl passieren, wenn da mal ein leerer String (
Delphi-Quellcode:
''
) auftaucht?


Wieso baut eigentlich "WertGefunden" den Wert um, wo es doch angeblich nur sucht?
Entweder es gibt noch sowas wie "WertUmschalten", welched danach den Wert ändert,
oder man gibt der "Gefunden"-Funktion einen entsprechenden Namen.


Manchmal fragt man sich, warum keiner auf die blöde Idee kommt den Debugger auszuprobieren.
Und eventuell auch mal die Index- und Bereichsprüfung in den Projektoptionen zu aktivieren.

nachti1505 19. Mär 2014 19:51

AW: Code wird nicht ausgeführt - warum?
 
Ich rate mal und sage: Ohne ShowMessage wird die ListView einfach nicht neu gezeichnet.... veranlasse doch nach der Änderung ein Neuzeichnen!

himitsu 19. Mär 2014 19:57

AW: Code wird nicht ausgeführt - warum?
 
Zitat:

Zitat von nachti1505 (Beitrag 1252606)
Ich rate mal und sage: Ohne ShowMessage wird die ListView einfach nicht neu gezeichnet.... veranlasse doch nach der Änderung ein Neuzeichnen!

Je nach ListView-Style kommt es drauf an "wie" man das zuweist.

Und Standardmäßig sollte sich die Anzeige von selbst aktualisieren.

Aber
Zitat:

Delphi-Quellcode:
in der funnktion gibt es dann soetwas wie {* ... *}Zeile := WerteListe.Strings[i];

sagt ja sowas von garnichts aus.

d7user1 19. Mär 2014 19:59

AW: Code wird nicht ausgeführt - warum?
 
Zitat:

Ich rate mal und sage: Ohne ShowMessage wird die ListView einfach nicht neu gezeichnet.... veranlasse doch nach der Änderung ein Neuzeichnen!
ich ändere die listview nicht. ich ändere die dazu parallel erstellte stringlist.

Zitat:

Was wird wohl passieren, wenn da mal ein leerer String ('' ) auftaucht?
das wird nie passieren da es prüfungen gibt die das nicht zulassen.

Zitat:

Wieso baut eigentlich "WertGefunden" den Wert um, wo es doch angeblich nur sucht?
Zitat:

( ... ) in der weteren ausfhrung wird einfach nur geguckt ob dieser wert "Zeile" ein "_" als erstes zeichen hat oder nicht.
wenn ja, wird es entfernt anderenfalls wird es hinzugefügt:

wie kann ich denn mit dem debuggen genau an dieser stelle anfangen?

Popov 19. Mär 2014 20:07

AW: Code wird nicht ausgeführt - warum?
 
Wo wir dabei sind, warum über
Delphi-Quellcode:
ListView1MouseUp()
und
Delphi-Quellcode:
ListView1.GetItemAt(X, Y)
?

Da gibt es doch bessere Möglichkeiten, z. B. OnClick oder OnDblClick:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
  NewColumn: TListColumn;
  ListItem: TListItem;
begin
  with ListView1 do
  begin
    ViewStyle := vsReport;
    NewColumn := Columns.Add;
    NewColumn.Caption := 'Caption';
    NewColumn.Width := 150;
    for i := 1 to 10 do
    begin
      ListItem := Items.Add;
      ListItem.Caption := 'Caption #' + IntToStr(i);
    end;
  end;
end;

procedure Test(Item: TListItem; i: Integer);
begin
  ShowMessage(Format('i ist: %d; Caption: %s', [i, Item.Caption]));
end;

procedure TForm1.ListView1DblClick(Sender: TObject);
begin
  if not (Sender is TListView) then Exit;

  with TListView(Sender) do
    Test(Selected, 4711);
end;
Und um das zu steigern, warum Werte in einer Parallel-StringList? Warum nicht als Bagage an ListView?
Delphi-Quellcode:
type
  TMeineDaten = class
    Str: String;
    Int: Integer;
  end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
  NewColumn: TListColumn;
  ListItem: TListItem;
  MeineDaten: TMeineDaten;
begin
  with ListView1 do
  begin
    ViewStyle := vsReport;
    NewColumn := Columns.Add;
    NewColumn.Caption := 'Caption';
    NewColumn.Width := 150;

    for i := 1 to 10 do
    begin
      MeineDaten := TMeineDaten.Create;
      MeineDaten.Str := '_Abc';
      MeineDaten.Int := 123;

      ListItem := Items.Add;
      ListItem.Caption := 'Caption #' + IntToStr(i);
      ListItem.Data := MeineDaten;
    end;
  end;
end;

procedure Test(Item: TListItem; i: Integer; Daten: TMeineDaten);
begin
  ShowMessage(Format('i ist: %d; Caption: %s', [i, Item.Caption]));

  ShowMessage(Format('Daten aus Bagage: %s und %d', [Daten.Str, Daten.Int]));
end;

procedure TForm1.ListView1DblClick(Sender: TObject);
begin
  if not (Sender is TListView) then Exit;

  with TListView(Sender) do
  begin
    Test(Selected, 4711, TMeineDaten(Selected.Data));
  end;
end;

//WICHTIG: bei löschen, der Items muss das Objekt vorher freigegeben werden!!!

Popov 19. Mär 2014 20:13

AW: Code wird nicht ausgeführt - warum?
 
Zitat:

Zitat von d7user1 (Beitrag 1252608)
wie kann ich denn mit dem debuggen genau an dieser stelle anfangen?

Eie Möglichkeit: in der Funktion am Anfang ein Haltezeichen setzten und dann (oder schon vorher) im Menü Ansicht>Debug-Fenster>Lokale Variablen wählen und Programm starten. Du bekommst ein Fenster mit aktuellen lokalen Werten. Mit der Funktionstaste F7 kannst du dann Zeile für Zeile weiter gehen.

PS: wenn da steht "auf Daten können wegen der Optimierung nicht zugegriffen werden", dann ist die Variable entweder unwichtig und oder bereits wieder entfernt, aber auf jeden Fall wegoptimiert.

d7user1 19. Mär 2014 20:19

AW: Code wird nicht ausgeführt - warum?
 
Zitat:

Wo wir dabei sind, warum über ListView1MouseUp() und ListView1.GetItemAt(X, Y) ?
das mache ich so weil ich in der listview auf eine CheckBox klicke und der code nur ausgeführt werden soll wenn ich diese eben klicke.

ich habe dein beispiel mit OnClick mal ausprobiert und es funktioniert. mein code macht nichts anderes aber es funktioniert nicht.

ich glaube das liegt daran dass ich mich im OnMouseUp-Event befinde. aber wenn ich tatsächlich auf OnClick umsteige, wie komme ich an den klick auf die checkbox dran?

---

ich habe das jetzt mal geändert:
es wird nicht mehr geprüft ob ich auf eine checkbox klicke und und und.
sobald ich das fenster mit der listview bestätige um den prozess danach zu starten rufe ich folgendes auf:
Delphi-Quellcode:
 for i := 0 to WerteListe.Count - 1 do
  begin
   for j := 0 to ListView1.Items.Count - 1 do
    begin
     if (not ListView1.Items[j].Checked) and ItemGefunden(ListView1.Items[j], i) then
      begin
       break;
      end;
    end;
  end;
selbst bei einer sortierten liste nach klick auf eine column wird so genau der string aus der stringlist entfernt welcher in der listview nicht checked ist.

aber warum das nicht in OnMouseUp nicht funktioniert sondern nur mit showmessage ist mir ein großes rätsel.

Popov 19. Mär 2014 20:30

AW: Code wird nicht ausgeführt - warum?
 
Delphi-Quellcode:
procedure Test(Item: TListItem; i: Integer; Daten: TMeineDaten);
const
  Schwadawum: array[Boolean] of String = ('nicht gesetzt.', 'gesetzt');
begin
  //ShowMessage(Format('i ist: %d; Caption: %s', [i, Item.Caption]));

  //ShowMessage(Format('Daten aus Bagage: %s und %d', [Daten.Str, Daten.Int]));

  ShowMessage(Format('Die Checkbox ist %s', [Schwadawum[Item.Checked]]));
end;
EDIT:

Delphi-Quellcode:
   for j := 0 to ListView1.Items.Count - 1 do
    begin
     if (not ListView1.Items[j].Checked) and ItemGefunden(ListView1.Items[j], i) then
Warum gehst du alle Items durch. Du hast doch das eine Item, das du angeklickt hast, doch geschickt. Du mußt nur das abfragen.

d7user1 19. Mär 2014 20:34

AW: Code wird nicht ausgeführt - warum?
 
es tut mir leid dass ich kein beispiel posten wollte und das was ich gepostet habe schwachsinn zu sein scheint.

ich werde mich mal einlesen ob bei OnMouseUp irgendwelchen speziellen messages gepostet werden und ob da was geblockt hat.

nur noch eine sache zur bagage:
die daten liegen in einer externen stringlist da ich diese stringlist noch an anderer stelle sehr häufig brauche.

Popov 19. Mär 2014 20:43

AW: Code wird nicht ausgeführt - warum?
 
Doppelte Pflege ist niemals gut.

NACHTRAG:

OnMouseUp ist für das was du vorhast nicht das optimale Ereignis, es gibt bessere. GetItemAt bietet zwar die Möglichkeit, aber dafür ist es nicht gedacht. Wenn dir ein OnDblClick nicht passt, es gibt noch OnClick. Wie gesagt, das ListItem auf das du geklickt hast kannst du auch über Selected ermitteln, statt mit GetItemAt. Das eine sagt welches ListItem aktuell ausgewählt ist (bei MultiSelected = False, sonst ist es das Erste), das andere über welchem ListItem sich gerade die Maus befindet.

Guck dir mal die Ereignisse mal der Reihe mal durch.

d7user1 19. Mär 2014 20:57

AW: Code wird nicht ausgeführt - warum?
 
Delphi-Quellcode:
Warum gehst du alle Items durch. Du hast doch das eine Item, das du angeklickt hast, doch geschickt. Du mußt nur das abfragen.
diese for-schleife befindet sich in einem ButtonOnClick. ich frage ganz zum schluss ab welche items checked sind und welche nicht.

zur bagage nochmal:
kann es sein dass ich mir diese doppelte for-schleife zum finden eines items und dem passendem stringlist-eintrag mit dem bagage sparen kann da die daten direkt am item hängen?

d7user1 19. Mär 2014 22:17

AW: Code wird nicht ausgeführt - warum?
 
ich melde mich noch ein letztes mal. die letzte stunde habe ich mir das mit dem bagage mal genauer angeguckt.

wenn ich vorher ein item angeklickt habe, habe ich mir das dazu passende item in der stringlist mit zwei verschachtelten for-schleifen gesucht.
bei wenigen dateien kein problem. aber dann habe ich es mit 13.000 probiert. rein rechnerich beenden sich die schleifen nicht für 13.000 * 13.000 duchläufe.

das war aber alles zu lange. ein durchlauf war noch nach 5 minuten nicht beendet.

jetzt gebe ich jedem listitem bei der erstellung (Items.Add) daten bei .Data mit auf dem weg.

suche ich nun den passenden eintrag in der stringlist sieht das so aus:

Delphi-Quellcode:
 with ListView1 do
  begin
for i := 0 to Items.Count - 1 do
    begin
     if not Items[i].Checked then
      begin
       IndexInSL := TMeineDaten(Items[i].Data).MeinIndex;
       WertInSL := WerteListe.Strings[IndexInSL];

       if WertInSL[1] = '_' then
        WerteListe.Strings[IndexInSL] := Copy(WertInSL, 2, Length(WertInSL))
       else
        WerteListe.Strings[IndexInSL] := '_' + WertInSL;
      end;
    end;
end;
statt 13.000 * 13.000 durchläufen gibt es nun nur noch 13.000 und statt 5 minuten und mehr dauert das alles nur noch 400 millisekunden.

Popov 19. Mär 2014 23:27

AW: Code wird nicht ausgeführt - warum? (erledigt, danke an Popov)
 
Welche Delphi-Version hast du?

EDIT:

Delphi-Quellcode:
if WertInSL[1] = '_' then
Was passiert eigentlich wenn der WertInSL leer ist? Kabum? Oder gibt es keine leeren Strings? Wie wäre es vorher zu prüfen ob die Länge größer 0 ist?

d7user1 19. Mär 2014 23:29

AW: Code wird nicht ausgeführt - warum? (erledigt, danke an Popov)
 
ich hatte vorher delphi 7 und 2005 personal, habe danach turbo delphi getestet und bin am ende doch bei delphi 2005 personal geblieben.

Popov 19. Mär 2014 23:32

AW: Code wird nicht ausgeführt - warum? (erledigt, danke an Popov)
 
Ich kenne mich mit 2005 nicht aus. Prüfe mal bitte ob TListView evtl. die Eigenschaft OwnsObjects hat und wenn ja, ob True oder False gesetzt.

d7user1 19. Mär 2014 23:33

AW: Code wird nicht ausgeführt - warum? (erledigt, danke an Popov)
 
ne, ich habe OwnerDraw und OwnerData aber das von dir genannte nicht.

Popov 19. Mär 2014 23:42

AW: Code wird nicht ausgeführt - warum? (erledigt, danke an Popov)
 
Hast du in der Hilfe nach geguckt, oder nur unter Objektinspector?

Der Grund ist, modernere Delphiversionen haben bei etlichen Klassen den besagten OwnsObjects Schalter. Ist es da und ist es True gesetzt, gibt die Klasse das angehängte Objekt automatisch frei beim löschen eines Items. Man muss es also nicht selbst tun.

Ist es nicht da, muss man für das Löschen der Items eine eigene Routine schreiben.

d7user1 19. Mär 2014 23:52

AW: Code wird nicht ausgeführt - warum? (erledigt, danke an Popov)
 
ich habe im OI nachgeguckt. anscheinend gibt es den nicht bei ListView bzw. Delphi 2005 PE

Popov 19. Mär 2014 23:56

AW: Code wird nicht ausgeführt - warum? (erledigt, danke an Popov)
 
In dem Fall mußt du es selbst machen.

Oder du guckst in der OH nach.

d7user1 20. Mär 2014 00:04

AW: Code wird nicht ausgeführt - warum? (erledigt, danke an Popov)
 
ok ist erledigt:

Delphi-Quellcode:
procedure ListView1Deletion(Sender: TObject; Item: TListItem);
begin
 TObject(Item.Data).Free;
 Item.Data := nil;
end;

// ...

ListView1.Items.Clear; // löscht auch alle Data-Objekte (getestet)


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:54 Uhr.

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