![]() |
Datenbank: SQL Server 2012 • Version: 11 • Zugriff über: XE 3
Stack Überlauf fehler
Guten Morgen,
ich habe vor, dass in meinem DBGrid sobald sich irgendwas in diesem Tut, eine Prozedure aufgerufen wird. Diese Procedure greift auf die mit dem DBGrid verknüpfte Datenbank zu und durchläuft diese. Es soll geguckt werden, ob in dem speziellen Datensatz der Artikel bestellt ist oder nicht. In der Datenbank wird existiert dafür ein Boolisches Feld. Die Prozedur sieht wir folgt aus:
Delphi-Quellcode:
Da sich die Daten in dem Grid ändern und somit evtl. auch der Bestell Status muss immer erst geschaut werden ob der Button gezeichnet werden muss oder eben nicht.
procedure TAuftrag_form.BestellbtnCreate();
var i:integer; begin i:=1; Ersatzteil_Dataset.First; while not Ersatzteil_Dataset.Eof do begin if Ersatzteil_DatasetBestellt.Value=True then begin DBAdvGrid4.RemoveButton(7,DBAdvGrid4.Row); end; Ersatzteil_Dataset.Next; end; Ersatzteil_Dataset.first; while not Ersatzteil_Dataset.Eof do begin if Ersatzteil_DatasetBestellt.Value=False then begin DBAdvGrid4.AddButton(7,DBAdvGrid4.Row,50,15,'Bestellen',TCellHAlign(2),TCellVAlign(2)); end; Ersatzteil_Dataset.Next; end; end; Wen ich mir die Prozedur auf einen Knopf lege ist alles inordnung. Möchte ich allerdings diese Prozedur in der Datasource beim OnChange aufrufen stürzt das Programm immer ab und gibt die Meldung "Stack Überlauf". Ich könnte mir vorstellen, dass die Datasource noch nicht bereit ist oder noch irgendwelche Aufgaben erledigen muss aber wie kann ich Abfragen ob dem so ist? Bzw. wie kann ich generell dieses Problem lösen? Gruß Chris |
AW: Stack Überlauf fehler
Du meinst vermutlich TDatasource.OnDataChange? Das wird auch ausgelöst, wenn sich der aktive Datensatz ändert. Da Du die Datenmenge durchläufst, wird das also ausgelöst, durchläuft die Datenmenge, wird wieder ausgelöst und durchläuft die Datenmenge etc. pp.
|
AW: Stack Überlauf fehler
Rate mal, was OnChange OnDataChange macht, wenn deine Funktion anfängt durch das DataSet zu Scrollen?
Tipp: Haltepunkt auf den Start deiner Funktion und dann schön mit F7 durchsteppen. PS: Zitat:
und verwende
Delphi-Quellcode:
und
if x then
Delphi-Quellcode:
.
if not x then
Reicht es nicht, wenn du nur einmal durchscrollst und in einem durchgang die Buttons hinzufügst? Oder müssen die unbedingt nacheinander sein. |
AW: Stack Überlauf fehler
Da ist offenbar vieles im Argen:
1. Man prüft Boolsche Ausdrücke nicht auf True! Eine Abfrage, ob ein Ausdruck wahr oder falsch ist, sieht folgendermaßen aus:
Delphi-Quellcode:
2. Mit diesem Konstrukt ist es nun auch nicht mehr nötig, die ganze Tabelle zweimal zu durchlaufen, da ein Boolean-Wert entweder wahr oder falsch ist und für beide Fälle entsprechende Methoden bereitgestellt werden.
if Ersatzteil_DatasetBestellt.Value then
begin TuDiesUndDas; TuDasAuchNoch; end else begin TuWasAnderes; TuNochWasAnderes; end; 3. Wenn du eine Ereignisbehandlung schreibst, in der das Ereignis, für das du diese Procedure schreibst, aufgerufen werden kann, ohne daß eine Abbruchbedingung definiert wurde, mußt du dich nicht wundern, wenn das einen Stack-Überlauf zur Folge hat. Recursive Programmierung erfordert also immer eine Abbruchbedingung. 4. Was möchtest du wirklich erreichen? Offenbar hast du ein DBGrid, das eine Tabelle mit Artikeln darstellt. Nun möchtest du jedesmal, wenn der Anwender einen Datensatz selektiert, prüfen, ob für diesen Artikel eine Bestellung vorliegt (wozu auch immer). Liegt keine Bestellung vor, soll, wie ich das verstanden habe, ein Button sichtbar werden, mit dem man eine solche Bestellung vornehmen kann. Und diesen Button möchtest du, wie es scheint, in einer Spalte des DBGrids erscheinen lassen? Wieso eigentlich? Ich würde hier einen Button unterhalb oder neben dem DBGrid platzieren, der je nach Zustand der entsprechenden Spalte (Value?) enabled oder disabled ist. In der Ereignisbehandlungsmethode AfterScroll deines Datasets löst du nun ein Ereignis aus, das den betreffenden Button je nach Zustand der entsprechenden Spalte auf verfügbar (enabled := true) oder nicht verfügbar setzt. Es ist also nicht notwendig, beim Wechseln des Datensatz-Zeigers jedesmal die ganze Tabelle zu durchlaufen, denn du möchtest ja nur diesen einen Datensatz überprüfen. |
AW: Stack Überlauf fehler
Morgen und danke für die Antworten.
Ja war bisschen schlampig implementiert. Ja hab auch das onDataChange Ereignis gemeint. Sorry für die ungenauigkeit, kommt nicht mehr vor. Zu der Logik bzw. Notwendigkeit des mehrmaligen Durchlaufen dieser Datenbank: Ich habe verschieden Geräte bzw. Reparaturen denen ich verschiedene Ersatzteile hinzufügen möchte aber auch löschen. Desweiteren kann man innerhalb dieses Forms zu anderen Geräten bzw. Reparaturaufträgen scrollen. Ich hatte halt die Idee die Knöpfe immer dann zu zeichenen (bzw. löschen) wenn sich was ändert. Ich könnte jetzt auch alle Eventualitäten und möglichen Triggerzeitpunkte raussuchen und dort dann überprüfen ob die Knöpfe gezeichnet werden müssen oder nicht. Fände es aber beim OnDataChange besser. Das mit dem Rekursiven aufruf leuchtet ein. Hab jetzt eine Wartemarke erstellt und blocke den Zugriff während die Datenbank durchlaufen wird. Danke für die schnelle und gute Hilfe. Zur Komplettierung hier nochmal der ordentliche Code:wink:
Delphi-Quellcode:
procedure TAuftrag_form.BestellbtnCreate();
var i:integer; begin busy :=true; Ersatzteil_Dataset.First; while not Ersatzteil_Dataset.Eof do begin if Ersatzteil_DatasetBestellt.Value then begin DBAdvGrid4.RemoveButton(7,DBAdvGrid4.Row); end else begin DBAdvGrid4.AddButton(7,DBAdvGrid4.Row,50,15,'Bestellen',TCellHAlign(2),TCellVAlign(2)); end; Ersatzteil_Dataset.Next; end; busy:=false; end; |
AW: Stack Überlauf fehler
Ah, die Buttons sind in jeder Zeile des Ersatzteil-Grids...
So kann man das auch lösen. So wie Persau das gelöst hat, ist es aber einfacher. Also: Dein Ersatzteil-Grid und dadrunter/drüber/neben ein (1!) Button 'btBestellen'. Im OnDataChange-Ereignis des ErsatzTeil-Datasets dann:
Delphi-Quellcode:
Fertig.
Procedure TMyForm.ErsartTeilSourceDataChange(Sender: TObject; Field: TField);
Begin if Field=nil then btBestellen.Enabled := Not Ersatzteil_DatasetBestellt.AsBoolean; End; Wenn Field=nil, dann wird die Zeile gewechselt. Der Button verändert seinen Status also genau dann, wenn eine neue Zeile im Grid ausgewählt wird und ist ausgegraut, wenn man das Teil nicht bestellen kann (weil schon bestellt) und normal, also drückbar, wenn nicht. Die Tatsache, das ein Ersatzteil schon bestellt ist, visualisierst Du entweder, indem Du die Spalte 'Bestellt' als Checkbox anzeigst, oder aber, indem Du die ganze Zeile einfärbst (z.B. grün=bestellt). Das spart Platz, denn die Information 'bestellt' erkennt man nun direkt an der Farbe. |
AW: Stack Überlauf fehler
Wollte die Tatsache das das Ersatzteil bestellt ist eigentlich dadurch visualisieren das der Button verschwindet. Sprich man bestellt und der Button geht weg. An sich funktioniert das mit der while auch ganz gut. Hab halt nun das Problem, dass ich durch die Schleife immer an den letzten Datensatz springe. Das wiederum ist schön und gut wenn ich aus dem Grid rausbleibe und die Datasource quasi nicht veränder. TU ich dies jedoch zeigt das Grid mir nur noch unvollständige Ergebnisse an. Das liegt daran, dass ich den Datenbank Zeiger ja verschiebe und damit dann das OnDataChange auslöse. Jetzt stell ich mir die Frage ob es hilft, wenn ich in meiner bestellbtncreate procedure den aktuellen Zeiger Speicher und nachher zurück setze? Könnt ihr mir das sagen bzw. Wie Kriege ich den überhaupt gespeichert?
@ Furtbichler: überprüft deine procedur immer den aktuell geänderten Datensatz oder wie geht das |
AW: Stack Überlauf fehler
Ich habe es zwar nicht ganz verstanden, aber den aktuellen Datensatzzeiger kannst Du Dir mit
![]() ![]() |
AW: Stack Überlauf fehler
Zitat:
Die Klimmzüge auf dem Client mögen zwar schön sein, sind meiner Meinung nach nicht zuverlässig und unnötig kompliziert. Gruß K-H |
AW: Stack Überlauf fehler
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:06 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 by Thomas Breitkreuz