Fehler bei Aktualisierung einer ListView

Für Themen zu Datenbanken und Zugriff auf diese. Auch für Datenbankkomponenten.
Joachim Raap
Beiträge: 57
Registriert: Mo 30. Mär 2020, 12:37

Fehler bei Aktualisierung einer ListView

Beitrag von Joachim Raap »

[gelöst] Hallo, zu folgendem Code wird dann verzweigt, wenn Daten aus einer ListView aktualisiert werden sollen.
Wenn die Editfelder über die ListView geladen werden (es wird in eine Zeile der ListView geklickt und der darin dargestellte Satz wird in die Editfelder übernommer), ist alles gut. Werden aber die Editfelder nicht nachgeladen (d.h. der erste Datensatz der ListView wird in die Editfelder geladen und soll bearbeitet weggeschrieben werden), wird ein Fehler erzeugt

(Exception-Klasse >>External: SIGSEGV<<

(was immer das heißt...
Eigentlich sollte mit dem unter gezeigten "if-Statement" eben dieser Fehler abgefangen werden - wird er aber nicht
Kann mir jemand "verständlich" (Anfänger) helfen?

Code: Alles auswählen

if F1ArtGrp.LVArtGrp.Selected <> nil
 then begin
          F1ArtGrp.LVArtGrp.Selected.Subitems[0]:=EdtGrpNr.Text;
          F1ArtGrp.LVArtGrp.Selected.Subitems[1]:=EdtGrpBez.Text;
         end
  else begin
           F1ArtGrp.LVArtGrp.Selected.Subitems[0]:=EdtGrpNr.Text;
           F1ArtGrp.LVArtGrp.Selected.Subitems[1]:=EdtGrpBez.Text;
          end;
Zuletzt geändert von Joachim Raap am Di 19. Mai 2020, 10:20, insgesamt 2-mal geändert.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 4175
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Niederösterreich
Kontaktdaten:

Re: Fehler bei Aktualisierung einer ListView

Beitrag von af0815 »

SIGSEGV sagt das auf einen Speicher zugegriffen hast, der ungültig ist.

Bei der if Bedingung fragst du zwar auf nil ab, greifts aber trotzdem zu. Irgendwie kapier ich nicht was du wirklich willst !)
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
Swirl
Beiträge: 51
Registriert: Fr 7. Aug 2015, 14:05
OS, Lazarus, FPC: win mac linux / jeweils aktuell
CPU-Target: x86_64, ARM Cort.-A7
Wohnort: Schwerte

Re: Fehler bei Aktualisierung einer ListView

Beitrag von Swirl »

Hallo Joachim,

schau dir deinen Code doch noch mal genau an. Ich vermute, du hast da mit copy and paste gearbeitet, ohne den Abschnitt nach else begin dann anzupassen.
Wenn ich deinen Code ins "Deutsche" übersetzen sollte, würde das heißen...

wenn F1ArtGrp.LVArtGrp.Selected <> nil
dann "mache etwas"
sonst "mache dasselbe"

Hinter dem sonst muss ja was anderes stehen als hinter dem dann. In deinem Konstrukt passiert bei True und False dasselbe.
Arbeite mit Lazarus 2.0.8 - FPC 3.0.4 auf Win/Linux
Spiele mit Lazarus auf macOS 10.14 (Mojave)

Joachim Raap
Beiträge: 57
Registriert: Mo 30. Mär 2020, 12:37

Re: Fehler bei Aktualisierung einer ListView

Beitrag von Joachim Raap »

Hallo,
ja - der Code wurde kopiert, ganz bewußt.
Und es soll auch genau das gleich passieren!
Der Unterschied liegt nur darin, daß ich in dem einen Fall einen Satz aus der ListView ausgewählt habe der dann in die Editfelder übertragen wird und in dem anderen Fall der Satz, der nach füllen der ListView in die Editfelder "ohne Auswahl" bearbeitet und gespeichert wird. In jedem Fall also soll nach der Bearbeitung die Änderung zurückgespeichert werden.
Ziel ist nur, den beschriebenen Fehler abzufangen.....
Sorry - ich kann es nicht besser erklären

Joachim Raap
Beiträge: 57
Registriert: Mo 30. Mär 2020, 12:37

Re: Fehler bei Aktualisierung einer ListView

Beitrag von Joachim Raap »

Nachtrag:
Es müßte ja intern eine Variable (ggf.Typ Boolean) geben, anhand der Compiler erkennt, ob aus einer ListView ein Satz ausgewählt worden ist oder nicht. Es ist mir sonst nicht verständlich, warum sich das System unterschiedlich verhält (wird ein Satz ausgewählt ist alles o.k. - wird kein Satz ausgewählt kommt es zu dem Fehler).
Kann man also auf diese "Variable" zugreifen und sie verändern (und wie heißt sie und wie wird sie angesprochen)?

shokwave
Beiträge: 434
Registriert: Do 15. Nov 2007, 16:58
OS, Lazarus, FPC: Win10 (L 1.6 FPC 3.0.0)
CPU-Target: i386,x64
Wohnort: Rudolstadt

Re: Fehler bei Aktualisierung einer ListView

Beitrag von shokwave »

Sorry, aber die Erklärung ist recht verwirrend.

Vielleicht zur Verdeutlichung:

Code: Alles auswählen

if F1ArtGrp.LVArtGrp.Selected <> nil then //Ist in der LV etwas ausgewählt?
begin //ja -> aktualisiere Eintrag -> ok
  F1ArtGrp.LVArtGrp.Selected.Subitems[0]:=EdtGrpNr.Text;
  F1ArtGrp.LVArtGrp.Selected.Subitems[1]:=EdtGrpBez.Text;
end else
begin //nein -> aktualisiere trotzdem, aber WAS????? Es ist jetzt nichts ausgewählt! -> Fehler
  F1ArtGrp.LVArtGrp.Selected.Subitems[0]:=EdtGrpNr.Text;
  F1ArtGrp.LVArtGrp.Selected.Subitems[1]:=EdtGrpBez.Text;
end;


Meintest du vielleicht, das du im 2. Fall einen neuen Eintrag generieren willst? Dann musst du auch einen neuen Eintrag anlegen!
mfg Ingo

shokwave
Beiträge: 434
Registriert: Do 15. Nov 2007, 16:58
OS, Lazarus, FPC: Win10 (L 1.6 FPC 3.0.0)
CPU-Target: i386,x64
Wohnort: Rudolstadt

Re: Fehler bei Aktualisierung einer ListView

Beitrag von shokwave »

Joachim Raap hat geschrieben:Nachtrag:
Es müßte ja intern eine Variable (ggf.Typ Boolean) geben, anhand der Compiler erkennt, ob aus einer ListView ein Satz ausgewählt worden ist oder nicht.


Das fragst du doch an der Stelle ab.

Code: Alles auswählen

if F1ArtGrp.LVArtGrp.Selected <> nil then

Jetzt musst du nur noch darauf reagieren... :)
mfg Ingo

