![]() |
AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"
Zitat:
![]() Zitat:
Zitat:
Zitat:
|
AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"
Zitat:
Zitat:
Zitat:
Aber: wenn ich ChachedUpdates deaktiviere, kann ich gar nicht mehr (einfach) sehen, wenn es (noch nicht per "Commit" bestätigte) Änderungen in den Queries ggü. der Datenbank gibt - und schon gar nicht, was genau geändert ist (das versuche ich nämlich auch noch optisch darzustellen - über TField-Vergleiche). Um das ohne CachedUpdates hinzubekommen, müsste ich mir dann den ursprünglichen Dateninhalt merken (eigene ReadOnly-DataSet?) und mit den aktuellen Daten vergleichen... Das ist irgendwie auch keine Lösung :( Ich versuche jetzt mal, das durch Eure Kommentare gelernte (oder herausgefundene) umzusetzen und schaue mal, ob ich eine vernünftige Erkennung von Änderungen hinbekomme... ...weitere Anmerkungen / "Stupser" :wink: sind gern gesehen! |
AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"
Zitat:
Um auf Feldebene zu sehen, was sich geändert hat, musst du meines Wissens immer mit der DB vergleichen. Eine Liste der betroffenen Datensätze muss in jedem Fall selbst mitführen. Ich wüsste zumindest nicht, wie man an eine Liste auf Basis von UpdatesPending kommen soll. Allerdings hatte ich auch noch nie den Bedarf. Vielleicht wäre es sinnvoll, die Daten in einem ClientDataSet zu verwalten, statt direkt mit der DB zu kommunizieren. Du willst die Daten ja sowieso erst nach Bestätigung durch den Anwender an die DB schicken. Da bietet sich so eine Zwischenschicht schon an. |
AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"
Zitat:
- bei der Erzeugung der Maske suche ich alle Controls auf der Maske heraus, die einen Datenbank-Bezug haben (bei denen es entweder ein Property "DataSource" oder "DataSet" gibt oder ein Property "DataField" oder "Field", die ihrerseits ein Property "DataSource" oder "DataSet" haben); die merke ich mir samt den dazugehörigen "TFields" in einer speziellen Liste - wenn ein "DataSource" auf der Maske den Status auf "dsEdit" setzt, durchsuche ich die Liste nach geänderten "TFields" (bei denen prüfe/vergleiche ich Value, NewValue und ggf. OldValue) - ist ein Feld geändert, suche ich in der o.a. Liste nach Controls, die sich auf die "DataSource" und das Feld beziehen und setze deren Fontfarbe auf "rot" Das funktioniert relativ gut - hat noch ein paar Spezialfälle, die ich gesondert handhabe, aber im großen und ganzen funktioniert das :-D Zitat:
Ich habe in der Richtung auch bereits Experimente in meinem Code gemacht - bin dann dort aber auf andere Probleme gestoßen, die nicht so einfach behebbar waren --> also leider auch keine "einfache" Lösung :stupid: Aktuell habe ich in dem Zusammenhang schon wieder ein komisches Problem: Ich will ja den korrekten Status sowohl eines einzelnen Records als auch des gesamten Queries (bzw. DataSet) bestimmen - dazu gehört auch herauszufinden, ob ein Record gelöscht wurde. Um solche Records überhaupt im DataSet zu haben, verwende ich folgenden Code (Auschnitt):
Delphi-Quellcode:
beim ersten Log-Aufruf kommt folgendes:
function DSRecGetState( const ds_ : TDataSet ) : TUpdateStatus;
var dsBDE : TBDEDataSet; updRecTypes : TUpdateRecordTypes; begin ... Log( ds_ ); // 1. Aufruf dsBDE := nil; if ( ds_ is TBDEDataSet ) then begin dsBDE := TBDEDataSet( ds_ ); end; updRectTypes := []; if ( Assigned(dsBDE) and dsBDE.CachedUpdates ) then begin updRecTypes := dsBDE.UpdateRecordTypes; if ( NOT (rtDeleted in updRecTypes) ) then begin dsBDE.UpdateRecordTypes := dsBDE.UpdateRecordTypes + [ rtDeleted ]; end; Log( ds_ ); // 2. Aufruf end; ... end;
Code:
beim zweiten Log-Aufruf kommt folgendes:
Active=true, RecordCount=1, CanModify=true, Modified=true, UpdateStatus()=Unmodified, State=dsEdit, CachedUpdates=true, UpdatesPending=false
Code:
:shock:
Active=true, RecordCount=1, CanModify=true, Modified=false, UpdateStatus()=Modified, State=dsBrowse, CachedUpdates=true, UpdatesPending=true
Was soll das? Wieso wird durch das Verändern des "UpdateRecordTypes"-Set der Status des einen (!) vorhandenen Records geändert? Er veliert das Modified-Flag und auch der State des gesamten Queries geht von "dsEdit" auf "dsBrowse"!??? Lt. Doku heißt es doch: An application might also use UpdateRecordTypes like a filter to temporarily limit visible records to those added or inserted by the user during the current session. Das habe ich so interpretiert, dass man das problemlos während der Laufzeit ändern kann (am Ende o.a. Funktion stelle ich das auch wieder auf den ursprünglichen Wert zurück)... |
AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"
Zitat:
Ein Blick in die Sourcen macht das klar:
Delphi-Quellcode:
procedure TBDEDataSet.SetUpdateRecordSet(RecordTypes: TUpdateRecordTypes);
begin CheckCachedUpdateMode; CheckBrowseMode; UpdateCursorPos; Check(DbiSetProp(hDbiObj(Handle), curDELAYUPDDISPLAYOPT, Longint(Byte(RecordTypes)))); Resync([]); end;
Delphi-Quellcode:
procedure TDataSet.CheckBrowseMode;
begin CheckActive; DataEvent(deCheckBrowseMode, 0); case State of dsEdit, dsInsert: begin UpdateRecord; if Modified then Post else Cancel; end; dsSetKey: Post; end; end; Zitat:
|
AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"
Zitat:
(OffTopic: eine Methode "CheckXXXX" zu nennen und dann in der Methode die Daten zu verändern, halte ich übrigens für seehr schlechten Programmierstil - und hatte ich ebenfalls beim groben durchsehen der Quellen nicht erwartet) Zitat:
Wäre denn (anhand der o.a. Ergebnisse) für die Status-Abfrage des aktuellen Records folgendes richtiger?
Delphi-Quellcode:
oder einfach ganz ohne TBDEDataSet-Prüfung (da UpdateStatus() in der Basis-Implementierung und ohne CachedUpdates usUnmodified zurückliefert):
Result := usUnmodified;
if ( (ds_ is TBDEDataSet) and TBDEDataSet(ds_).UpdatesPending and (ds_.UpdateStatus() <> usUnmodified) ) then begin Result := ds_.UpdateStatus(); else if ( ds_.Modified ) then begin Result := usModified; end;
Delphi-Quellcode:
Aber für die Abfrage des Status des gesamten Queries müsste dann doch tatsächlich über alle Records gelaufen werden - auf das State-Property kann ich mich da ja nicht verlassen (wenn CachedUpdates gesetzt ist), oder?
Result := usUnmodified;
if ( ds_.UpdateStatus() <> usUnmodified ) then begin Result := ds_.UpdateStatus(); else if ( ds_.Modified ) then begin Result := usModified; end; |
AW: TQuery (BDE) / TDataSet - Verständnisproblem "Modified"
UpdatesPending ist doch für alle Datensätze außer dem aktuellen, falls er gerade editiert wird, ausreichend:
Delphi-Quellcode:
function HasSomethingChanged(ADataSet: TBDEDataSet): Boolean;
begin Result := ADataSet.UpdatesPending; if not Result and (ADataSet.State in [dsEdit, dsInsert]) then begin ADataSet.UpdateRecord; Result := ADataSet.Modified; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:11 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