Delphi-PRAXiS
Seite 2 von 2     12   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Absturz des SQL-Editors in der IDE (D7/ADS10.1) (https://www.delphipraxis.net/191898-absturz-des-sql-editors-der-ide-d7-ads10-1-a.html)

haentschman 18. Mär 2017 15:29

AW: Absturz des SQL-Editors in der IDE (D7/ADS10.1)
 
Hallöle...:P

Deine Gedanken sind richtig. Wie leicht kannst du noch einen Schritt weiter machen...8-)
Zitat:

Würdet Ihr von einer zentralen Stelle mit den SQL-Queries gleich eine Query-Komponente zurückgeben
Ja...zentral. Hier bietet sich eine abstrakte Klasse oder Interface je DBMS an. Die Anwendung kennt kein DBMS. Sie arbeitet auf Dataset Ebene oder mit Listen. (Beispiel: GetDatabaseVersion)
Delphi-Quellcode:
function TDatabase.CreateQuery: TUniQuery;
begin
  Result := TUniQuery.Create(nil);
  Result.Connection := FMeineConnection;
end;
...
procedure TDatabase.GetDatabaseVersion;
var
  Query: TUniQuery;
begin
  Query := CreateQuery;
  try
    Query.SQL.Text := 'SELECT F_VERSION FROM T_VERSION';
    Query.Open;
    FDatabaseVersion := Query.FieldByName('F_VERSION').AsInteger;
  finally
    Query.Free;
  end;
end;
...
procedure TDatabase.FillQuery(Query: TDataSet);
  Query: TUniQuery;
begin
  Query := CreateQuery;
  Query.SQL.Text := 'SELECT F_BlBB FROM T_BLA';
  Query.Open;
end;
Zitat:

oder nur einen SQL-String für eine Komponente?
Du hast keine Komponenten mehr auf der Form. :thumb: Das Statement ist in der Klasse definiert.
Delphi-Quellcode:
Query.SQL.Text := 'SELECT F_VERSION FROM T_VERSION'
Die Funktion gibt das neuerzeugte TDataSet oder die Liste zurück...enweder als Result oder var Parameter.
Eine andere Möglichkeit ist die Statements extern zu verwalten in Ressourcen. Wenn du es wissen willst kann ich nochmal darauf eingehen. :wink:
Zitat:

Nachteil wäre, dass ich (in der IDE) keine persistenten Felder mehr nutzen kann, an die ich z.B. Standard-AufbereitungsRoutinen (in OnGetText) hängen kann.
Die Aufbereitung von Feldern z.B. für ein TDBGrid müsste dann auch im Grid erfolgen.
Ebenso müsste ich auf Lookup-Felder verzichten
Wenn du die datensensitiven Komponenten wegläßt, hast diese Probleme nicht mehr. :stupid: Wenn du dir Datenklassen baust, kannst du auch komplexe Daten an die Nodes oder Zeilen hängen.
Zitat:

Die Aufbereitung von Feldern z.B. für ein TDBGrid müsste dann auch im Grid erfolgen.
Die Berechnerei kannst dann in der Klasse erledigen statt im Visuellen Control. Das macht dich unabhängig...
Zitat:

Wenn man den Parameter-Gedanken weiterspinnt, dann wäre es doch sinnvoll, für jede Abfrage eine eigene Routine zu machen, die ein Query liefert und konkret benannte und typisierte Werte entgegen nimmt. Andernfalls müsste ich immer die Parameter-Namen bzw. -Positionen nachschlagen
Jawoll..ja. 8-)

Wenn man weiterspinnt...
Delphi-Quellcode:
function TDatabase.Save(Blubb: TBlubbClass): Integer;
var
  Qry: TUniQuery;