Joachim Raap
Beiträge: 57
Registriert: Mo 30. Mär 2020, 12:37

Re: Fehler bei Aktualisierung einer ListView

Beitrag von Joachim Raap »

mh - noch ein Versuch:
aus der Datenbank (MySQL) werden - um es einfach zu halten - Artikelgruppen ausgelesen, die aus einer Gruppen-Nummer und einem Gruppentext bestehen. In der Datenbank gibt es 5 Sätze.
Diese 5 Sätze werden untereinander nach Gruppennummer sortiert in die ListView geschreiben.
Der 5. Satz (also der letzte) wird zusätzlich in Editfelder übertragen (eines für die Gruppen-Nummer ein zweiter für den Gruppentext).

Nun zum Verhalten:
1. Wähle ich aus der ListView z.B. den 3. Satz aus, wird die Gruppen-Nummer und der Grupentext in die Edit-Felder übertragen. Dort ändere ich z.B. den Gruppentext und speichere ihn zurück in
die Datenbank - das funktioniert und entspricht - shokwave - also dem ersten Fall.
2.Wenn ich aber keine Auswahl aus der ListView treffe - also beim Laden den 5.Satz ändere weil der sowieso in
den Editfeldern steht - kommt es zu dem Fehler.

Ist das Problem deutlicher geworden?

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 4175
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Niederösterreich
Kontaktdaten:

Re: Fehler bei Aktualisierung einer ListView

Beitrag von af0815 »

Und was hat das jetzt mit dem Codeschnipsel zu tun ? Du fragst auf nil ab, deinem Code ist das - komplett egal. Und deine Beschreibung ist im Code nicht ersichtlich.

F1ArtGrp.LVArtGrp.Selected wenn das nisl ist dann kann ein Zugriff auf F1ArtGrp.LVArtGrp.Selected.xxxx nur in einem SIGSEGV enden, da der Zeiger ja nil (=0) ist !!!!

