Newsgroup: it.comp.lang.delphi
Titolo: problemi con Costruttore

da un Form devo passare un Parametro al Componente TSqlConnection 
inserito in un DataModule
se nel datamodule assegno l'evento OnCreate ed assegno manualmente il 
valore sNomeDataBase a SQLConnection, funziona (apre le Query)
 
devo poter fare la stessa cosa con un costruttore, non assegnando a 
DesignTime il paramentro Params.. DataBase.
 
seguendo con F7 noto che
sul costruttore:      constructor Create(AOwner: TComponent; 
sNomeDataBase: string); overload;
passa 2 volte, assegnando il valore solo al secondo passaggio
 
^^^^^^^^
 
versione 1: solleva eccezione (***) al momento dell'assegnazone
 
Self.SQLConnection1.DatabaseName := sNomeDataBase
 
--- form
procedure Tfrm_Base.FormShow(Sender: TObject);
var rDatiAvvio: TDatiAvvio;
begin
   //classe che legge i dati di partenza
   rDatiAvvio := TDatiAvvio.Create;
   rDatiAvvio.LeggeDatiAvvio;
   ...
   FreeAndNil(rDatiAvvio);
 
   //ora devo creare l'istanza del DataModule
   frm_Connetti := Tfrm_ConnessioneFB.Create;
   frm_Connetti := Tfrm_ConnessioneFB.Create(Self, sNomeDb);
   bConnesso := frm_Connetti.ConnettiDataBase(sNomeDb);
end;
 
--- Datamodule
   type
 
   { Tfrm_ConnessioneFB }
 
   Tfrm_ConnessioneFB = class(TDataModule)
     IBConnection1: TIBConnection;
 
   private
     { private declarations }
 
   public
     { public declarations }
     constructor Create; overload;
     constructor Create(AOwner: TComponent; sNomeDataBase: string); 
overload;
     function ConnettiDataBase(sNomeDB: string): boolean;
   end;
 
constructor Tfrm_ConnessioneFB.Create;
begin
   inherited;
end;
 
constructor Tfrm_ConnessioneFB.Create(sNomeDataBase: string);
begin
    inherited Create(sNomeDataBase);
    //(***) solleva eccezione
    Self.SQLConnection1.Params.Values['Database'] := sNomeDataBase;
end;
 
--- versione 2 : cambia la dichiarazione del costruttore
non solleva eccezione, ma non assegna la proprieta'
SQLConnection1.Params.Values['Database'] := sNomeDataBase;
quando apro una Query, solleva giustamente eccezione (perche' DataBase 
non e' stato assegnato)
 
constructor Create(AOwner: TComponent; sNomeDataBase: string); overload;
 
constructor Tfrm_ConnessioneFB.Create;
begin
   inherited;
end;
 
constructor Tfrm_ConnessioneFB.Create(AOwner: TComponent; sNomeDataBase: 
string);
begin
    inherited Create(AOwner);
    Self.SQLConnection1.DatabaseName := sNomeDataBase;
end;

 end;
 
ciao.
 
Scusa ma non credo di aver capito: Intanto hai dimenticato di dirci che eccezione ti esce (o forse e' un  errore in compilazione?)
 
Poi non ho capito che differenza c'e' tra i due casi, mi sembrano scritti male, nel senso che non e' codice compilabile quindi non si capisce se le differenze sono un errore di battitura o cosa... 
 
In linea di massima lo schema che stai seguendo e' corretto:
 
dichiari il datamodule:
 
TMyDatamodule = class(TDatamodule)
...
constructor Create( owner: TComponent; DBName : string ); overload;
...
 
constructor TMyDatamodule.Create( owner: TComponent; DBName : string ); 
begin
  inherited Create(owner);
  sqlconnection.databasename := dbname;
end;
 
e poi nella form lo istanzi usando il costruttore alternativo
 
dm := TMyDataModule.Create( self, databasename );
 
Non riesco a capire dalla tua spiegazione in che punto non fa quello che ti aspetti e/o ti da errore...
 
ciao
Giacomo
 
 
 
 

1) hai letto BENE cosa dice l'help in linea sull'evento OnShow?
 
2) visto che la lettura dei dati per la connessione al db non ha nulla a che vedere con l'interfaccia utente, xche non spostare la lettura dei parametri dal form (interfaccia) al datamodule (logica)?
 
3) se fai quello che e' scritto al punto 3, non ti serve un costruttore ma puoi usare l'evento OnCreate, ben spiegato nella guida in linea.
A differenza di OnShow, OnCreate viene chiamato SOLO UNA VOLTA.
 
Un commento dovrebbe spiegare  PERCHE' si fa una cosa e non IL COME si fa.
Il COME lo si capisce dal codice.
Poi, io che sono paranoico, scriverei cosi:
 
 
var 
  DbParams: TDatiAvvio;
  Allow: boolean;
 
begin
 
  DbParams := TDatiAvvio.Create;
  try
    try
      DbParams.LeggeDatiAvvio;
      Allow := True;  
 
    except
      on E:Exception do
      begin
        Allow := False; 
        Log(E.ClassName + ' ' +E.Messgae + ' loading startup data');
      end; 
    end;
 
  finally
    FreeAndNil(DbParams);
  end;
 
  if (Not Allow) then
  begin
    ShowMessage('La lettura dei parametri e' fallita. Vedere il log');
    exit|abort|qui|lieve mano...
  end;
 
...
 
A.

>
grazie degli spunti, mi ero incasinato.
ciao.
 
ho seguito le tue indicazioni, ed ora passa regolarmente, 1 sola volta;
evidentemente era il doppio costruttore create a creare confusione.
 
altra cosa, il datamodule lo creo come Self, quindi secondo logica si 
distruggera' con il Padre; mi conviene creare anche un Distruttore da 
chiamare alla chiusura del form Padre ?
 
-----------
 
nel datamodule
   public
     { Public declarations }
     constructor create(owner: TComponent; DbName: string); overload;
 
constructor Tfrm_ConnettiFb.create(owner: TComponent; DbName: string);
begin
   inherited Create(owner);
   SQLConnection.Params.Values['Database'] := DbName;
end;
 
nel form
procedure Tfrm_Avvio.FormShow(Sender: TObject);
var sEnte, DbName: string;
begin
   //importa identificatore
   DBName := Identifica;
 
   frm_ConnettiFb := Tfrm_ConnettiFb.Create(Self, DBName);
 

>
[...]
tu che sei paranoico, hai perfettamente ragione, sono andato a leggere, 
non mi serve un costruttore.
ciao.
 
OnCreate: ms-help://embarcadero.rs_xe2/vcl/Forms.TForm.OnCreate.html
Use OnCreate to perform special processing when the form is created and 
is invoked by TCustomForm's constructor. Either implement this event or 
override the constructor of the form; do not do both. Any objects 
created in the OnCreate event should be freed by the OnDestroy event.
 
OnShow : ms-help://embarcadero.rs_xe2/vcl/Forms.TForm.OnShow.html
Occurs when the form is shown (that is, when its Visible property is set 
to true).
 
Use OnShow to perform special processing when the form is shown (that 
is, when the form's Visible property is set to true).