begin
  Result := -1;
  Qry := CreateQuery;
  try
    case Blubb.State of
      ddsNew:
        begin
          Qry.SQL.Text := GetSQLByName('SER_INSERT_BLUBB'); // aus Ressource
          Qry.ParamByName('UID').AsInteger := Blubb.UserID;
          Qry.ParamByName('GRO').AsString := Blubb.Group;
          Qry.ParamByName('DEF').AsInteger := 0;
          Qry.ExecSQL;
          Blubb.ID := Qry.ParamByName('RET_ID').AsInteger; // neue ID direkt im Objekt ... geht bei Firebird
          Result := Blubb.ID;
        end;
      ddsEdit:
        begin
          Qry.SQL.Text := GetSQLByName('SER_EDIT_BLUBB');
          Qry.ParamByName('GRO').AsString := Blubb.Group;
          Qry.ParamByName('ID').AsInteger := Blubb.ID;
          Qry.ExecSQL;
          Blubb.State := ddsNormal;
          Result := Blubb.ID;
        end;
      ddsDeleted:
        begin
          Qry.SQL.Text := GetSQLByName('SER_DELETE_BLUBB');
          Qry.ParamByName('ID').AsInteger := Blubb.ID;
          Qry.ExecSQL;
          Result := Blubb.ID;
        end;
    end;
  finally
    Qry.Free;
  end;
end;
...das Objekt kennt seinen Status. Dann speichere mal mein Blubb Objekt mit
Delphi-Quellcode:
DatabaseInstanz.Save(Blubb)
...fertsch. :thumb:


Weiter so...:thumb:

p80286 18. Mär 2017 16:06

AW: Absturz des SQL-Editors in der IDE (D7/ADS10.1)
 
Zitat:

Zitat von haentschman (Beitrag 1364652)
Die Anwendung kennt kein DBMS. Sie arbeitet auf Dataset Ebene oder mit Listen.

:thumb:

Spätestens wenn man die Routinen eines "alten" Programms für eine neue Aufgabenstellung verwenden will, weiß man, daß sich etwas Mehrabeit gelohnt hat.

Gruß
K-H

SneakL8 18. Mär 2017 18:31

AW: Absturz des SQL-Editors in der IDE (D7/ADS10.1)
 
Puh, ok ...

Erstmal vielen Dank für Deine ausführliche Antwort. Die muss ich erstmal verarbeiten. Hier ein erster Versuch einer Erwiderung...

1. Zu Deinem ersten Beispiel: die FillQuery-Methode hat Query als Var. und Param. Da ist mir die Funktionsweise nicht ganz klar. Soll der Parameter mit einem Query versorgt werden (falls er bei Übergabe nil ist)? Dann müsste er als var übergeben werden. Wenn er gefüllt ist, müsste man erst einen Close machen, falls er noch aktiv ist:
Code:
if Assigned(Query) then begin
  if Query.Active then
    Query.Close;
end
else
  Query := CreateQuery;
2. Wenn ich komplett auf Komponenten verzichte, dann müsste ich ja "einfache" TLabel, TEdit, ... einfügen und mit DataToForm- bzw. FormToData-Methoden die Felder befüllen (KundenNrLabel.Caption := Query.FieldByName('KUNDENNR').Text). Das wäre jetzt (solange man auf TDataSet als Basis setzt) datenbankunabhängig. Würden diese Zuweisungen dann in meiner Zugriffsklasse in einer entsprechenden Methode passieren, in der auch der Query gebildet wird? Dann wäre QueryString und Zugriff auf Felder/Feldnamen beisammen. Auf externe Ressourcen gehe ich mal noch nicht ein, das überfordert mein Hirn gerade. Eins nach dem anderen :)
Würde man das dann in eine Methode "KundeToForm(const Vorname, Nachname, Strasse, Ort : TControl" packen, der ich diverse Controls übergeben kann (TLabel, TEdit, ...) und die Werte dann zugewiesen werden, wenn ich ein Control übergeben habe (if Vorname is TLabel then ... else if Vorname is TEdit then ...)?

3. TGrid: Würdest Du dann ein CustomGrid machen und die Verbindung zu Query selbst bauen? Oder ein datensensitives TDBGrid nehmen, das dann alle gelieferten Felder anzeigt, wenn ich es zur Laufzeit mit einem TDataSet verbinde? (Dritt-Komponenten mal außen vor)

4. Dein Beispiel mit den Save-/Load-Methoden: die TBlubbclass würde nun meine fachlichen Daten enthalten. Aber in der Save-Methode von TDatabase wird dann doch "Wissen" der Tabelle benötigt, da Du ja die Felder UID und GRO explizit ansprichst. Oder sollten die grundsätzlich immer bei allen Tabellen da sein? Oder Wird TDatabase für jede Tabelle abgeleitet und Load/Save entsprechend auscodiert?