Nochmals, wenn F1ArtGrp.LVArtGrp.Selected ungültig (=nil) ist, dann kann man keine Variable/Property darinnen ansprechen weil diese ganz einfach nicht existiert.
ungültig.Subitems[0]:=EdtGrpNr.Text;
Das geht nicht gut wie du festgestellt hast. Du darfst hier dann nicht F1ArtGrp.LVArtGrp.Selected nehmen, sondern das was du wirklich meinst, wenn etwas nicht selektiert ist.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Joachim Raap
Beiträge: 57
Registriert: Mo 30. Mär 2020, 12:37

Re: Fehler bei Aktualisierung einer ListView

Beitrag von Joachim Raap »

verstehe ich nicht!
Diese Programmstelle habe ich nur dargestellt weil das die Stelle ist, wo der Fehler erzeugt wird - was vorher passiert, habe ich versucht zu beschreiben.
Was wird denn benötigt? der ganze Code?

Benutzeravatar
Swirl
Beiträge: 51
Registriert: Fr 7. Aug 2015, 14:05
OS, Lazarus, FPC: win mac linux / jeweils aktuell
CPU-Target: x86_64, ARM Cort.-A7
Wohnort: Schwerte

Re: Fehler bei Aktualisierung einer ListView

Beitrag von Swirl »

Habe da noch eine Idee...

af0815 hat ja das bisher gesagte auf den Punkt gebracht.

Nochmals, wenn F1ArtGrp.LVArtGrp.Selected ungültig (=nil) ist, dann kann man keine Variable/Property darinnen ansprechen weil diese ganz einfach nicht existiert.

Ich denke, das mit dem nicht möglichen Zugriff auf das nicht vorhandene F1ArtGrp.LVArtGrp.Selected hast do soweit verstanden.
Dem Problem kommen wir vielleicht auf die Spur, wenn du uns deinen Satz...

2.Wenn ich aber keine Auswahl aus der ListView treffe - also beim Laden den 5.Satz ändere weil der sowieso in
den Editfeldern steht - kommt es zu dem Fehler.

...näher erläuterst.

Außerdem bin ich nochmal über einen deiner Sätze oben gestolpert:

...und der darin dargestellte Satz wird in die Editfelder übernommen


In deinen Zuweisungen machst Du es ja eigentlich umgekehrt. F1ArtGrp.LVArtGrp.Selected.Subitems[0]:=EdtGrpNr.Text; müsste dann ja eigentlich EdtGrpNr.Text:=F1ArtGrp.LVArtGrp.Selected.Subitems[0]; heißen.
Arbeite mit Lazarus 2.0.8 - FPC 3.0.4 auf Win/Linux
Spiele mit Lazarus auf macOS 10.14 (Mojave)

Joachim Raap
Beiträge: 57
Registriert: Mo 30. Mär 2020, 12:37

Re: Fehler bei Aktualisierung einer ListView

Beitrag von Joachim Raap »

Sorry - wie gesagt ich bin "Lazarus- und Datenbankanfänger" und verstehe Eure Ausführungen nicht wirklich......
Ich kopiere hier mal den ganzen Code der Procedure hinein - vielleicht kommt ihr damit klar :roll:
procedure TF1ArtGrp.BtSpeichernClick(Sender: TObject);
var
Datum : string;

