Beim Öffnen meines Delphi-Projekts habe ich einen hartnäckigen Bug:
<PRE>
Fehler beim Lesen von DBCount1.Active: Keine
SQL-Anweisung verfügbar. Fehler ignorieren und
fortfahren? WARNUNG: Ignorieren kann bedeuten, daß
Komponenten gelöscht werden oder Eigenschaftswerte
verlorengehen.
</PRE>
Ich habe eine einfache datensensitive Komponente geschrieben. Die eigentliche Funktionalität läuft im Designer und auch zur Laufzeit einwandfrei. Nur beim Öffnen des Projekts verusucht Delphi offenbar, die Query auf Active=true zu setzen, bevor ich ihr ein SQL-Statement zugewiesen habe, und offenbar an meinen Methoden vorbei. Wie kommt das?
<PRE>
TDBCount = class (TCustomControl)
private
FRequestActive: Boolean;
FQuery: TQuery;
function GetActive: Boolean;
procedure SetActive(Value: Boolean);
procedure UpdateSQL;
protected
procedure Loaded; override;
public
constructor Create(AOwner: TComponent); override;
published
property Active: Boolean read GetActive write SetActive;
property MasterSource: TDataSource read GetMasterSource write SetMasterSource;
property MasterField: string read GetMasterField write SetMasterField;
property CountTableName: TFileName read FCountTableName write SetCountTableName;
property CountField: string read GetCountField write SetCountField;
property Active: Boolean read GetActive write SetActive;
property Caption: TCaption read GetCaption write SetCaption;
property DatabaseName: string read GetDatabaseName write SetDatabaseName;
property SessionName: string read GetSessionName write SetSessionName;
end;
</PRE>
Es gibt noch weitere Methoden, die alle funktionieren und deshalb hier weggelassen wurden. Die ganzen Property-SetMethoden rufen immer UpdateSQL auf, so dass das SQL-Statement von FQuery zu jedem Zeitpunkt entweder gültig oder die Query geschlossen ist. Das tut´s auch.
<PRE>
constructor TDBCount.Create(AOwner: TComponent);
begin
inherited;
FRequestActive := false;
FQuery := TQuery.Create(Self);
...
end;
function TDBCount.GetActive: Boolean;
begin
Result := FQuery.Active;
end;
procedure TDBCount.SetActive(Value: Boolean);
begin
FRequestActive := Value;
if csLoading in ComponentState then Exit;
if Assigned(FQuery) then FQuery.Active := Value;
end;
procedure TDBCount.UpdateSQL;
var s: string; WasActive: Boolean;
begin
if (csLoading in Componentstate) or (not Assigned(FQuery)) then Exit;
WasActive := FQuery.Active;
s := ErzeugeSQLStatement; //funktioniert
FQuery.SQL.Text := s;
if WasActive and (s <> '') then
FQuery.Active := true;
end;
procedure TDBCount.Loaded;
begin
inherited Loaded;
if FRequestActive then Active := true;
end;
</PRE>
Im Objektinspector ist ein Objekt meiner Klasse auf Active=true gesetzt. Delphi speichert dieses Property beim Schließen des Projekts weg und stellt es beim Laden wieder her. Jetzt mein Problem: Wie kommt Delphi dazu? In der *.dfm-Datei steht dazu Folgendes:
<PRE>
object DBCount1: TDBCount
Left = 21
Top = 374
Width = 232
Height = 18
MasterSource = srcPerson
MasterField = 'ID'
CountTableName = 'werk'
CountField = 'AUTOR_ID'
Active = True
Caption = 'Autor'
DatabaseName = 'DB_LPROJEKT'
SessionName = 'sesLProjekt'
end
</PRE>
Vielen Dank für jede Hilfe!
Björn
<PRE>
Fehler beim Lesen von DBCount1.Active: Keine
SQL-Anweisung verfügbar. Fehler ignorieren und
fortfahren? WARNUNG: Ignorieren kann bedeuten, daß
Komponenten gelöscht werden oder Eigenschaftswerte
verlorengehen.
</PRE>
Ich habe eine einfache datensensitive Komponente geschrieben. Die eigentliche Funktionalität läuft im Designer und auch zur Laufzeit einwandfrei. Nur beim Öffnen des Projekts verusucht Delphi offenbar, die Query auf Active=true zu setzen, bevor ich ihr ein SQL-Statement zugewiesen habe, und offenbar an meinen Methoden vorbei. Wie kommt das?
<PRE>
TDBCount = class (TCustomControl)
private
FRequestActive: Boolean;
FQuery: TQuery;
function GetActive: Boolean;
procedure SetActive(Value: Boolean);
procedure UpdateSQL;
protected
procedure Loaded; override;
public
constructor Create(AOwner: TComponent); override;
published
property Active: Boolean read GetActive write SetActive;
property MasterSource: TDataSource read GetMasterSource write SetMasterSource;
property MasterField: string read GetMasterField write SetMasterField;
property CountTableName: TFileName read FCountTableName write SetCountTableName;
property CountField: string read GetCountField write SetCountField;
property Active: Boolean read GetActive write SetActive;
property Caption: TCaption read GetCaption write SetCaption;
property DatabaseName: string read GetDatabaseName write SetDatabaseName;
property SessionName: string read GetSessionName write SetSessionName;
end;
</PRE>
Es gibt noch weitere Methoden, die alle funktionieren und deshalb hier weggelassen wurden. Die ganzen Property-SetMethoden rufen immer UpdateSQL auf, so dass das SQL-Statement von FQuery zu jedem Zeitpunkt entweder gültig oder die Query geschlossen ist. Das tut´s auch.
<PRE>
constructor TDBCount.Create(AOwner: TComponent);
begin
inherited;
FRequestActive := false;
FQuery := TQuery.Create(Self);
...
end;
function TDBCount.GetActive: Boolean;
begin
Result := FQuery.Active;
end;
procedure TDBCount.SetActive(Value: Boolean);
begin
FRequestActive := Value;
if csLoading in ComponentState then Exit;
if Assigned(FQuery) then FQuery.Active := Value;
end;
procedure TDBCount.UpdateSQL;
var s: string; WasActive: Boolean;
begin
if (csLoading in Componentstate) or (not Assigned(FQuery)) then Exit;
WasActive := FQuery.Active;
s := ErzeugeSQLStatement; //funktioniert
FQuery.SQL.Text := s;
if WasActive and (s <> '') then
FQuery.Active := true;
end;
procedure TDBCount.Loaded;
begin
inherited Loaded;
if FRequestActive then Active := true;
end;
</PRE>
Im Objektinspector ist ein Objekt meiner Klasse auf Active=true gesetzt. Delphi speichert dieses Property beim Schließen des Projekts weg und stellt es beim Laden wieder her. Jetzt mein Problem: Wie kommt Delphi dazu? In der *.dfm-Datei steht dazu Folgendes:
<PRE>
object DBCount1: TDBCount
Left = 21
Top = 374
Width = 232
Height = 18
MasterSource = srcPerson
MasterField = 'ID'
CountTableName = 'werk'
CountField = 'AUTOR_ID'
Active = True
Caption = 'Autor'
DatabaseName = 'DB_LPROJEKT'
SessionName = 'sesLProjekt'
end
</PRE>
Vielen Dank für jede Hilfe!
Björn