5. An den Aufruf "GetSQLByName" hatte ich auch schon gedacht. Aber dann muss der Aufrufer ja doch wieder wissen, wie die Parameter und die gelesenen Felder heißen von dem, was GetSQLByName liefert. Da finde ich es praktischer, hier gleich den SQL-String stehen zu haben, dann sehe ich beim auscodieren der FieldByName-Aufrufe gleich wie meine Felder heißen. Verstehst Du, was ich meine?

6. Noch ein anderer Gedanke zum "individuellen QueryBuilder": wenn ich z.B. die Daten eines Kunden auf dem Dialog im Kunden-Stamm, auf dem Lieferschein und auf der Rechnung anzeigen will, mache ich dann unterschiedliche Queries zw. Query-Methoden, da ich beim KundenStam mehr Daten lesen will als für den Lieferschein/die Rechnung? Oder versuche ich die anzahl der verschiedenen Queries klein zu halten und baue nur ein Query, der immer alle Felder liest und ich verwende dann nur die, die ich im Kontakt gerade brauche?

Viele Grüße
Sneak-L8

haentschman 19. Mär 2017 06:42

AW: Absturz des SQL-Editors in der IDE (D7/ADS10.1)
 
Moin... 8-)
Zitat:

Zu Deinem ersten Beispiel: die FillQuery-Methode hat Query als Var. und Param. Da ist mir die Funktionsweise nicht ganz klar. Soll der Parameter mit einem Query versorgt werden (falls er bei Übergabe nil ist)? Dann müsste er als var übergeben werden. Wenn er gefüllt ist, müsste man erst einen Close machen, falls er noch aktiv ist:
Der Varianten gibt es verschiedene... Zum Einen eine function die Query als Rückgabewert hat oder die Variante mit der Übergabe der Query als Parameter. Wenn man sich die Variante der function entschieden hat, sollte der Name ausdrücken das innerhalb eine neue Instanz erzeugt wird. (bsp. CreateMeinDataSet). Bei der Parametervariante erfolgt Erzeugung der Instanz in der gleichen Ebene wie die Freigabe.
Delphi-Quellcode:
function TDatabase.CreateMeinDataSet(Parameter: TMeineParameter): TDataSet;
  Query: TUniQuery;
begin
  Query := CreateQuery; // hier wir die Instanz erzeugt
  Query.SQL.Text := 'SELECT F_BLUBB FROM T_BLA';
  Query.Open;
end;
.
procedure TDatabase.FillQuery(Query: TDataSet);
  Query: TUniQuery;
begin
  Query.SQL.Text := 'SELECT F_BLUBB FROM T_BLA';
  Query.Open;
end;
Zitat:

Wenn ich komplett auf Komponenten verzichte, dann müsste ich ja "einfache" TLabel, TEdit, ... einfügen und mit DataToForm- bzw. FormToData-Methoden die Felder befüllen (KundenNrLabel.Caption := Query.FieldByName('KUNDENNR').Text). Das wäre jetzt (solange man auf TDataSet als Basis setzt) datenbankunabhängig.
...JA. :wink: Ich versuche dich von den datensensitiven Komponenten abzuhalten. :wink: Auch wenn es mehr Arbeit erscheint, diese Arbeit wirst du schätzen wissen wenn du die Komponenten gegen schönere austauschst. 8-)
Zitat:

Würde man das dann in eine Methode "KundeToForm(const Vorname, Nachname, Strasse, Ort : TControl" packen, der ich diverse Controls übergeben kann (TLabel, TEdit, ...) und die Werte dann zugewiesen werden, wenn ich ein Control übergeben habe (if Vorname is TLabel then ... else if Vorname is TEdit then ...)?
...NÖ umkekehrt. 8-) Spendiere deiner Form eine Property mit den Daten (TDataset). Wenn du die Form erzeugst/anzeigst gibst du das Dataset mit, welches du zuvor geladen hast und die Daten enthällt. Wenn du die Daten in Objektlisten hast, übergibst der Form das Objekt aus der Liste. Innerhalb der Form kannst du enweder auf das Objekt oder mit DataSet.FieldByName auf die Daten zugreifen und die Controls füllen. Das Speichern funktioniert in umgegehrter Reihenfolge...
Delphi-Quellcode:
TfoBlubb = class(TForm)
  edtName: TEdit;
  edtCaption: TEdit;
strict private
  FBlubbDaSet: TDataSet;
public
  property BlubbDataSet: TBlubbDataSet read FBlubbDaSet write FBlubbDaSet;
