Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   TDataset.Locate mit ListView Integer (https://www.delphipraxis.net/195456-tdataset-locate-mit-listview-integer.html)

Stewag 1. Mär 2018 16:46

TDataset.Locate mit ListView Integer
 
In einem TListview habe ich als zweite Spalte eine ID als SubItem gesetzt.

Da SubItem nur Strings akzeptiert ist die ID dort als String abgelegt, obwohl das Feld in der Datenbank ein Integer ist.

Nun will ich per Locate nach der ID suchen:

Delphi-Quellcode:
if tdata1.Locate('ID', VarArrayOf([StrToInt(Listview1.items[i].Subitems.Text)]), []) then
schlägt aber fehlt mit dem Hinweis, dass "12345" kein gültiger Integer ist.
Offenbar exportiert Variant hier stets einen String.

Hat jemand eine Idee, wie ein Integer exportiert werden kann?

himitsu 1. Mär 2018 16:53

AW: TDataset.Locate mit ListView Integer
 
Ein Variant kann einen Integer enthalten.
Wenn man einem Variant einen Integer zuweist, dann ist der auch als Typ "Integer" im Variant gespeichert und nicht als String. (Variant kann nicht alles, was Delphi kann, aber den kann er)
:gruebel:

Da du nur in einem Feld suchst, lass mal das Array weg und versuche es so
Delphi-Quellcode:
if tdata1.Locate('ID', Listview1.items[i].Subitems.Text, []) then

if tdata1.Locate('ID', StrToInt(Listview1.items[i].Subitems.Text), []) then

Delphi.Narium 1. Mär 2018 17:08

AW: TDataset.Locate mit ListView Integer
 
himitsus erste Variante sollte eigentlich funktionieren.

Ein VarArrayOf braucht man nur, wenn man gleichzeitig nach mehreren Werten suchen will, z. B. sowas:
Delphi-Quellcode:
tdata1.Locate('SpalteVerzeichnis;SpalteDateiname', VarArrayOf([VariabelMitVerzeichnisnamen, VariabelMitDateiname]),[])

Also wenn man beim Locate mehrere Spaltennamen angibt und dann für jede Spalte einen Wert übergeben muss.

Eventuell hilft auch noch ein
Delphi-Quellcode:
if tdata1.Locate('ID', Trim(Listview1.items[i].Subitems.Text), []) then
. Wenn dann das Problem bleibt, müsste man nach weiteren Fehlern suchen, die nicht zwingend direkt vom Locate, sondern eher von den Daten herrühren könnten.

Dann eventuell mal prüfen, ob es in der ID-Spalte eventuell einen Wert gibt, der kein Integer ist. (Bei 'ner Integerspalte natürlich eher unwahrscheinlich, aber ein NULL-Wert könnte da schon zu einem "komischen" Ergebnis führen.)

himitsu 1. Mär 2018 17:15

AW: TDataset.Locate mit ListView Integer
 
Ach ja, ein TDataSet kann eigentlich fast garnichts. (ist mehr sowas wie TStrings, also vor allem eine gemeinsamme Schnittstelle)

Je nach DB-Komponenten kann es sein, dass die hier bissl anders reagieren.
Beim TClientDataSet und bei den DevArt-Komponenten kann man eigentlich auch problemlos einen String mit Zahl rein geben, obwohl man in einem Integer-Feld sucht.

hoika 1. Mär 2018 17:16

AW: TDataset.Locate mit ListView Integer
 
Hallo,
ich würde einfach mal mit einer lokalen Variable arbeiten.
Da macht das Debuggen auch noch mehr Spaß.

Stewag 1. Mär 2018 17:18

AW: TDataset.Locate mit ListView Integer
 
Hallo,

danke für die schnellen Antworten.
Habe nun fest gestellt, dass das Variant gar nicht der Grund für den Fehler war sondern der im Subitem enthaltene Zeilenumbruch:shock:.

Delphi-Quellcode:
showmessage('M'+Listview2.items[i].Subitems.Text+'M');
ergibt nämlich diese Ausgabe:

M12345
M

und nicht diese: M12345M

Die Zuweisung sieht so aus:
Delphi-Quellcode:
ListItem2.SubItems.Add(qCompare2.FieldByName('ID').AsString);
:(

Stewag 1. Mär 2018 17:22

AW: TDataset.Locate mit ListView Integer
 
... bzw. vollständige Zuweisung:

Delphi-Quellcode:
ListItem1, ListItem2: TListItem;

  ListItem2 := ListView2.Items.Add;
  ListItem2.Caption := qCompare2.FieldByName('Bezeichnung').AsString;
  ListItem2.SubItems.Add(qCompare2.FieldByName('ID').AsString);

Delphi.Narium 1. Mär 2018 17:32

AW: TDataset.Locate mit ListView Integer
 
Dann sollte das Trim ausreichen, da das u. a. führende und folgende Zeilenumbrüche wegnimmt.

Bei Stringlisten (und SubItems scheint hier dann jeweils eine zu sein (TListItem.SubItems Property)), bekommt man beim Zugriff auf Text immer einen Zeilenumbruch am Ende "mitgeliefert". Der ist bei Integer nicht so wirklich hilfreich.

Mögliche Lösung (grob und ungetestet):
Delphi-Quellcode:
if Listview1.items[i].Subitems.Count > 0 then begin
  if tdata1.Locate('ID', Listview1.items[i].Subitems[0]), []) then begin

  end;
end;
// oder
if Listview1.items[i].Subitems.Count > 0 then begin
  if tdata1.Locate('ID', StrToInt(Listview1.items[i].Subitems[0])), []) then begin

  end;
end;
// oder
if tdata1.Locate('ID', StrToInt(Trim(Listview1.items[i].Subitems.Text))), []) then begin

end;

himitsu 1. Mär 2018 17:33

AW: TDataset.Locate mit ListView Integer
 
Zitat:

Zitat von Stewag
schlägt aber fehlt mit dem Hinweis, dass "12345" kein gültiger Integer ist.

Zitat:

Zitat von Stewag (Beitrag 1394962)
Habe nun fest gestellt, dass das Variant gar nicht der Grund für den Fehler war sondern der im Subitem enthaltene Zeilenumbruch:shock:.

Ich würde fast wetten das hätte man auch in der Fehlermelung gesehn, wenn du sie "komplett" kopiert hättest. :zwinker:

Strg+C im Exception-Dialog (geht in fast allen Delphi-Dialogen)
und Strg+V hier im Forum, mit [QUOTE]...[/QUOTE] drumrum.

Zitat:

Listview1.items[i].Subitems.Text
Joar, wenn SubItems z.B. eine StringList wäre
und du auch alle Subitems abfragst, anstatt nur das Gewünschte, dann wäre natülich nach jedem SubItem ein Zeilenumbruch. :stupid:
Delphi-Quellcode:
Listview1.Items[i].SubItems[0]
,
Delphi-Quellcode:
Listview1.Items[i].SubItems[0].Text
oder irgendwie so, für das erste SubItem.

Stewag 1. Mär 2018 17:39

AW: TDataset.Locate mit ListView Integer
 
... sooo simpel, ihr seid klasse - vielen Dank!
Und ja, man hätte es an der Fehlermeldung sehen können :oops:


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