![]() |
Datenbank: SQLite • Version: ? • Zugriff über: UniDac
SQLite + DBGrid + Sortieren über Spalten Click
Hallo zusammen,
ich verwende in meinem Programm eine SQLite Datenbank. Die User möchten nun das Sie über den Klick auf den Titel einer Spalte die Datenmenge nach dieser Spalte Sortieren, so wie es halt auch fast jedes Programm macht. Ich hab das bisher noch nie umsetzen müssen und hab bisl im Internet darüber gesucht. Hab ich das richtig interpretiert das man die Datenmenge im DBGrid nicht sortieren kann, sondern das man den SQL Befehl erneut mit der Order By Klausel absetzen muss? Mein Lösungsansatz (der auch funktioniert) sieht bisher wie folgt aus:
Delphi-Quellcode:
giSortColumn und gsSortOrder sind Globale Variablen in denen ich mir den letzten Sortier Stand merke.
//Get Sort Column Number and Name
If Column.Index = giSortColumn Then Begin If gsSortOrder = 'ASC' Then gsSortOrder := 'DESC' Else gsSortOrder := 'ASC'; End Else Begin gsSortOrder := 'ASC'; End; giSortColumn := Column.Index; sFieldName := Column.FieldName; //Sort Try With (sqlitefile_query1) Do Begin Active := False; datsrc_test.DataSet := Nil; SQL.Clear; SQL.Add('Select * From DATCOM'); SQL.Add('Order By ' + sFieldName + ' ' + gsSortOrder); datsrc_test.DataSet := sqlitefile_query1; Active := True; End; Except On E:Exception Do Begin MessageDlg(E.Message, mtError, [mbOK], 0); Exit; End; End; //Show Sort Column dbgrid_test.Columns[giSortColumn].Title.Font.Style := dbgrid_test.Columns[giSortColumn].Title.Font.Style + [fsBold]; |
AW: SQLite + DBGrid + Sortieren über Spalten Click
Zitat:
Es sei denn du verwendest ein Grid, dass die Datenmenge intern zwischenspeichert und daher auch sortieren kann. wie z.B. ![]() |
AW: SQLite + DBGrid + Sortieren über Spalten Click
Zitat:
Delphi-Quellcode:
MyQuery.IndexFieldNames := 'Nachname ASC CIS; Vorname DESC';
Da UniDac und IbDac aus derselben Schmiede stammen, gehe ich mal davon aus, daß das, was in meiner IbDac-Hilfe steht, auch für UniDac gilt: Use the IndexFieldNames property to get or set the list of fields on which the recordset is sorted. Specify the name of each column in IndexFieldNames to use as an index for a table. Ordering of column names is significant. Separate names with semicolon. The specified columns don't need to be indexed. Set IndexFieldNames to an empty string to reset the recordset to the sort order originally used when the recordset's data was first retrieved. Each field may optionally be followed by the keyword ASC / DESC or CIS / CS / BIN. Use ASC, DESC keywords to specify a sort direction for the field. If one of these keywords is not used, the default sort direction for the field is ascending. Use CIS, CS or BIN keywords to specify a sort type for string fields: CIS - compare without case sensitivity; CS - compare with case sensitivity; BIN - compare by character ordinal values (this comparison is also case sensitive). If a dataset uses a TCustomDAConnection component, the default value of sort type depends on the TCustomDAConnection.Options option of the connection. If a dataset does not use a connection (TVirtualTable dataset), the default is CS. Read IndexFieldNames to determine the field (or fields) on which the recordset is sorted. Ordering is processed locally. Note: You cannot process ordering by BLOB fields. Wenn man eine Komponente erwirbt, ist es meist nicht verkehrt, sich die Dokumentation dazu anzuschauen, bevor man sie einsetzt. |
AW: SQLite + DBGrid + Sortieren über Spalten Click
Bei ADO geht das auch (in-Memory sorting),indem Du die Eigenschaft 'IndexFieldNames' belegst (Feldnamen durch Semikolon getrennt).
Allgemein gesehen ist es ziemlicher Blödsinn, die Daten vom Server sortieren zu lassen. Sortieren ist doch ein wenig Ressourcenfressend und so ein DB-Server ist dafür eigentlich zu schade. Und wenn Du nun mal nicht eine SQLite-DB hast, sondern später mal eine richtige DB, bei der mehrere Leute dran sitzen und die klicken munter auf die Sortierspalten, dann ist der Server so mit Sortieren beschäftigt, das er andere Sachen nicht mehr zeitnah hinbekommt. Lieber heute richtig anfangen, als sich morgen falsche Sachen angewöhnt haben. Nur in sehr seltenen Fällen, nämlich wenn die anzuzeigende Tabelle soviele Daten enthält, das Du die gar nicht alle in den lokalen Speicher bekommst, sollte man das dem Server überlassen. Dann aber auch nur mit Index auf jeder Spalte, was auch wieder behämmtert ist (Stichwort: Index-Shotgun). Richtig ist, ein Grid oder ein in-Memory Dataset zu verwenden, das das Sortieren eben lokal erledigt. Warum auch nicht, denn die Daten sind doch eh schon da. Nur das dämliche TDBGrid kann das eben nicht. Wenn deine TDataset-Komponente das nicht kann, dann kopiere die Daten in ein TClientDataset, das kann -glaube ich zumindest- sortieren. Edit: Hab gerade 'UniDac' gelesen.. Na dann gehts ja. |
AW: SQLite + DBGrid + Sortieren über Spalten Click
ADO : xxx.Sort='FELDDNAME';
TClientDataSet: xxx.IndexName:='Feldname'; Dac: keine Ahnung, das will noch entdeckt werden! |
AW: SQLite + DBGrid + Sortieren über Spalten Click
Vielen Dank für die Tipps.
Das mit den IndexFieldNames habe ich ausprobiert und funktioniert einwandfrei! Ich hab nur noch eine Verständnisfrage... Wenn ich im SQL eine Ordre By Klausel hab, werden meine Daten sobald ich sie im DBGrid hab ja erst mal nach diesen Kriterien sortiert. Wie verhält sich das wenn ich dann über IndexFieldNames sortiere? Die Order By Klausel wird dann ja ausser Kraft gesetzt oder nicht? |
AW: SQLite + DBGrid + Sortieren über Spalten Click
Vereinfacht ausgedrückt: das ORDER BY legt die Reihenfolge fest, in der der Server die Datensätze zum Client schickt. Wenn Letzterer sie aber einmal lokal zwischengespeichert hat, kann er sie wieder umsortieren, wie er lustig ist.
|
AW: SQLite + DBGrid + Sortieren über Spalten Click
Order By , hier muss eine SQL Abfrage Neu gemacht werden (Daten kommen sortiert vom Server)
IndexName, das Betrift die Daten, die sich nach dem laden im ClientDataSet befinden, die werden in der Komponente sortiert und Betrift nur die Daten, die dort drin sind unabhängig vom SQL Server! |
AW: SQLite + DBGrid + Sortieren über Spalten Click
Ok, dann wäre es so wie ich es haben möchte...
Noch ne andere Frage... Meine Tests habe ich in einem Testprogramm gemacht wo ich ein DBGrid verwendet hab wo an den Einstellungen nichts verändert wurde... Jetzt versuch ich das ganze in mein bestehendes Programm einzubauen und auf einmal kommt mein Programm nicht mehr ins "OnColumnTitleClick" Ereignis... :shock: Gibt es Einstellungen die das verhinden können? |
AW: SQLite + DBGrid + Sortieren über Spalten Click
Ich vermute mal das durch das rüberkopieren von Codezeilen ist das Event des Grids noch nicht mit dem Code verknüpft oder die Komponenten heißen anders o.ä.
|
AW: SQLite + DBGrid + Sortieren über Spalten Click
Nee, einfacher...
Ich hatte in den Options dgTitleClick deaktiviert :oops: |
AW: SQLite + DBGrid + Sortieren über Spalten Click
Muss man beim Sortieren von Zahlenwerten noch etwas berücksichtigen?
Die werden bei mir gerade z.B. wie folgt sortiert: 100 11 12 200 Ich hab diese Werte leider als String Werte in der SQLite, Caste Sie aber zu Integers
Code:
Jetzt weiß ich aber nicht woher das Problem kommt... Ob es an meinem Datentyp in der DB liegt und das Casten nichts bringt oder ob es an der Sortierung an sich liegt...
CAST(SUM(Feld1) as Integer)
Hab schon CIS und BIN ausprobiert... |
AW: SQLite + DBGrid + Sortieren über Spalten Click
Datamodule1.KUTable.Sort := '[DEIN_VORNAME]';//1.Spalte
Datamodule1.KUTable.Sort := '[DEIN_NAME]';//1.Spalte usw. |
AW: SQLite + DBGrid + Sortieren über Spalten Click
Zitat:
|
AW: SQLite + DBGrid + Sortieren über Spalten Click
:cyclops:
|
AW: SQLite + DBGrid + Sortieren über Spalten Click
Zitat:
|
AW: SQLite + DBGrid + Sortieren über Spalten Click
Zitat:
Wenn Du numerische Werte in einem (..)Grid anzeigst, sind sie nicht mehr numerisch. Wo zum .. sortierst Du und wo führst Du den Cast aus? (und alle die sagen, das ein Grid nur für die Anzeige ist, grinsen jetzt) Gruß K-H |
AW: SQLite + DBGrid + Sortieren über Spalten Click
Dass ein SUM() überhaupt auf Strings geht, ist mir neu.
|
AW: SQLite + DBGrid + Sortieren über Spalten Click
Zitat:
Zitat:
Mittlerweile hab ichs auf den Feldtyp "int" umgestellt. Betrachte ich meine SQLite Tabelle mit dem SQLiteManager Add-On im Firefox werden die Daten durch ein "Order By" richtig sortiert. Sortiere ich im Programm über die UniDac Komponente mit einem "Order By" habe ich wieder das beschriebene Problem das er nicht richtig sortiert. Dasselbe habe ich wenn ich nach einem Klick auf die Spalten Überschrift mit "IndexFieldName" sortiere. Hatte jemand schon mal solche Probleme? |
AW: SQLite + DBGrid + Sortieren über Spalten Click
Liegt das evtl. an der SUM() Funktion???
Wenn ich die Daten ohne Group By und und SUM() Funktion abhole und über die IndesFieldName Funktion der TUniQuery sortiere, dann klappt alles mit dem sortieren. Wenn ich aber in meinem SQL Befehl einen SUM() habe mit Group By und danach sortiere dann bekomme ich wieder die falsche Sortierung... Hier mal ein Code Beispiel wie ich es meine: SQL
Code:
Delphi Source für die Sortierung
Select Commissions, Sum(Menge) as "Kommissions Menge" From Tabelle1
Group By Commissions
Delphi-Quellcode:
SQLiteFile_DisplayCommissions.IndexFieldNames := '"' + sFieldName + '" ' + gsSortOrder + ';';
sFieldName würde z.B. die DBGrid Spaltenüberschrift "Kommissions Menge" beinhalten. Der SQL beinhaltet einen Group By da die Kommission aus mehreren Positionen besteht und in einer Info Ansicht die Gesamtmenge angezeigt werden soll... |
AW: SQLite + DBGrid + Sortieren über Spalten Click
Feldname mit Leerzeichen, geht das tatsächlich?
|
AW: SQLite + DBGrid + Sortieren über Spalten Click
Entsprechend gequotet geht das AFAIK so ziemlich mit jedem DBMS.
|
AW: SQLite + DBGrid + Sortieren über Spalten Click
Zitat:
|
AW: SQLite + DBGrid + Sortieren über Spalten Click
Welcher Datentyp wird dir denn bei dem sum-Feld angezeigt?
Delphi-Quellcode:
aDS.FieldByName('SumMenge').Datatype
|
AW: SQLite + DBGrid + Sortieren über Spalten Click
Zitat:
Code:
das erwartete Ergebnis bringen.
select * from MyTabelle order by 1
Zitat:
Zitat:
Ich nehme eher an, daß Du die Daten, die bereits angezeigt wurden, und jetzt nicht mehr numerisch sind, versuchst zu sortieren. Und das geht zunächst einmal nicht. Eine Krücke wäre es wenn Du explizit führende Nullen oder Leerzeichen einfügst. dann sollte es wie "richtig sortiert" aussehen. Aber der wahre Jakob ist das nicht! Gruß K-H |
AW: SQLite + DBGrid + Sortieren über Spalten Click
Zitat:
Das erklärt nun den Fehler! Aber woher kommt der? Von der UniDac Query? Oder von der SQLite DB? Zitat:
An das mit den führenden Nullen dachte ich auch schon, aber so schön würde ich die Lösung nicht finden, vor allem da sie auch nicht User freundlich ist... |
AW: SQLite + DBGrid + Sortieren über Spalten Click
Schau mal hier, falls du es noch nicht selber gefunden hast :
![]() |
AW: SQLite + DBGrid + Sortieren über Spalten Click
Ich war gestern im DevArt Forum unterwegs und hab gesucht, auf den Artikel bin ich aber nicht gestoßen, Vielen Dank! :thumb:
Leider haben die damals ja auch keine praktikable lösung gefunden :pale: Mal schaun ob mein eigener Topic mehr Erfolg hat im DevArt Forum... |
AW: SQLite + DBGrid + Sortieren über Spalten Click
Nur falls es dich interessiert : Ich benutze UniDAC mit mysql, dort werden mir alle sum-Felder als ftFloat gegeben.
|
AW: SQLite + DBGrid + Sortieren über Spalten Click
Wie kann ich den denn DataType eines Feldes in eine String Variable einlesen?
|
AW: SQLite + DBGrid + Sortieren über Spalten Click
Delphi-Quellcode:
S := FieldTypeNames[aDB.FieldByName('FeldName').DataType];
EDIT : Du könntest als WorkAround mal versuchen eine temporäre Tabelle anzulegen und dort das Summenfeld als Integer definieren. Danach deinen select in diese Tabelle als insert durchführen, evtl. klappt das ja. |
AW: SQLite + DBGrid + Sortieren über Spalten Click
Zitat:
Selbst wenn ich in der SQLite wieder ein Text Feld habe in dem die Mengen mit führenden Nullen stehen entfernt mir mein SUM() diese wieder und ich steh wieder vor dem Problem das ich einen String habe und nicht richtig sortieren kann... |
AW: SQLite + DBGrid + Sortieren über Spalten Click
Also nach bisl Testerei hab ich jetzt die folgenden Lösung (hätte ich auch früher drauf kommen können)...
Ich habe vorhin festgestellt das wenn ich mein summiertes Mengen Feld (welches als Integer in der Datenbank definiert ist) über den Alias Namen in der Order By Klausel sortiere, dass ich dann das richtige Sortier Ergebnis erhalte. Also habe ich mich jetzt gegen die "IndexFieldName" Funktion der TUniQuery entschieden und sortiere im OnTitleClick des DBGrids wieder über einen SQL Befehl (ich denke die Lösung ist vertretbar, da meine SQLite auf dem Client liegt und so kein Unterschied entsteht ob ich auf dem Client die Ergebnis Menge sortiere oder mir das Ergebnis neu sortiert hole) Meiner Meinung nach ist in der DevArt Komponente ein Bug und es ist nicht ein Fehler der SQLite Developer wie es AlexP im DevArt Forum (in dem Beitrag den baumina gepostet hat) darstellt... Hier anbei mein Source für den Sort:
Delphi-Quellcode:
//Get Sort Column Number and Name If Column.Index = giSortColumn Then Begin If gsSortOrder = 'ASC' Then gsSortOrder := 'DESC' Else gsSortOrder := 'ASC'; End Else Begin gsSortOrder := 'ASC'; End; giSortColumn := Column.Index; sFieldName := Column.FieldName; //Sort via SQL Try With (sqlitefile_query1) Do Begin Active := False; datsrc_test.DataSet := Nil; SQL.Clear; SQL.Add('Select '); SQL.Add('COMMON, COM_NO, COM_KZ, SUM(COMSTT) as "Test" '); SQL.Add('From DATCOM '); SQL.Add('Group By COMMON, COM_NO, COM_KZ '); SQL.Add('Order By ' + sFieldName + ' ' + gsSortOrder); datsrc_test.DataSet := sqlitefile_query1; Active := True; End; Except On E:Exception Do Begin MessageDlg(E.Message, mtError, [mbOK], 0); Exit; End; End; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:10 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