end;
...
edtName.Text := FBubbDataSet.FieldByName('NAME').AsString;
...
// Alternativ mit Objekten wenn man eines übergibt
edtName.Text := FBlubb.Name;
...mit Objekten brauchst du die FeldNamen nicht kennen.
Zitat:

TGrid: Würdest Du dann ein CustomGrid machen und die Verbindung zu Query selbst bauen? Oder ein datensensitives TDBGrid nehmen, das dann alle gelieferten Felder anzeigt, wenn ich es zur Laufzeit mit einem TDataSet verbinde? (Dritt-Komponenten mal außen vor)
...sicherlich geht das mit dem DBGrid und DataSource. Damit bindest du du dich an dieses eine Control. Als Beispiel nehme ich immer: Wenn es dir nicht mehr gefällt kannst du es nicht (sinngemäß) einfach austauschen. (Sichwort: Trennung der Oberfläche von den Daten)
Zitat:

An den Aufruf "GetSQLByName" hatte ich auch schon gedacht. Aber dann muss der Aufrufer ja doch wieder wissen, wie die Parameter und die gelesenen Felder heißen von dem, was GetSQLByName liefert.
Das stammt aus meiner Variante mit der Ressource. GetSQLByName gibt anhand des Namens in der Ressource das komplette Statement zurück.
WERBUNG 8-): http://www.delphipraxis.net/190316-d...e-creator.html siehe Tutorial und Anleitung.
Zitat:

Da finde ich es praktischer, hier gleich den SQL-String stehen zu haben, dann sehe ich beim auscodieren der FieldByName-Aufrufe gleich wie meine Felder heißen. Verstehst Du, was ich meine?
...ja. :wink: Da ich nicht mehr mit DataSet in der Anwendung, sondern mit Objekten arbeite, habe ich nur ein Mal nach dem Auslesen die FieldByName Aufrufe.
Zitat:

Aber in der Save-Methode von TDatabase wird dann doch "Wissen" der Tabelle benötigt, da Du ja die Felder UID und GRO explizit ansprichst. Oder sollten die grundsätzlich immer bei allen Tabellen da sein? Oder Wird TDatabase für jede Tabelle abgeleitet und Load/Save entsprechend auscodiert
...ja, auscodiert. Die Klasse enthällt die Methoden für den Zugriff auf die benötigten Tabellen.
Beispiel: stark gekürzt!
Delphi-Quellcode:
IdVA_Database = interface(IdDatabase)

TDatabaseIB = class(TInterfacedObject, IdDatabase) //in der Anwendung existiert nur das Interface für alle gleich.
  strict private
    FConnection: TUniConnection;
    FConnected: Boolean;
    function GetConnected: Boolean;
  public
    constructor Create;
    destructor Destroy; override;

    property Connected: Boolean read GetConnected;
    function Connect: Boolean;
    procedure Disconnect;
    procedure StartTransaction;
    procedure Commit;
    procedure Rollback;

    procedure CreateDatabase;
    function CreateQuery: TUniQuery;
    function CreateStoredProc: TUniStoredProc;
    function GetSQLByName(SQLName: string): string;
    procedure ExecuteScript(SQL: TStrings);
    // Beispiele
    function Save(UserRole: TdUserRole): Integer; overload;
    function Save(User: TdUser): Integer; overload;
   
    procedure SaveList(aList: TAlarmStateList); overload;
    procedure SaveList(aList: TDeviceList); overload;

    procedure Get(User: TdUser; UserName: string); overload;
    procedure Get(Device: TDevice; ID: Integer); overload;

    procedure FillList(aList: TMasterDeviceList); overload;
    procedure FillList(List: TdUserList; UserID: Integer = -1); overload;
  end;
Zitat:

Noch ein anderer Gedanke zum "individuellen QueryBuilder": wenn ich z.B. die Daten eines Kunden auf dem Dialog im Kunden-Stamm, auf dem Lieferschein und auf der Rechnung anzeigen will, mache ich dann unterschiedliche Queries zw. Query-Methoden, da ich beim KundenStam mehr Daten lesen will als für den Lieferschein/die Rechnung? Oder versuche ich die anzahl der verschiedenen Queries klein zu halten und baue nur ein Query, der immer alle Felder liest und ich verwende dann nur die, die ich im Kontakt gerade brauche
...Querys thematisch trennen! :wink: Wenn du z.B. die Lieferantendaten an verschiedenen stellen benötigst, würde es Sinn machen die nicht doppelt anzulegen... :zwinker:

