![]() |
Datenbank: IB/FB • Zugriff über: hierfür egal
Dataset als Parameter mit OOP oder wie ?
Hi,
ich habe hier verschiedene Forms die dienen zum Ausgeben von Listen. Die gleichen sich schon ziemlich, aber sind nicht identisch. Insbesondere die auzugebenden Daten sind natürlich unterschiedlich. Hierzu habe ich mir eine Klasse gebaut, die ganz grob so aussieht : Zitat:
Das wird schon überall gebraucht, ist aber immer eine andere Tabelle. 8) Ich habe nun in der Ursprungsform folgendes stehen :
Delphi-Quellcode:
Ich wollte DS erst später konkret besetzen. So scheint es aber nicht zu gehen. Wo muß das DS hin um es später je nach Lage zu nutzen ? So wie es hier steht gibt es nur AVs.
ErmittleDaten (DS); // DS ist als VAR Parameter deklariert.
while not DS.Eof do begin ZeigePositionen; DS.Next; end; |
Re: Dataset als Parameter mit OOP oder wie ?
Hallo Hansa,
wie hast du denn ErmittleDaten deklariert?
Delphi-Quellcode:
Ist es als Methode zu deiner Klasse oder als globale Prozedur deklariert? Wie sieht der Body der Methode aus?
procedure ErmittleDaten(DS: TDataSet);
|
Re: Dataset als Parameter mit OOP oder wie ?
Delphi-Quellcode:
Bei mir ist vieles in protected untergebracht :mrgreen: und auch das :
procedure ErmittleDaten(var DS: TDataSet);
Delphi-Quellcode:
Ist natürlich ein FIBdataset, aber das ist egal.
protected
DS : TDataset; Eben weil ich es später noch brauche. Momentan ist der Stand eben so, daß ich die ganze Prozedur auch leer lassen könnte und schreibe in einem Nachfahren das Dataset im Klartext da rein. Das will ich aber nach Möglichkeit umgehen, denn ich brauche nur einen Platzhalter, der nach Bedarf besetzt wird und dann könnte ich die "ErmittleDaten" Prozedur allgemein halten und nur das jeweilige Dataset verwenden. |
Re: Dataset als Parameter mit OOP oder wie ?
Warum sollte das protected sein? :gruebel:
Du hast sicher eine abstrakte Basisklasse... Die bekommt ein privates Feld fDataSet vom Typ TDataSet. Dazu eine öffentliche oder protected readonly Property DataSet. Der Constructor der Basisklasse schuckt ein const aDataSet :TDataSet und besetzt damit fDataSet. Warum sollten die Nachfahren auch diekten Zugriff darauf haben? :gruebel: |
Re: Dataset als Parameter mit OOP oder wie ?
Zitat:
Delphi-Quellcode:
type
TVorfahre = class private FDataset: TDataSet; protected procedure ErmittleDaten; virtual; abstract; procedure ZeigeKopf; virtual; abstract; procedure ZeigePositionen; virtual; abstract; procedure ZeigeFuss; virtual; abstract; property Dataset: TDataSet read FDataset write FDataset; end;
Delphi-Quellcode:
type
TNachkomme = class(TVorfahre) ... public ... property Dataset; end; |
Re: Dataset als Parameter mit OOP oder wie ?
So, Thx, das geht jetzt so weit. Property war tatsächlich das, was ich vermißt hatte. Es wird schon mal compiliert. :mrgreen: Allerdings kommt noch AV beim ersten Zugriff auf "Dataset".
Das muß doch wohl noch irgendwo her kommen bzw. erzeugt werden. Wenn das noch jemand wüßte, wäre echt nett. Für jetzt reichts mir erst mal. 8) |
Re: Dataset als Parameter mit OOP oder wie ?
Hi,
das DataSet über eine Property zu setzen ist nicht wirklich gut. Wenn dann sollte das über den Konstruktor laufen: constructor create(DS:TFIBDataSet); Grüße Lemmy |
Re: Dataset als Parameter mit OOP oder wie ?
Was ? Nicht wirklich gut ? :shock: Dann muß ich anders fragen : was ist besser ? :lol: Ich habe das ja auch nur mit property gemacht, weil Sprint und Robert_G gesagt haben, so sollte ich es machen. :mrgreen:
Soweit scheint das ganze ja auch zu gehen, bis auf die Zugriffsverletzung, weil das Ding wohl nicht initialisiert ist. Ich muß doch bestimmt zumindest den Tabellennamen mit angeben. Was überhaupt alles ? Eigentlich hatte ich vor dem property-Dataset ein konkretes aus meinem Datenmodul zuzuweisen. Also so :
Delphi-Quellcode:
Hierbei kommt dann Zugriffsverletzung :
Dataset := KundeDS; // Dataset : property KundeDS : aus Datemodul
Delphi-Quellcode:
Das ist der erste Zugriff auf "Dataset" überhaupt.
Dataset.close;
|
Re: Dataset als Parameter mit OOP oder wie ?
Wie? Was? Wo?
Hast du dir überhaupt meinen Post durchgelesen? :roll: |
Re: Dataset als Parameter mit OOP oder wie ?
Ich bräuchte ein Beispiel für den Constructor. Momentaner Stand ist, daß ich das von Sprint so umgesetzt habe. Also habe ich statt meines konkreten Datasets eben "Dataset" da stehen, kann aber nicht drauf zugreifen. Mit ein paar Wörtern alleine komme ich so nicht weiter. Wo muß der Konstruktor genau hin ? Wie sieht er konkret aus ?
Bzw. um es nochmals zu sagen : wie teile ich meinem Programm mit, daß es sich an einer Stelle bei Dataset um den Lagerbestand handelt und woanders z.B. um eine Adresse ? |
Re: Dataset als Parameter mit OOP oder wie ?
Hi Hansa,
muss mich entschuldigen! Ich übergebe dem Konstruktor kein DataSet, sondern die Datenbankverbindung mittels der IBDatabase oder der IBTransaction: also hier mal ein Beispiel (mit IBX, was aber nichts zur Sache tut):
Delphi-Quellcode:
und hier die abgeleitete Klasse:
type TDBObject=class(TObject)
private protected iID:Int64; IBDataSet:TIBDataSet; sSQL, sSaveSQL:String; bSave, bExpicitTransaction:Boolean; Transaction:TIBTransaction; procedure SetSQLStatement; virtual; procedure SaveValues; virtual; procedure SelectValues; virtual; abstract; procedure SetValues; virtual; public constructor create(DefaultDataBase:TIBDataBase); overload; constructor create(DefaultTransaction:TIBTransaction); overload; procedure Free; virtual; procedure Save; property SaveDB:Boolean read bSave write bSave; property ID:Int64 read iID; end;
Delphi-Quellcode:
Im Konstruktor der Klasse TDBObject wird je nach aufgerufenen Konstruktor eine IBDataSet oder eine IBTransaction + IBDataSet erzeugt und natürlich beim Destruktor wieder freigegeben. Ich habe so einige Klassen erzeugt, teilweise auch mit Enkeln (wie nennt man das, wenn man eine Klasse ableitet und von dieser wieder ableitet?).
type TAdresse=class(TDBObject)
private sName, sStrasse, sOrt, sTelefon, sFax, sAnrede, sTitel, sAnschrift:String; protected procedure SelectValues; override; public constructor create(DefaultDataBase:TIBDataBase; AdresseID:Int64); property Name:String read sName write sName; property Strasse:String read sStrasse write sStrasse; property Ort:String read sOrt write sOrt; property Telefon:String read sTelefon write sTelefon; property Fax:String read sFax write sFax; property Anrede:String read sAnrede write sAnrede; property Titel:String read sTitel write sTitel; property Anschrift:String read sAnschrift; end; Die Übergabe der IBDataSet bzw. Transaction mache ich deshalb, um zum einen bei der IBDataset innerhalb der Klasse die Transaktionssteuerung zu machen, oder wenn ich die Transaction-Instanz übergebe wird die Transaktionssteuerung außerhalb der Klasse vorgenommen (wenn das Objekt der Klasse z.B. von einem anderen Objekt (z.B: Auftrag) aufgerufen wird). Grüße Lemmy |
Re: Dataset als Parameter mit OOP oder wie ?
Lemmy, das ist ja schon gut, aber ich kann doch nicht auf niedriger Objekt-Ebene schon solch komplizierte Gebilde einbauen. Ich will doch nur ein Dataset haben, welches ich nach Bedarf durch ein geeignetes und auch schon definiertes ersetze. Sogar die Feldnamen sind fast identisch, aber nicht alle.
|
Re: Dataset als Parameter mit OOP oder wie ?
Zitat:
|
Re: Dataset als Parameter mit OOP oder wie ?
Guten Morgen,
was heißt hier niedrige Objektebene? Wieviele Nachfahren von TDBObject willst Du denn erzeugen? Die Klasse TAdresse ist mein Ziel, dort steckt alles drin, was ich in dieser Anwendung benötige. Neben TAdresse gibts noch ein paar andere. Lediglich bei einer Klasse habe ich mich zu ner weiteren Vererbung entschlossen, da ich diese universell einsezten muss:
Delphi-Quellcode:
type THoaiAnsatz=Class(TDBObject)
protected sHoaiAnsatzNr, sAuftragNr, sBeschreibung, sBearbeiter, sStrasse, sOrt, sTeilort, sSonstiges, sPLZ:String; cSchaetzung, cBerechnung, cAnschlag, cFeststellung:Currency; cSchaetzungHonorar, cAnschlagHonorar, cFeststellungHonorar, cBerechnungHonorar:Currency; cMwst, cBesondereLeistungen, cLeistungsbild, cNebenkosten, cAbschlag:Currency; cNebenPauschale, cBLWiederholungen:Currency; iHoaiZone, iHoaiZuschlag:SmallInt; iHoaiTeilID:SmallInt; dtDatum:TDate; iAuftraggeberID, iHoaiVorlageID, iAuftragID:Int64; adrAuftraggeber:TAdresse; sHoaiVorlage:String; AnrechenbareKost:THoaiAnrechenbareKosten; IBDatabase:TIBDatabase; cGrundhonorar:Currency; iObjektID:Int64; sBegruendung:TStringList; procedure SelectValues; override; procedure SetValues; override; function GetNebenkostenHonorar:Currency; virtual; procedure SetSQLStatement; public constructor create(DefaultTransaction: TIBTransaction; HOAIAnsatzID:Int64); procedure free; override; procedure saveValues; override; property AnsatzNummer:String read sHoaiAnsatzNr; property AuftragNummer:string read sAuftragNr; property Beschreibung:String read sBeschreibung; .... und deren Ableitungen:
Delphi-Quellcode:
type THoai2Ansatz=Class(THoaiAnsatz)
protected IBDataSetDetail:TIBDataSet; cVorplanungen, cEntwurfsplanungen:Currency; iWiederholungen:Integer; iVorplanung, iEntwurfsplanung:Integer; cUmbauzuschlag:Currency; cWiederholungenHonorar,cWiederholungenLB, cVorhandeneBausubstanz:Currency; sSQLDetail, sSaveSQLDetail:String; procedure SelectValues; override; procedure SaveValues; override; procedure SetValues; override; function GetNebenkostenHonorar:Currency; override; procedure SetSQLStatement; public constructor create(DefaultTransaction: TIBTransaction; HOAIAnsatzID:Int64); procedure free; override; ... Von den Ableitungen gibts derzeit 2, im Endausbau werden es wohl um die 12 werden. Ein "allgemeingültiges" Objekt wirst Du nie erzeugen können, wenn Du durch das Objekt (z.B. Adresse:TAdresse) die Eigenschaften auslesen willst (Adresse.Name) Da kannst Du nicht einmal ne Adresse auslesen und ein anderes mal den Lagerbestand! Dazu brauchst Du spezielle Klassen, die sich der Gegebenheit der Tabelle anpassen. Holger Klemt geht in seinem ![]() Grüße Lemmy |
Re: Dataset als Parameter mit OOP oder wie ?
Ich glaube keiner versteht mich. :cry: Sprint vielleicht, aber das andere ist wohl viel komplizierter als überhaupt gebraucht. Also gut, ich bringe ein ausführlicheres Beispiel :
2 Ausgabe-Grids. Eines für Lager, das andere für Preise. In beiden Fällen brauche ich zuerst mal die Artikel und da fängts an. Die sind etwas kompliziert. Sie können 1-3 Zeilen für die Bezeichnung haben. Sie werden je nach Eigenschaften farblich gekennzeichnet usw. Jetzt habe ich das alles in einer separaten Unit. Die Anzeige sieht dann so aus :
Delphi-Quellcode:
ZeigePosition zeigt die Artikel mit allem drum und dran an. ZeigeDetailposition dient zum Anzeigen entweder des Lagerbestandes oder des Preises.
ZeigePosition;
ZeigeDetailposition; ZeigeDetailPosition bleibt erst mal leer, weil erst später feststeht was jetzt angezeigt wird (also Lager oder Preis). Nun habe ich in den abgeleiten Klassen 2 Datasets PreisDS und LagerDS. Mit 2 verschiedenen Joins einmal über Lager und einmal über Preise. Die Ursprungsklasse kann davon aber noch nichts wissen. Meine Überlegung war, die Logik so in der Ursprungsklasse beizubehalten, aber eben mit einem leeren Dataset, daß erst später konkret besetzt wird. Mit der Property ging das wohl schon so, bis auf die Tatsache, daß kein Zugriff darauf möglich ist. Es sieht also so aus, daß die Feldnamen bzw. die Daten für die Artikel in beiden Fällen gleich sind (das ganze läuft über einen Join (ARTIKEL JOIN LAGER bzw. ARTIKEL JOIN PREIS) und ich eben im Vorfeld alles was mit den Artikeln zu tun hat erledigen will. Würde das gelingen, so müßte ich nur noch in ZeigeDetaildaten die entsprechende Lagerdaten/Preise anzeigen. ZeigePositionen ist nun gedacht zur Anzeige der immer gleichen Artkeldaten und das kann ich nicht nutzen, weil zum Schluß diese Daten in den Datasets LagerDS bzw. PreisDS drin stecken. Davon weiß eben die Grundklasse noch nichts. 8) |
Re: Dataset als Parameter mit OOP oder wie ?
Tja, so ist Delphi. Phänomenal ! :shock: Es ist schon sehr erstaunlich, was da alles möglich ist, sofern man sich nur tief genug in die Problematik eingräbt, sucht und auch mal experimentiert. Um es vorwegzunehmen : vergesst die properties und den ganzen Rest.
Das geht so einfach, daß ich mich nicht traue zu sagen wie. Das ganze ist reproduzierbar und getestet anhand zweier Tabellen. Leider weiß ich noch nicht genau, worauf es letztendlich ankommt, aber im Großen und Ganzen ist es ziemlich klar. Die grundlegende Programm- und Datenbankarchitektur spielt allerdings eine gewaltige Rolle. Ich schätze mal, daß sich der Aufwand, ein komplexes Ausgabe-Formular zu entwerfen (wie im konkreten Fall) auf 10 % der veranschlagten Zeit reduzieren läßt. Ich kann also im Laufe eines einzigen Tages 20 in Frage kommende Formulare so gestalten, daß alles paßt. Vom Wartungsaufwand dafür ganz zu schweigen. 8) |
Re: Dataset als Parameter mit OOP oder wie ?
Hättest du hier eine richtige Frage gestellt, dann hättest du auch eine passende Antwort bekommen.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:04 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 by Thomas Breitkreuz