begin
//Datum aus EdtAnlage korrekt umwandeln
Datum := FormatDateTime('YYYY-MM-DD',Date);
F1LogIn.ConnectDB;
if neuerSatz
then begin
//Prüfen, ob die Gruppennummer über alle Bereiche schon existiert
strGrpNr:='0';
F1LogIn.SQLQuery1.SQL.Text:='select * from art_grp where Grp_Loesch=0 order by Grp_Nr';
F1LogIn.SQLQuery1.open;
while not (F1LogIn.SQLQuery1.EOF) and (strGrpNr<>EdtGrpNr.Text) do
begin
strGrpNr:=F1LogIn.SQLQuery1.FieldByName('Grp_Nr').AsString;
F1LogIn.SQLQuery1.Next;
end;
if strGrpNr=EdtGrpNr.Text
then begin
EdtGrpNr.Text:='';
LblMeldgArtGrp.Font.Color:=clred;
LblMeldgArtGrp.Caption:='Die gewählte Gruppe existiert bereits';
end
else begin
//Prüfung der Gruppennummer o.k. - neuen Datensatz in Datenbank schreiben
strGrpBereich:=IntToStr(CBGrpBereich.ItemIndex);
if EdtGrpBez.Text='' then EdtGrpBez.Text:='n.n.';
F1LogIn.SQLQuery1.SQL.Text:='insert into art_grp (Grp_Nr,Grp_Bez,Grp_AnzArtikel,Grp_Anlage,Grp_Loesch,Grp_Bereich) values ('''+EdtGrpNr.Text+''','''+EdtGrpBez.Text+''','''+EdtArtikel.Text+''','''+Datum+''',0,'''+strGrpBereich+''');';
F1LogIn.SQLQuery1.open;
F1LogIn.CloseDB;
LblMeldgArtGrp.Font.Color := clgreen;
LblMeldgArtGrp.Caption:='Die neue Gruppe wurde angelegt';

//Aktualisierung der ListView
F1ArtGrp.LVArtGrp.Items.Clear;
F1LogIn.SQLQuery1.SQL.Text:='select * from art_grp where Grp_Loesch=0 order by Grp_Nr';
F1LogIn.SQLQuery1.open;
while not F1LogIn.SQLQuery1.EOF do
begin
strGrpID:=F1LogIn.SQLQuery1.FieldByName('Grp_ID').AsString;
strGrpNr:=F1LogIn.SQLQuery1.FieldByName('Grp_Nr').AsString;
strGrpBez:=F1LogIn.SQLQuery1.FieldByName('Grp_Bez').AsString;
strGrpAnzArt:=F1LogIn.SQLQuery1.FieldByName('Grp_AnzArtikel').AsString;
strGrpAnlage:=F1LogIn.SQLQuery1.FieldByName('Grp_Anlage').AsString;
strGrpLoesch:=F1LogIn.SQLQuery1.FieldByName('Grp_Loesch').AsString;
strGrpBereich:=F1LogIn.SQLQuery1.FieldByName('Grp_Bereich').AsString;
UpDateLV (strGrpID,strGrpNr,strGrpBez,strGrpAnzArt,strGrpAnlage,strGrpBereich);
F1LogIn.SQLQuery1.Next;
end;
neuerSatz:=false;
EdtGrpNr.Text:='';
EdtGrpBez.Text:='';
CBGrpBereich.ItemIndex:=-1;
end;
end
else begin
F1LogIn.SQLQuery1.SQL.Text:='select * from art_grp where Grp_ID='''+strGrpID+''';';
F1LogIn.SQLQuery1.Open;
strGrpBereich:=F1LogIn.SQLQuery1.FieldByName('Grp_Bereich').AsString;
if (strGrpNr=EdtGrpNr.Text) and (strGrpBez=EdtGrpBez.Text) and (CBGrpBereich.ItemIndex=StrToInt(strGrpBereich))
then begin
LblMeldgArtGrp.Font.Color:=clred;
LblMeldgArtGrp.Caption:='Speichern nicht notwendig - es wurden keine Änderungen vorgenommen';
end
else begin
//Es wurden Änderungen an der Grp_Nr und/oder der Grp_Bez und/oder dem Grp_Bereich vorgenommen
strGrpBereich:=IntToStr(CBGrpBereich.ItemIndex);
F1LogIn.SQLQuery1.SQL.Text:='update art_grp set Grp_Nr='''+EdtGrpNr.Text+''', Grp_Bez='''+EdtGrpBez.Text+''', Grp_Bereich='''+strGrpBereich+''' where Grp_ID='''+strGrpID+''';';
F1LogIn.SQLQuery1.open;
//ListView aktualisieren #23
if F1ArtGrp.LVArtGrp.Selected <> nil
then begin
F1ArtGrp.LVArtGrp.Selected.Caption;
F1ArtGrp.LVArtGrp.Selected.SubItems[0]:=EdtGrpNr.Text;
F1ArtGrp.LVArtGrp.Selected.SubItems[1]:=EdtGrpBez.Text;
F1ArtGrp.LVArtGrp.Selected.SubItems[4]:=strGrpBereich;
end
else begin
F1ArtGrp.LVArtGrp.Selected.Caption;
F1ArtGrp.LVArtGrp.Selected.SubItems[0]:=EdtGrpNr.Text;
F1ArtGrp.LVArtGrp.Selected.SubItems[1]:=EdtGrpBez.Text;
F1ArtGrp.LVArtGrp.Selected.SubItems[4]:=strGrpBereich;
end;
LblMeldgArtGrp.Font.Color:=clgreen;
LblMeldgArtGrp.Caption:='Der Datensatz wurde aktualisiert';
EdtGrpNr.Text:='';
EdtGrpBez.Text:='';
CBGrpBereich.ItemIndex:=-1;
end;
end;
F1LogIn.CloseDB;
end;

Benutzeravatar
Swirl
Beiträge: 51
Registriert: Fr 7. Aug 2015, 14:05
OS, Lazarus, FPC: win mac linux / jeweils aktuell
CPU-Target: x86_64, ARM Cort.-A7
Wohnort: Schwerte

Re: Fehler bei Aktualisierung einer ListView

Beitrag von Swirl »

Hallo Joachim,

bitte packe mal den gesamten Inhalt deines Projektordners und hänge das zip dann hier rein.

Gruß,
Michael
Arbeite mit Lazarus 2.0.8 - FPC 3.0.4 auf Win/Linux
Spiele mit Lazarus auf macOS 10.14 (Mojave)

wp_xyz
Beiträge: 3264
Registriert: Fr 8. Apr 2011, 09:01

Re: Fehler bei Aktualisierung einer ListView

Beitrag von wp_xyz »

Eigentlich ist der Absturz doch klar, das haben schon einige vor mir geschrieben:

Code: Alles auswählen

if F1ArtGrp.LVArtGrp.Selected <> nil
then begin
  F1ArtGrp.LVArtGrp.Selected.Caption;   // hier ist F1ArtGrp.LVArtGrp.Selected <> nil
  F1ArtGrp.LVArtGrp.Selected.SubItems[0]:=EdtGrpNr.Text;
  F1ArtGrp.LVArtGrp.Selected.SubItems[1]:=EdtGrpBez.Text;
  F1ArtGrp.LVArtGrp.Selected.SubItems[4]:=strGrpBereich;
end
else begin        // hier ist F1ArtGrp.LVArtGrp.Selected = nil, d.h. es existiert nicht und du kannst auf kein Property von F1ArtGrp.LVArtGrp.Selected zugreifen.
  F1ArtGrp.LVArtGrp.Selected.Caption;
  F1ArtGrp.LVArtGrp.Selected.SubItems[0]:=EdtGrpNr.Text;
  F1ArtGrp.LVArtGrp.Selected.SubItems[1]:=EdtGrpBez.Text;
  F1ArtGrp.LVArtGrp.Selected.SubItems[4]:=strGrpBereich;
end;

In der 1. Zeile wird geprüft, ob F1ArtGrp.LVArtGrp.Selected ungleich nil ist. Wenn ja, wird in in den ersten Block nach dem "then" verzweigt und auf Properties von F1ArtGrp.LVArtGrp.Selected zugegriffen. Wenn nicht, wird in den zweiten Block nach "else" verzweigt. Aber dort steht derselbe Code wie in dem 1.Block. Insbesondere greifst du auch wieder auf Properties von F1ArtGrp.LvArtGrp.Selected zu. Aber nun existiert F1ArtGrp.LvArtGrp.Selected gar nicht - das war ja gerade die Bedingung in dem "if" in der 1.Zeile. Joachim, wenn du das nicht vestehst, rate ich dir, nochmals ein paar elementare Pascal-Tutorials anzusehen.

P.S.
Was soll die Zeile "F1ArtGrp.LvArtGrp.Selected.Caption"? Das ist eine Propery. Wenn die so dasteht wie von dir geschrieben, wird sie gelesen und das Ergebnis verworfen. Wanrscheinlich willst du der Caption irgendwas zuweisen, das hast du unter den Tisch fallen lassen. Also: F1ArtGrp.LVArtGrp.Selected.Caption := 'hallo'

Joachim Raap
Beiträge: 57
Registriert: Mo 30. Mär 2020, 12:37

Re: Fehler bei Aktualisierung einer ListView

Beitrag von Joachim Raap »

mh - gelernt habe ich, daß solche Foren offensichtlich immer nur darauf verweisen, daß man irgendwas lesen oder nacharbeiten soll.
Das ich das tun muß, weiß ich eigentlich selbst (habe deutlich mitgeteilt, daß ich für Lazarus und Datenbanken Anfänger bin)- hilft mir für mein aktuelles Problem aber sehr wenig. Auch ist der Code bei "if" oder "else" völlig belanglos weil ich einen Grund und eine Lösung suche, welchen Code man schreiben muß um den Fehler "richtig" vermeiden.
Übrigens - übernommen habe ich den Code für mich abgewandelt aus dem youtube-Tutorial -> https://www.youtube.com/watch?v=XfRGzeJ ... F&index=23
nach ca 14 Min; da scheint es zu funktionieren.

Gut (bzw. nicht gut)

Antworten