Du bist an dem Punkt wo du entscheiden mußt welche Technik du benutzen willst. Letztendlich muß es zu dir passen...:wink: Lieber über die Entscheidung lange nachdenken und mit Beispielen ausprobieren. :thumb: Wenn du einmal die Anwendung angefangen hast, ist es eher nicht möglich die Methode der Datenbeschaffung zu wechseln.

Aus der Erfahrung heraus:
Ich bin für Objekte in Listen. Da kann man sich die Daten bliebig zusammensetzen...auch aus verschieden Tabellen. Das Laden/Speichern übernimmt das Database "Modul". Dem Objekt ist die Quelle der Daten egal. Der Anwendung ist es wurscht wie Daten in das Objekt gekommen sind...Datenbank, XML, Omas Küchenschrank. :stupid: Wenn du in der Anwendung mit der DataSet Ebene arbeitest hast du quasi mit FieldByName eine Bindung zu einer Datenbank. (auch wenn es Möglichkeiten gibt ein DataSet aus anderen Quellen zu erstellen)
DBGrid alles schön und gut. Du wirst aber an den Punkt kommen das die Query im Grid angezeigt werden kann, aber weil du JOINS benutzt hast, das DataSet nicht gespeichert werden kann. :?
Da fängst du dann an umzubauen weil deine Anforderung gestiegen ist. Dadurch entstehen die berühmten Workarounds...:P

:hi:

SneakL8 3. Apr 2017 20:32

AW: Absturz des SQL-Editors in der IDE (D7/ADS10.1)
 
Hallo zusammen,

und wieder herzlichen Dank an @haentschman für Deine Ausführungen.

Ich habe mich jetzt drangemacht und mal alle neuen TAdsQuerys aus den Formularen rausgeworfen und eine QueryBuilder-Klasse gebaut.

Ich hab mich jetzt mal für ein Interface (IDataSet) entschieden, das nur ein paar Sachen aus TDataSet enthält und sonst neue für mich praktische Funktionen (z.B. ein Refresh, das sich bei einem statischen Cursor den aktuellen Satz merkt, und nach Close/Open zu diesem zurückkehrt, damit man vom Update nichts sieht, solange die Datenbasis unverändert bleibt) einführt.
Auf TDataSource und datensensitive Felder habe ich im ersten Schritt noch nicht verzichtet, um nicht gleich alles bisherige umzuwerfen.

Über die Builder-Technik baue ich mir die Daten auf:
TMyQueryBuilder.GetQueryKunde(self, Kunden).LinkTo(MyDataSource).LockForEdit;

Eigentlich wollte ich dann das zurückgegebe IDataSet auch in einer Variable im Form speichern, damit ich später darauf zugreifen kann. Doch da habe ich die Rechnung ohne IntfClear gemacht und mir nette Speicherzugriffsfehler eingehandelt. Jetzt gebe ich erstmal ein TDataSet zurück. Ganz auch eine Variable im Formular verzichten klappt leider noch nicht, weil ich z.B. noch ein xxx.Post; absetzen will, wenn das Formular zum Ändern von Daten dient und ich (noch) datensensitive Elemente nutze.

Aber mich beschäftigt das Interface trotzdem. Nach Studium von Google (bzw. seinen Suchtreffern) scheint es mir so, dass ich irgendwo noch auf die IDataSet-Variable zugreife, nachdem das TDataSet bereits freigegeben wurde. Ich bin aber der Meinung, dass ich die Variablen rechtzeitig vor dem Release des TDataSets freigebe (Zuweisung von nil), also spätestens im Destroy des Formulars (vor dem inherited). Das scheint aber nicht zu klappen.
Habt Ihr da vielleicht einen Tipp für mich? Oder passt das alles und ich hab nur irgend eine Variable übersehen?

Ansonsten fühlt sich die Sache mit der Trennung der DataSets/Queries und dem Formular gut an. Selbst die Formatierung der Felder (DisplayName, DisplayFormat oder OnGettext/OnSetText) kann ich ja in der GetQuery-Methode nach dem Open mittels FieldByName('xxx').DisplayName := 'xxx' machen. Dadurch ist es nochmal leichter, Formular und Datenkomponente zu trennen. Und ich kann die Aufbereitung a) zentral und b) direkt beim Query-String machen, so ist alles schön bei einander. Wobei ich mir DisplayName auch sparen kann, indem ich im select-Statement gleich ein 'as "xxx"' hinter die zu lesenden Felder packe...

