Announcement

Collapse
No announcement yet.

Instanziiren von Datenmodulen in Delphi 5

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Instanziiren von Datenmodulen in Delphi 5

    Hallo, ich hab da folgendes Problem.
    Wenn ich in einer MDI Anwendung versiche ein Datenmodul beim erstellen eines neuen Formulars zu instanziieren, erhalte ich keine wirklich neue Instanz des Datenmoduls.

    Ich hab da folgendes in der FormCreate:

    var Data : TDatamodule1;

    begin
    Data := TDatabodule1.Create(self);
    Data.Datasource.... := .....

    ...
    end;

    Das läuft auch so weit. Die Fkt. setzt unter anderem auch einen Filter fuer das Datenmodul.
    Geht auch in der ersten Instanz des Fenster.
    Bei der zweiten Instanz des Fensters laeft es auch durch, aber beide Fenster greifen dann auch die gleiche Instanz des Datenmoduls zu.
    Änderungen im ersten Fenster erscheinen auch im zweiten und im zweiten Fenster wird der Filter nicht gesetzt.

    Wo ist denn da mein Fehler . Can anybody help?

    Gruss Lukas

  • #2
    Hallo,

    damit jedes MDI-Fenster seine eigene Datenmodul-Instanz verwendet, darf man <b>keine</b> globale Variable verwenden, sondern ein <b>Objektfeld</b> für die Datenmodulinstanz. Im folgenden Beispiel wird DMChild als privates Objektfeld von TMDIChild deklariert, somit verwendet jede Instanz des MDI-Fensters auch wirklich einen eigenen Zeiger auf die zuständige Datenmodulinstanz.
    <pre>
    unit Childwin;

    interface

    uses Windows, Classes, Graphics, Forms, Controls, ExtCtrls, DBCtrls,
    StdCtrls, Mask, Data, Db;

    type
    TMDIChild = class(TForm)
    DBEdit1: TDBEdit;
    DBNavigator1: TDBNavigator;
    DBEdit2: TDBEdit;
    DBEdit3: TDBEdit;
    DBImage1: TDBImage;
    DataSource1: TDataSource;
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
    private
    { Private declarations }
    DMChild : TDataModuleMDI ;
    public
    { Public declarations }
    end;

    implementation

    uses Dialogs; // ShowMessage-Hinweise

    {$R *.DFM}

    procedure TMDIChild.FormCreate(Sender: TObject);
    begin
    ShowMessage('TMDIChild.FormCreate');
    DMChild := TDataModuleMDI.Create(nil);
    // alle Aktionen sollen sich auf das neue Datenmodul beziehen
    with DMChild do
    begin
    // Neu: TDatabase-Instanz im Datenmodul aktivieren
    Session1.Active := True;
    Database1.Connected := True;
    Table1.Open;
    // Kontrolle: Tatsächlich neue TSession-Instanz ?
    ShowMessage('TMDIChild.FormCreate: ' + Session1.SessionName);
    // Neu: Datasource-Instanz im MDIChild an das Datenmodul anbinden
    DataSource1.DataSet := Table1;
    end;
    end;

    procedure TMDIChild.FormClose(Sender: TObject; var Action: TCloseAction);
    begin
    ShowMessage('TMDIChild.FormClose');
    DMChild.Table1.Close;
    Action := caFree;
    end;

    procedure TMDIChild.FormDestroy(Sender: TObject);
    begin
    ShowMessage('TMDIChild.FormDestroy');
    if not Assigned(DMChild) then
    Exit;
    // alle Aktionen sollen sich auf die eigenen Datenmodul-Instanz beziehen
    with DMChild do
    begin
    Table1.Active := False; // wird bereits von FormClose erledigt
    Database1.Connected := False ; // zum besseren Verständnis
    Session1.Active := False ; // zum besseren Verständnis
    Free;
    end;
    DMChild := NIL ;
    ShowMessage('TMDIChild.FormDestroy: Datenmodul zerstört');
    end;

    end.
    </pre>
    Ansonsten muss noch folgendes beachtet werden:<br>
    - Session1.Active = False <br>
    - Session1.AutoSessionName = True<br>
    - Session1.PrivateDir = leer<br>
    - Table1.DatabaseName = DB (Name der TDatabase-Instanz im Datenmodul)<br>
    - TMDIChild: globale Variable wird als Objektfeld von TMDIChild deklariert<br>
    - TMDIChild.FormCreate: TSession/TDatabase-Instanz im Datenmodul aktivieren<br>

    Damit verwendet jedes MDI-Childfenster eine eigene Datenmodul-Instanz
    mit einer eigenen TSession/TDatabase-Kombination. Letzteres ist zwar nicht ungebedingt notwendig, verbessert jedoch zum einen die Übersichtlichkeit und ist ausbaufähiger (falls jeder MDIChild seine
    Datenbankaktionen später in einem getrennten Thread ausführen soll).

    Die TDataSource-Instanz würde ich vom Datenmodul ins MDIChild-Formular verlegen, damit muss zur Laufzeit nur ein (!) Wert (DataSource1.DataSet := Table1 zugewiesen werden.

    Ergebnis: Jeder Client verwendet eine eigene Datenbankverbindung und kann somit getrennt durch den Datenbestand browsen.

    P.S: Das vollständige Beispielprojekt findet sich in meinem Buch <i>Client/Server Datenbankentwicklung mit Delphi</i>

    Comment

    Working...
    X