![]() |
Aufgaben mit LiveBindings und Delphi-DB's erledigen
Liste der Anhänge anzeigen (Anzahl: 2)
Ich habe jetzt mal ein paar Informationen im Delphi DOC-Wiki zu LiveBindings gelesen. Da scheinen mehr Möglichkeiten drin zu stecken, als ursprünglich von mir vermutet.
Daher meine Frage: Ist es möglich, in einem VCL-Projekt mit LiveBindings und einer (welcher?) Delphi-Datenbank eine einfache Datei mit 10 Feldern ohne viel Aufwand zu verwalten und dabei die folgenden Anforderungen zu erfüllen: * Die Liste sollte bei Bedarf sortierbar sein, aber auch ohne Sortierung darstellbar sein * Feldinhalte sollten mit unterschiedlichen Farben in der Liste angezeigt werden können * Datensätze sollten gefiltert werden können und dann nur die gefilterten Sätze in der Liste angezeigt werden * Es sollte ohne großen Aufwand eine andere Datenbank-Datei (Standard / User) gewählt werden können, gleiche Felder * Es sollten Icons in den Spalten darstellbar sein * Datensätze sollten in der nicht sortierten Liste eine Zeile nach oben oder eine nach unten verschiebbar sein * Datensätze sollten in der nicht sortierten Liste per Drag und Drop verschiebbar sein. * Wäre toll, wenn die Datenbank ohne Feldlängenbegrenzung auskommt und ich mich nicht um so was kümmern müsste * Ein Datensatz sollte mit einem eigenständigen Dialog erzeugt / bearbeitet werden können Ich wäre dankbar für generelle Aussagen, ob das so mit LiveBindings (incl. Expressions) RELATIV EINFACH realisierbar wäre und wenn Ja, welche Datenbank zu empfehlen wäre (bitte möglichst eine einfache, ich bin da völlig ahnungslos mit Delphi-DB's - mir steht Delphi-Enterprise 10.1 zur Verfügung). Die Funktionalität ist derzeit im Programm mit einer Alternativlösung (einfache TStringlist, Felder getrennt durch Sonderzeichen) schon vorhanden (zur Verdeutlichung 2 anliegende Screenshots). Mich nervt aber, dass für so relativ einfache Aufgaben - Verwaltung einer einfachen Liste - (immer wieder mal) so ein großer Aufwand betrieben werden muss (Source-Zeilen in der Unit, die das bei mir erledigt, hat ca. 600 Zeilen). Daher würde ich hier gerne als "Blaupause" mal eine Umstellung auf LiveBindings testen. Bevor ich mich jedoch an die Arbeit mache, wäre ich über einige Hinweise oder Ratschläge von Euch dankbar. |
AW: Aufgaben mit LiveBindings und Delphi-DB's erledigen
Also ich denke nicht das Du mit den Livebindings da wirklich "schnell" zum Ziel kommst. Mein Eindruck ist eher das die LiveBindigs VCL stiefmütterlich behandelt werden. Das ganze Konzept ist sh..... (meine Meinung).
Zur Datenbank schaue dir sqlite an dass sollte Deinen Anforderungen noch am nächsten kommen. |
AW: Aufgaben mit LiveBindings und Delphi-DB's erledigen
Es gab schon einige solche Versuche. Zuletzt hier:
![]() Ist aber meiner Kenntnis nach noch nichts nachhaltiges draus entstanden. |
AW: Aufgaben mit LiveBindings und Delphi-DB's erledigen
Da die VCL spezielle DB Controls hat, würde ich das gerade bei einer Datenbank/Dataset als Backend jederzeit irgendeiner Binding Lösung bevorzugen.
Bei FMX sieht das (leider) anders aus, da es dort keine speziellen DB Controls gibt, die mit einer TDataSource zusammen arbeiten. |
AW: Aufgaben mit LiveBindings und Delphi-DB's erledigen
"Wenn man's kann ist alles einfach."
Für mich sehen Deine beiden Beispiele wie eine klassische DB-Anwendung aus. Ich würde da keinen Gedanken an LiveBindings oder DB-Controls verschwenden. Wenn ich Dich richtig verstanden habe und die richtigen Schlüsse ziehe, dann hast Du z.Zt eine Stringlist, die Du in einer Listview anzeigst. (OK da gibt's noch etwas zum sortieren und ..) Wahrscheinlich wird Deine Stringlist aus einer Datei gefüllt. Diese Datei würde ich durch eine Query und eine Firebird-DB ersetzen. Sprich Filtern und Sortieren z.B. wird in der SQL-Abfrage erledigt, und die Query schreibt die entsprechenden Ergebnisse in eine Stringlist. Diese wird wie gehabt angezeigt. Kombinierst Du die Query noch mit einer Connection ist der Wechsel der DB eine Kleinigkeit (ist aber ach so kein Hexenwerk!) Was die DB angeht, bevorzuge ich Firebird, aber auch alle anderen lokalen DBs sollten erst einmal genügen. Und der Austausch sollte in zwei Schritten erledigt sein: a) Konvertieren/Übertragen der Daten b) Ändern der Connection-Parameter uU. ist noch ein dritter Schritt notwendig c) Anpassen der SQL-Texte Und wenn Du das alles noch in ein DataModule auslagerst hast Du eine richtig pflegeleichte Anwendung. Gruß K-H |
AW: Aufgaben mit LiveBindings und Delphi-DB's erledigen
Erst mal vielen Dank für Eure Antworten.
Habe mir mal das ClientDataset in Verbindung mit dem DBGrid angesehen, ich denke, das erfüllt bestens die gestellte Aufaben (Sortierung, Filterung). Mit meiner bisherige StringList befüllte ich das ClientDataset, wenn der Bearbeitungsdialog gestartet wird. Dann kann ich Filtern, sortieren, bearbeiten usw. und nach OK übertrage ich den Inhalt aus dem ClientDataset wieder in meine Stringliste. Einfache Sache und ich kann die bestehende Dateistruktur beibehalten. Per LiveBindings habe ich eine Edit.Text Eigenschaft mit der Filter-Eigenschaft aus dem ClientDataset verbunden (über eine Expression), so dass ich hier ganz einfach über die Eingabe von Suchtext in das Editfeld filtern kann. Was mir dabei auffällt: * Nach dem Setzen des Filters aktualisiert sich das DBGrid erst, wenn ich einmal darauf klicke. Gibt einen Befehl, der das sofort nach Setzen des Filters macht? * Wenn das Programm mit Styles arbeitet, werden Farben im DBGrid, die man über den Spalten-Editor setzt (den kannte ich noch gar nicht), nicht berücksichtigt, AUCH DANN, wenn man über StyleElements den entsprechenden Ausschluss vornimmt. Ist das ein bekannter Bug und wie kann man das umgehen? * Wenn ich filtere, kann ich z.B. mit NameOFField = 'TTab*' mir einen gesuchten Eintrag anzeigen lassen. Gibt es eine Möglichkeit, direkt in allen Feldern zu suchen ('*' hat nicht funktioniert). Wie gesagt, die ganze Datenbankarbeit mit den typischen Delphi-Datenbank-Komponenten ist neu für mich. Aber die Funktionalität von ClientDataset und DBGrid finde ich schon toll. Damit kann man viel Handarbeit ersparen. |
AW: Aufgaben mit LiveBindings und Delphi-DB's erledigen
Wie setzt du denn den Filter? Ich mach das immer wie folgt und das Grid aktualisiert sich ohne das ich reinklicken muss:
Delphi-Quellcode:
//ggf.: ClientDataset.Filtered:=false;
ClientDataset.Filter:='irgendwas'; ClientDataset.Filtered:=true; Bei deinem dritten Sternchen, hab ich die Intention nicht ganz verstanden, aber du kannst den Filterstring ja beliebeig formulieren, fast wie eine Where-Bedingung in einem SQL-Statement. NameOFField1 = 'TTab*' Or NameOFField2 = 'TTab*' or NameOFField3 = 'TTab*' |
AW: Aufgaben mit LiveBindings und Delphi-DB's erledigen
Zitat:
Zitat:
Delphi-Quellcode:
eingeben.qf := QuotedStr (bnFind.Text+'*'); cds1.Filter := 'QuellDaten = ' + qf + ' OR ' + 'ZielDaten = ' + qf + ' OR ' + 'AusnahmeKomp = ' + qf + ' OR ' + 'Wert = ' + qf; Schön wäre es, wenn es ein "SearchInAnyField"-Platzhalter gäbe, so das dass ich nicht jedes einzelne Feld hier angeben muss. Weiterer Punkt: Ist hier tatsächlich die Beschränkung gegeben, dass man nur nach grid* filtern kann, aber nicht nach *grid*? Mit der ersten Variante wird z.B. bei der Eingabe von "grid" der gesuchte Text nicht gefunden, wenn der mit "TGrid" beginnt, die zweite Variante wird aber anscheinend nicht unterstützt. |
AW: Aufgaben mit LiveBindings und Delphi-DB's erledigen
@Harry
Du kennst die Methode ![]() Das kombiniert mit dem ![]()
Delphi-Quellcode:
procedure TWhatever.DataSetOnFilterRecord( Dataset: TDataSet; var Accept: Boolean );
begin Accept := CurrentFilter.IsSatisfiedBy( DataSet ); end;
Delphi-Quellcode:
DataSetSpecifications = class
class function IsInAnyField( aStr: string ): ISpecification<TDataSet>; // usw. end; |
AW: Aufgaben mit LiveBindings und Delphi-DB's erledigen
Danke für den Hinweis. Nein, kannte ich noch nicht (mal kurz gesehen).
Aber verstehe ich das richtig, hier wird mir eine Datenmenge als Ergebnis meines Filters gegeben, die ich nun akzeptieren kann oder nicht. D.h. ich kann nur weiter einschränken, aber nicht den Filter erweitern, oder? Ich möchte erreichen, dass statt "TGrid" auch schon "grid" akzeptiert wird als ein valides Ergebnis des Filters, wenn ich z.B. auf ein TStringGrid treffe. |
AW: Aufgaben mit LiveBindings und Delphi-DB's erledigen
Ähm, du kannst dir die Specifications definieren und zusammenbauen wie du möchtest und das immer wieder wie du möchtest
|
AW: Aufgaben mit LiveBindings und Delphi-DB's erledigen
Liste der Anhänge anzeigen (Anzahl: 1)
Ok, das Event (OnFilterRecord) behalte ich mal in Reserve. Momentan kann ich es wie gewünscht per "Like" lösen, wobei man das in Zusammenhang mit "%" nutzen muss.
Der folgende Filter liefert mir wie gewünscht eine Suche über alle Felder, für den Begriff "grid" alle Einträge zurück, der ihn als Teil enthält (zusätzlich wird noch ein StandardFilter berücksichtigt [FrameWorkFilter], wenn der nicht Leer ist):
Delphi-Quellcode:
vgl. Resultat der Suche im anliegenden Screenshot. Einen Platzhalter für Feldnamen, der für alle Felder steht, scheint es ja nicht zu geben (Hinweis, ich verwende hier nur das ClientDataset mit dem Datasource, ohne eine Datenbank dahinter).
procedure TF_ConvertList.bnFindChange(Sender: TObject);
var find, AllFieldsFilter: String; L: Integer; begin cds1.Filtered := False; if bnfind.Text <> '' then begin find := QuotedStr ('%'+ bnFind.Text+'%'); //<-- "%" mit Like, "*" für PartialRight-Suche for L := 0 to cds1.FieldCount-1 do begin if L = cds1.FieldCount-1 then begin AllFieldsFilter := AllFieldsFilter + cds1.FieldList[L].FieldName + ' like ' + find; end else begin AllFieldsFilter := AllFieldsFilter + cds1.FieldList[L].FieldName + ' like ' + find + ' OR '; end; end; if FrameWorkFilter <> '' then begin cds1.Filter := FrameWorkFilter + ' and (' + AllFieldsFilter + ')'; end else begin cds1.Filter := AllFieldsFilter; end; end else begin cds1.Filter := FrameWorkFilter; end; cds1.Filtered := (bnFind.Text <> '') or (FrameWorkFilter <> ''); end; Insgesamt scheint sich ja da eine erfreuliche Bandbreite an Möglichkeiten aufzutun. |
AW: Aufgaben mit LiveBindings und Delphi-DB's erledigen
Hallo Harry...:P
Warum willst du dich in der Datenstruktur an das DataSet, DataSource, DB sensitive Controls Gedöns pressen lassen? Imho holst du dir mehr Flöhe in den Pelz als notwendig. :roll: Persönlich habe ich mich davon komplett verabschiedet...und ein Klotz am Bein ist weg. :thumb: Mein Vorgehen: 1. Für die Daten des Programmes existieren einfache Datenobjekte (TPerson z.B.) 2. Diese werden in generischen Listen gehalten. 3. Das Füllen der Listen übernimmt eine Datenschicht welche als Interface implementiert ist. Beispiel: Data.FillList(PersonList: TPersonList) 4. Wenn die Listen gefüllt sind, werden die Daten in einem beliebigen Control dargestellt. Das Objekt hängt an dem jeweiligem Eintrag dran. Vorteile: 1. Der Programmlogik ist es völlig wurscht wo die Daten herkommen...sie arbeitet mit den Objekten. 2. Die Datenschicht ist austauschbar... (Herkunft der Daten z.B. aus XML oder verschiedenen DBMS) 3. Die Daten können an verschiedene Controls übergeben werden. Du bist nicht auf die VCL beschränkt. Imho auch über LiveBindings. Je nach Größe und Aufwand kann man sich das ORM (Datenschicht) selbst zusammenstellen (meine bevorzugte Variante) oder es mit einem verfügbarem Framework erledigen lassen. Zu Filter + Sortierung: * Sortieren der generischen Listen über Comparer * Filtern über Neuaufbau der Anzeige über die Kriterien. * Ableitung der Liste die ähnlich dem Comparer einen Filter erhält / übergeben bekommt. Über einen Getter gibst du die "gefilterte" Liste zurück. ...sieh es als Denkanstoß. :thumb: ...ein schönes Wochenende. |
AW: Aufgaben mit LiveBindings und Delphi-DB's erledigen
ergänzend zu haentschman: Da Du dich mit Datenbanken erst anfängst zu befassen (lt. deinem anderen Thread): Ich würde vermeiden die Datenmenge in einem Dataset nach eigener Willkür zu sortieren - das macht einfach keinen Sinn (wegen mir: Keine Regel ohne Ausnahme) nur damit in der Anzeige eine bestimmte Reihenfolge einzuhalten ist. Dazu gibt es zum einen Datenbankmechanismen (Index, Filter) oder die "bessere" Alternative über eine Datenbankzugriffsschicht bei der die Oberfläche unabhängig von irgend welchen Datenbankmöglichkeiten bestimmen kann wie die Datensätze angezeigt werden
Keine Frage: Die Lernkurve ist steiler, aber der Schritt Zeit in ein ORM zu investieren ist gut angelegt.. Grüße |
AW: Aufgaben mit LiveBindings und Delphi-DB's erledigen
Zitat:
Bislang habe ich das überall so gemacht, wie Du es hier beschrieben hast. Jedoch muss da immer viel händisch regeln und es hat mich einfach beeindruckt, wie einfach man mit dem ClientDataset filtern oder sortieren kann. Für kleine Datenmengen scheint das eine einfache, kompakte Sache zu sein. |
AW: Aufgaben mit LiveBindings und Delphi-DB's erledigen
Moin... :P
Zitat:
* iteriere durch die Datenmenge... sagen wir um etwas zu suchen und zu berechnen. Was macht das Grid? Aushängen / Einhängen...Arbeit Extra. * nur VCL * im Vergleich zu generischen Listen schnarch langsam (ggf. Eventorgien) * ClientDataSet war mal (ist noch?) verbuggt * mit ClientDataset geht noch... aber füge mal einer Datenmenge die aus der DB geholt wird 2 Felder für die Anzeige hinzu oder ändere die Anzeige. (Beispiel: in der DB steht nur der Index für einen Wert, der Klartext in einem String Array. In der Anzeige willst du aber Klartext. (Feldtypen passen nicht)... Leerfelder dazuholen und extra füllen ist die Devise... = Basteln * versuche mal in einer numerischen Spalte in Abhängigkeit vom Wert eine unterschiedliche Anzahl von Nachkommastellen darzustellen. Das geht nur über selbst Zeichnen. Da fängt die Bastelei schon wieder an. :roll: * wenn du dann noch im Grid editieren willst, hast du verloren. (Da gabs gerade etwas dazu) * du bist auf die Optik der DB Controls angewiesen... teilweise verstaubte W95 Optik. Teilweise keine konsistente Darstellung der DB Controls. * (Query - Edit, Post etc.) besser saubere SQL als nicht zu wissen was wirklich mit welchem Overhead in der Komponente passiert. * Verwaltung der SQL Statements extern...also nicht in der Komponente verteilt über die Anwendung. * wenn man mal mit der Bastelei angefangen hat wird der Code u.U. immer schlechter wartbar, weil man an verschiedenen Stellen nachhelfen muß. * man kann nicht eben mal sagen... "Das Grid mag ich nicht mehr. Ich mach das jetzt mit Edits..." (Austauschbarkeit der GUI Schicht) Zitat:
Zitat:
Fazit: Ich habe gerade ein Projekt wo unbedingt DB Grids gefordert sind. Was ich, um die Darstellung zu gewährleisten, teilweise für Verrenkungen machen muß... :roll: Je komplexer die Anforderung umso größer die Bastelei. Für meinen Geschmack ist es ein Rückschritt in Technologie aus den 90ern. :roll: ...letztendlich bleibt es meine Meinung. Ein schönes Wochenende. :thumb: |
AW: Aufgaben mit LiveBindings und Delphi-DB's erledigen
Zitat:
Nebenbei finde ich es durchaus bemerkenswert, daß ein ziemlich brauchbares ORM wie TMS Aurelius auch ein TAureliusDataset mitbringt, mit dem man die Objektinstanzen des ORM wieder über datensensitive Controls ansprechen kann. So ganz beiseite wischen würde ich den Ansatz mit datensensitiven Controls noch nicht. Er hat sicher noch eine Weile seine Daseinsberechtigung. Wie mit all diesen Sachen muss man natürlich lernen damit umzugehen und mit der nötigen Erfahrung lassen sich die verschiedenen Anforderungen auch effizient und relativ schnell lösen. Das gilt natürlich für ein ORM ebenso. |
AW: Aufgaben mit LiveBindings und Delphi-DB's erledigen
Hallo Harry,
kennst du die Serie zu ![]() Da ist es schön beschrieben, und am Ende wird auch gezeigt wie man das von Hand machen kann. Hier gab es auch schon ![]() Ich benutze das LB im Moment einer super-simplen, flachen Datenbank mit Sqlite, aber von Hand gesetzt, per LiveBinding. Funktioniert, aber so ganz traue ich dem Braten noch nicht. Zumindest läuft das mit Sqlite unter allen Plattformen. Zu Haentschman's Vorschlag, das wird in der Serie oben auch beschrieben. Als Objektliste funktioniert das genauso wie in einer Datenbank, das ist den LiveBindings egal wo die Daten herkommen. Aber ich sehe auch den Speicherbedarf, ich habe immer noch die Hoffnung das eine Sqlite Datenbank nicht alle Daten erstmal in den Speicher lädt. Bei der Objektliste wird das aber wohl so sein, es sei denn man kümmert sich aufwändig um Laden und Zerstören der Objekte im Speicher. Ein fertiges ORM würde wohl auch gehen, das habe ich nocht nicht gecheckt, ist aber doch mit Kanonen auf spatzen zu schiessen. Diese einfache Anforderung die du unten beschreibst habe ich i.d.R. auch zu 90%, und dafür soll (muss) LiveBindings doch ausreichen, ohne grosse Verrenkungen. Rollo |
AW: Aufgaben mit LiveBindings und Delphi-DB's erledigen
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo Rollo,
nein, kannte ich noch nicht, danke für den Link. Interessant insofern, dass man das entsprechend auch für FMX machen kann (habe ich gerade mal spaßeshalber getestet) und soweit ich das sehe, funktioniert auch alles (incl. Gruppierung der Daten nach Kategorien und Updates der geänderten Daten in alle Richtungen). DBEdits wurden natürlich durch normale TEdits ersetzt. In der Anlage ein Screenshot. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 04:35 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-2025 by Thomas Breitkreuz