Viele Grüße
Sneak-L8

Rollo62 4. Apr 2017 06:52

AW: Absturz des SQL-Editors in der IDE (D7/ADS10.1)
 
Hallo haentschman,

wenn du Alle Komponenten rausgeworfen hast und nur normale Komponenten mit der DB verknüppelst liegt es Nahe das du das mal mit LiveBindings versucht hast.
Die sind ja eingentlich für die Bindung von DB zu Komponente gemacht, und bei einfachen Label, Edit, etc. sollte das doch auch gut funktionieren.

Arbeitest du auch damit, oder machst du da komplett deinen eigenen Layer drum ?
Ich fände es wünschenswert mal ein schönes BestPractices Beispiel mit LiveBinding in Code zu sehen, in einer
echten Anwendung.
Steven Ball hat da ja eine schöne Serie zu gemacht, aber mir fehlt immer noch der Ansatz wie man das in größeren Projekten anlegen sollte.


Rollo

haentschman 4. Apr 2017 07:16

AW: Absturz des SQL-Editors in der IDE (D7/ADS10.1)
 
Moin...:P
Zitat:

wenn du Alle Komponenten rausgeworfen hast und nur normale Komponenten mit der DB verknüppelst liegt es Nahe das du das mal mit LiveBindings versucht hast.
...und dann wieder begraben. :roll:
Thread: http://www.delphipraxis.net/190711-l...ceadapter.html
Zitat:

Arbeitest du auch damit, oder machst du da komplett deinen eigenen Layer drum ?
Ich arbeite mit Objekten in Objektlisten und Interfaces als "Zwischenschicht" zur Datenbank. Für jedes DBMS gibt es ein spezielles Interface. Die Anwendung arbeitet mit dem Interface. :thumb: Die Anbindung der Objekte aus der Liste funktioniert klassisch nach Bedarf. :thumb:

Die Livebindings haben mir keinen Mehrwert gebracht...:?

Rollo62 4. Apr 2017 08:15

AW: Absturz des SQL-Editors in der IDE (D7/ADS10.1)
 
Für das Füllen und Reagieren auf Änderungen musst du dann Alles von Hand verknüpfen und hast du zu jeder Komponente einen "Wrapper" der das bidirektional erledigt ?
Oder benutzt du dafür auch schon RTTI oder das Spring4D Framework ?

Das sollte eigentlich ja LiveBindings leisten, so das man einfach DB mit dem View verbinden kann.
Warum genau hast du dich gegen LB entschieden, war es die Performance, oder die Stabilität ?
Ich möchte den LB Gedanken noch nicht komplett über Bord werfen :stupid:

Rollo

haentschman 4. Apr 2017 08:42

AW: Absturz des SQL-Editors in der IDE (D7/ADS10.1)
 
Moin...:P
Zitat:

Für das Füllen und Reagieren auf Änderungen musst du dann Alles von Hand verknüpfen
...ja. :wink: Da gehört eigentlich noch mehr dazu...:wink:
sinngemäß: Beispiel an einem Frame:
1. Dem Frame wird das Objekt was es anzuzeigen gilt übergeben.
2. Vom Objekt wird eine Kopie erstellt. (neue Instanz)
3. Der Frame arbeitet mit der Kopie. (zurücksetzen möglich etc.).
4. In den klassischen OnChange werden die Änderungen in die Kopie geschrieben.
5. Speichern NEIN: Die Kopie wird weggeräumt...
6. Speichern JA: Über Assign des Originalobjektes werden die Werte übertragen. Die Kopie wird weggeräumt...
...fertsch. 8-) Klar ist das mehr Arbeit. Aber man hat die Kontrolle...8-)

Zitat:

Das sollte eigentlich ja LiveBindings leisten, so das man einfach DB mit dem View verbinden kann.
Warum genau hast du dich gegen LB entschieden, war es die Performance, oder die Stabilität ?
...versuche mal ohne Code mit LB ein Objekt aus einer Liste an ein ListviewItem oder einen Combobox Eintrag zu hängen. :? Klassisch wäre das ein Einzeiler.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:43 Uhr.
Seite 2 von 2     12   

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