Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Datenmodul (https://www.delphipraxis.net/178191-datenmodul.html)

Walter Landwehr 22. Dez 2013 11:32

Datenbank: Firebird • Version: 2.5.002 • Zugriff über: IBO

Datenmodul
 
Hallo,

Ich habe ein Formular 'Patientfrm'
Hierzu ein Datenmodul 'dmPatient'

In der Uses Klauses sind die Patientfrm mit der dmPatient verbunden.

Im dem Formular Patientfrm will ich im OnCreate Ereignis eine Query öffnen die auf dem Datenmodul liegt.

Delphi-Quellcode:
dmPatient.Patient1Qry.Open;
Leider kommt nun eine Schutzverletzung. Irgendwie habe ich keinen Zugriff auf das Datenmodul. Hat jemand eine Idee warum nicht.

Vielen Dank schon mal im Voraus für einen Tipp.

Furtbichler 22. Dez 2013 11:37

AW: Datenmodul
 
Vermutlich ist dmPatient noch nicht instantiiert. Beachte die Erstellungreihenfolge der Formulare in den Projekteigenschaften. Vermutlich wird das Formular zuerst erzeugt.

Richige Vorgehensweise: Erzeuge das Datenmodul im Formular (FormCreate) explizit selbst (und gib es im FormDestroy wieder frei). Nimm dazu die implizite Erzeugung aus den Projekteigenschaften bzw. dem Projektquelltext heraus.

Walter Landwehr 22. Dez 2013 11:42

AW: Datenmodul
 
Hallo,

habe es schon gelöst. Hatte diese Zeile vergessen.
Delphi-Quellcode:
dmPatient:=TdmPatient.create(PatientFrm);
Danke.

Walter Landwehr 22. Dez 2013 12:06

AW: Datenmodul
 
Hallo,

ist doch noch ein :( Problem vorhanden.

Das Datenmodul meint das das Formular PatientFrm Nil ist warum?

Danke für einen Tipp.

Furtbichler 22. Dez 2013 12:12

AW: Datenmodul
 
Im FormCreate könnte das noch nicht zugewiesen sein.
Solche Kreuzreferenzen sind schlecht. Ganz schlecht. Sie mal zu, ob Du das anders hinbekommst... Kannst das ja hier mal skizzieren,falls Du nicht weiterkommst.

Perlsau 22. Dez 2013 13:15

AW: Datenmodul
 
Zitat:

Zitat von Walter Landwehr (Beitrag 1240754)
Das Datenmodul meint das das Formular PatientFrm Nil ist warum?

Wozu benötigst du im Datenmodul eine Referenz auf deine Form-Unit? Ich gestehe, ich habe das früher, als ich's noch nicht besser wußte, auch so gemacht, um z.B. die Statusbar in der Hauptform (UnitMain) aktualisieren zu können, wenn sich der Datensatzzeiger eines Queries ändert. Dazu hatte ich die UnitMain in die Uses-Klausel des Datenmoduls aufgenommen, und zwar im Implementationsabschnitt. Das hat dann zwar funktioniert, ist aber ganz schlechter Stil. Heute mache ich das so:

1. Das Datenmodul erhält im Interface-Abschnitt eine neue Typ-Deklaration.
2. Unter PRIVATE wir eine Variable dieses neuen Typs deklariert.
3. Unter PUBLIC wird ein neues Property deklariert.
4. In der Ereignisbehandlung AfterScroll wird nun das Ereignis ausgelöst.
5. In der MainForm wird nun in OnActivate festgelegt, was beim ausgelösten Ereignis zu geschehen hat.

Delphi-Quellcode:
UNIT UnitData;

INTERFACE

USES
  SysUtils, Classes, DB, DBAccess, IBC, MemDS, Dialogs;

// 1. neue Typ-Deklaration
TYPE TUpdateStatusbarEvent = Procedure of Object;

TYPE
  TDatMod = CLASS(TDataModule)
    ConMain : TIBCConnection;
    ...

    Procedure Qset_ArbeitgeberAfterScroll(DataSet: TDataSet);

  PRIVATE { Private-Deklarationen }
    Var
// 2. Variable des neuen Typs
      fUpdateStatusbar : TUpdateStatusbarEvent;

  PUBLIC { Public-Deklarationen }
    Function Verbinden_Datenbank : Boolean;
    ...

// 3. neues Property
    Property OnUpdateStatusbar : TUpdateStatusbarEvent Read fUpdateStatusbar Write fUpdateStatusbar;
  END;

Var
  DatMod: TDatMod;

IMPLEMENTATION

...

Procedure TDatMod.Qset_ArbeitgeberAfterScroll(DataSet: TDataSet);
begin
  BTab.Firma_ID := Qset_Arbeitgeber.FieldByName('ID_ARBEITGEBER').AsInteger;
// 4. Ereignis auslösen
  IF Assigned(fUpdateStatusbar) THEN fUpdateStatusbar;
end;

...

// 5. In der MainForm wird nun in OnActivate festgelegt, was beim ausgelösten Ereignis zu geschehen hat
Procedure TFormMain.FormActivate(Sender: TObject);
begin
  ...

  // Die private Methode StatusBarAktualisieren wird aufgerufen, wenn das Ereignis eintritt
  DatMod.OnUpdateStatusbar := StatusBarAktualisieren;

  ...
end;

Furtbichler 22. Dez 2013 14:11

AW: Datenmodul
 
Bei Events übergibt man -per Konvention- noch den Sender, also den Auslöser des Events. Daran kann der Empfänger des Events ermitteln, von wem das Ereignis kommt. In deinem Fall ist das überflüssig, weil es sowieso das Datenmodul ist, aber wenn Du mehrere Datenmodule hättest, könntest Du anhand des Absenders noch zusätzliche Informationen anzeigen.

Deine Lösung ist ansonsten vollkommen korrekt.

Also (nicht besser, aber eben Standard)

Delphi-Quellcode:
// 1. neue Typ-Deklaration
TYPE TUpdateStatusbarEvent = Procedure (Sender : TObject) of Object; // Existiert schon als 'TNotifyEvent'
...
Procedure TDatMod.Qset_ArbeitgeberAfterScroll(DataSet: TDataSet);
begin
   BTab.Firma_ID := Qset_Arbeitgeber.FieldByName('ID_ARBEITGEBER').AsInteger;
// 4. Ereignis auslösen
   IF Assigned(fUpdateStatusbar) THEN fUpdateStatusbar (Self);
end;

Perlsau 22. Dez 2013 14:15

AW: Datenmodul
 
@Furtbichler

Prima, hab ich mir sofort notiert :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:18 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz