Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Sortieren im DBGrid bei Datumswerten?

60 views
Skip to first unread message

Heiko Baumann

unread,
Jun 12, 2011, 4:35:31 PM6/12/11
to
Hallo zusammen,

eine Frage: ich hab in einem DBGrid (genauer: JvDBUltimGrid aus der Jedi
JVCL) Datumswerte (tt.mm.jjjj) angezeigt. Das Grid bringt das Sortieren
durch Mausklick auf den Spaltenkopf von Haus aus mit, das funktioniert
auch soweit, aber bei Datumsangaben stimmts leider nicht ganz, da
offenbar nur die Stringwerte verglichen werden und somit in der
Reihenfolge '01.06.2011' vor '13.05.2011' vor '23.04.2011' kommt, was
eigentlich ja genau anders rum sein müsste.

Gibts da nen Trick wie man das richtig sortieren lassen kann, ohne dass
es von der DB neu erledigt wird? Die Daten sind ja schon alle im Client,
da müsste man ja nicht unbedingt eine neue Abfrage starten.. oder?

Danke!
LG Heiko

Nicole Wagner

unread,
Jun 16, 2011, 8:12:06 AM6/16/11
to
Heiko Baumann wrote:

Das wuerde ich so nicht machen.

Schreibe eher ein "sort by date" in Deine SQL Abfrage und lasse die
Query auf Klick akutualisieren.

Oder sind die Daten nicht aus der DB?

Nicole

Heiko Baumann

unread,
Jun 16, 2011, 2:39:11 PM6/16/11
to
Am 16.06.2011 14:12, schrieb Nicole Wagner:
> Heiko Baumann wrote:
>
>> Hallo zusammen,
>>
>> eine Frage: ich hab in einem DBGrid (genauer: JvDBUltimGrid aus der
>> Jedi JVCL) Datumswerte (tt.mm.jjjj) angezeigt. Das Grid bringt das
>> Sortieren durch Mausklick auf den Spaltenkopf von Haus aus mit, das
>> funktioniert auch soweit, aber bei Datumsangaben stimmts leider nicht
>> ganz, da offenbar nur die Stringwerte verglichen werden und somit in
>> der Reihenfolge '01.06.2011' vor '13.05.2011' vor '23.04.2011' kommt,
>> was eigentlich ja genau anders rum sein mᅵsste.

>>
>> Gibts da nen Trick wie man das richtig sortieren lassen kann, ohne
>> dass es von der DB neu erledigt wird? Die Daten sind ja schon alle im
>> Client, da mᅵsste man ja nicht unbedingt eine neue Abfrage starten..

>> oder?
>>
>> Danke!
>> LG Heiko
>
>
>
> Das wuerde ich so nicht machen.
>
> Schreibe eher ein "sort by date" in Deine SQL Abfrage und lasse die
> Query auf Klick akutualisieren.
>
> Oder sind die Daten nicht aus der DB?

Doch doch, das wᅵrde sicherlich gehen, allerdings wᅵre eine erneute
Anfrage an die DB performancetechnisch ungᅵnstig und sogar ᅵberflᅵssig,
da die Daten ja alle bereits beim Client liegen und nur umsortiert
werden mᅵssen.

Hab die Ursache inzwischen gefunden: ich mache dummerweise per SQL ᅵber
DATE_FORMAT aus dem Datumsfeld einen String, und dann ist es nicht
verwunderlich, dass das DBGrid falsch sortiert. Wenn das Feld ein echtes
TDate oder TDAtetime ist, klappts mit der nativen Sortierung des Grids
problemlos.

Danke fᅵrs Mitdenken!

LG Heiko
>
> Nicole

Nicole Wagner

unread,
Jun 17, 2011, 5:08:58 AM6/17/11
to
Heiko Baumann wrote:


> Doch doch, das wᅵrde sicherlich gehen, allerdings wᅵre eine erneute
> Anfrage an die DB performancetechnisch ungᅵnstig und sogar
> ᅵberflᅵssig, da die Daten ja alle bereits beim Client liegen und nur
> umsortiert werden mᅵssen.
>
> Hab die Ursache inzwischen gefunden: ich mache dummerweise per SQL
> ᅵber DATE_FORMAT aus dem Datumsfeld einen String, und dann ist es
> nicht verwunderlich, dass das DBGrid falsch sortiert. Wenn das Feld
> ein echtes TDate oder TDAtetime ist, klappts mit der nativen
> Sortierung des Grids problemlos.
>
> Danke fᅵrs Mitdenken!


Danke fuer das Posten der Loesung.
Klar, wenn die Abfrage "dauert", ist es guenstiger, keine neu zu
stellen.

Deine Kompomente kenne ich nicht.
Ist sie gut? Kostenlos? Hast Du ein Link?

Warum ich es anders machen wuerde, hat diesen Grund:
Grundsaetzlich ist ein DBGrid nur eine Darstellung. Es "hat" keine
Daten wie ein TStringGrid, sondern zeigt sie nur so an, wie sie in der
DB sind. D.h. wenn Du die Anzeige aendern willst "musst" Du (auch da
gibt es natuerlich Wege, es anders zu machen), die Query zur DB aendern.

Das ist mal die Grundregel, gegen die man was tun kann.
Meiner Erfahrung nach ist es im Zweifel aber effizienter, gegen
Grundregeln NICHTS zu tun. Wenn der Delphi IDE Programmierer und viele,
mit denen Du sprichtst, von der Grundregel ausgehen, dann ist es
leichter fuer Dich und mich, es auch zu tun. Denn im Zweifel schwimme
man mit dem Strom.

Ob ich mit meinen DBGrids nur die DB darstelle? - Leider nein.
Es war ein dorniger Weg, bis es tat, was ich wollte.

Darum habe ich auch gefragt, ob Dein Datum aus der DB kommt.


Nicole

Heiko Baumann

unread,
Jun 18, 2011, 4:43:53 PM6/18/11
to
>
> Deine Kompomente kenne ich nicht.
> Ist sie gut? Kostenlos? Hast Du ein Link?

Die Jedi VCL ist doch recht weit verteitet - eine Sammlung aus vielen
vielen Erweiterungen. Manches (meiner Meinung nach) unnᅵtz, manches aber
doch sehr nett.
http://jvcl.delphi-jedi.org/

>
> Warum ich es anders machen wuerde, hat diesen Grund:
> Grundsaetzlich ist ein DBGrid nur eine Darstellung. Es "hat" keine
> Daten wie ein TStringGrid, sondern zeigt sie nur so an, wie sie in der
> DB sind. D.h. wenn Du die Anzeige aendern willst "musst" Du (auch da
> gibt es natuerlich Wege, es anders zu machen), die Query zur DB aendern.

Das ist vᅵllig klar. Ich will ja nichts ᅵndern, sondern dem Benutzer
einfach die Mᅵglichkeit der Sortierung der Daten zu geben.

>
> Das ist mal die Grundregel, gegen die man was tun kann.

? Das klingt etwas abenteuerlich...

> Meiner Erfahrung nach ist es im Zweifel aber effizienter, gegen
> Grundregeln NICHTS zu tun. Wenn der Delphi IDE Programmierer und viele,
> mit denen Du sprichtst, von der Grundregel ausgehen, dann ist es
> leichter fuer Dich und mich, es auch zu tun. Denn im Zweifel schwimme
> man mit dem Strom.

Ist mir zu philosophisch. Die Daten liegen in der DB, die Query holt sie
und packt sie in eine bestimmte View, das Grid oder sonstwas zeigt genau
diese Daten an, fertig. Ist doch schᅵn dass es eine so klare logische
Struktur gibt, wozu sollte ich diese "Grundregel" brechen?


>
> Ob ich mit meinen DBGrids nur die DB darstelle? - Leider nein.
> Es war ein dorniger Weg, bis es tat, was ich wollte.

Hm. Was kommt denn dann noch rein? Berechnete oder lookup-Felder? Das
zᅵhlt doch als DB-Feld. Oder was meinst du?

Na dann, trotzdem Danke und frohes Schaffen..
LG Heiko

Perlsau

unread,
Jun 19, 2011, 6:35:37 AM6/19/11
to
Am 12.06.2011 22:35, schrieb Heiko Baumann:
> Gibts da nen Trick wie man das richtig sortieren lassen kann, ohne dass
> es von der DB neu erledigt wird? Die Daten sind ja schon alle im Client,
> da m�sste man ja nicht unbedingt eine neue Abfrage starten.. oder?

Sortierungen finden nicht in der Datenbank statt, sondern werden von der
Anwendung, die auf die DB zugreift, erledigt. Ich verwende z.B. die
FibPlus-Komponenten, um auf eine Firebird-Datenbank (2.5) zuzugreifen.
Eine Sortierung mit FibPlus gestaltet sich denkbar einfach:

CASE Spalte OF
0 : FibSet_Titel.DoSort(['INDEX'], [SortOrder]);
1 : FibSet_Titel.DoSort(['TITEL'], [SortOrder]);}
...
END;

Spalte ist hier eine globale Variable, die mit der jeweiligen Spalte im
DBGrid korrespondiert. FibSet_... sind Datasets, SortOrder ist Boolean,
gibt die Sortierrichtung an. Klicke ich auf den Titel einer Spalte
(OnTitleClick) im DBGrid, wird zuerst gepr�ft, ob der Column-Index mit
Spalte identisch ist. Wenn ja, l�st das ein SortOrder := Not Sortorder
aus: Die Sortierrichtung wird umgekehrt. Wenn nein, geschieht ein
SortOrder := TRUE und die globale Variable Spalte wird auf den Wert der
neu zu sortierenden Spalte im DBGrid gesetzt.

Steht dir kein DoSort zur Verf�gung, verwendest du zum Sortieren SQL:

PROCEDURE Sort_Titel(Spalte : INTEGER);
VAR
Merk : INTEGER;
SQL : STRING;

BEGIN
Merk := DatMod.FibSet_Titel.FieldByName('INDEX').AsInteger;
CASE Spalte OF
0 : BEGIN
DatMod.FibSet_Titel.Close;
SQL := 'SELECT * FROM TITEL ORDER BY INDEX';
IF SortOrder THEN SQL := SQL + 'ASC' ELSE SQL := SQL + 'DESC';
DatMod.FibSet_Titel.SQLs.SelectSQL.Text := SQL;
DatMod.FibSet_Titel.Open;
END;
1 : BEGIN
DatMod.FibSet_Titel.Close;
SQL := 'SELECT * FROM TITEL ORDER BY LOWER(TITEL) ';
IF SortOrder THEN SQL := SQL + 'ASC' ELSE SQL := SQL + 'DESC';
DatMod.FibSet_Titel.SQLs.SelectSQL.Text := SQL;
DatMod.FibSet_Titel.Open;
END;
...
END;

Die Sortierung findet also definitiv nicht in der Datenbank statt,
sondern wird von deinem Dataset oder Query erledigt. Die SQL-Befehle
sorgen daf�r, da� die Daten in der gew�nschten Reihenfolge aus der DB
gelesen werden. M�chtest du nach Lookup-Feldern sortieren, empfiehlt
sich der Befehl "inner join". Nehmen wir an, ich habe in meiner Tabelle
TITEL ein Feld REGIE, das auf die Tabelle REGIE verweist und in es nur
ein Integer steht, n�mlich der Prim�rschl�ssel aus der Tabelle REGIE.
Dann mu� der SQL-Befehl so aussehen:

SELECT * FROM REGIE
INNER JOIN TITEL
ON REGIE.INDEX=TITEL.REGIE
ORDER BY REGIE.NAME

Heiko Baumann

unread,
Jun 24, 2011, 5:52:17 AM6/24/11
to
Nach kurzer Auszeit (Gardasee *g*) wieder zur�ck...

> Sortierungen finden nicht in der Datenbank statt, sondern werden von der
> Anwendung, die auf die DB zugreift, erledigt. Ich verwende z.B. die
> FibPlus-Komponenten, um auf eine Firebird-Datenbank (2.5) zuzugreifen.
> Eine Sortierung mit FibPlus gestaltet sich denkbar einfach:
>
> CASE Spalte OF
> 0 : FibSet_Titel.DoSort(['INDEX'], [SortOrder]);
> 1 : FibSet_Titel.DoSort(['TITEL'], [SortOrder]);}
> ...
> END;

Ja, genau so geht das auch mit den Zeos-Komponenten. Mein Problem war
aber, dass ich bereits in der Query aus dem Datumsfeld einen String
gemacht hab (format_date...) und dadurch die Strings richtigerweise
falsch sortiert wurden (01.05.2011 kommt vor 07.04.2011 kommt vor
21.01.2011).

Na dann geht die Anfrage doch nochmal neu an die DB, genau das wollte
ich ja umgehen. Aber sch�ner Quelltext - frag mich nur ob du das f�r
jede Query extra machst oder das irgendwie generalisierst, sonst w�re es
doch ein ziemlicher Aufwand, oder?

Danke f�r die Antwort!

Perlsau

unread,
Jun 24, 2011, 8:28:04 AM6/24/11
to
Am 24.06.2011 11:52, schrieb Heiko Baumann:

>> Eine Sortierung mit FibPlus gestaltet sich denkbar einfach:
>> CASE Spalte OF
>> 0 : FibSet_Titel.DoSort(['INDEX'], [SortOrder]);
>> 1 : FibSet_Titel.DoSort(['TITEL'], [SortOrder]);}
>> ...
>> END;

> Ja, genau so geht das auch mit den Zeos-Komponenten. Mein Problem war
> aber, dass ich bereits in der Query aus dem Datumsfeld einen String
> gemacht hab (format_date...) und dadurch die Strings richtigerweise
> falsch sortiert wurden (01.05.2011 kommt vor 07.04.2011 kommt vor
> 21.01.2011).

Solches sollte man tunlichst vermeiden. Ich kann mir keinen Fall
vorstellen, f�r den man bereits in der Query ein Datums- oder
Integerfeld in ein Stringfeld umwandeln m��te. Datumsformatierungen
lassen sich gew�hnlich ebenfalls in der Query vornehmen, ohne daraus
einen String zu machen.

Wieso? Ich finde es funktioaler, wenn ein DBGrid den Zustand der
korrespondierenden Query exakt darstellt. Sonst hast du u.U. im DBGrid
eine ganz andere Sortierung als z.B. im entsprechenden Formular. F�r
mich bleibt der Grundsatz bestehen: Sortierungen und sonstige
Darstellungs-Sachen immer soweit wie m�glich in der Query regeln. Im
DB-Grid werden lediglich Farben, Titel- und Record-Schrift usw. eingestellt.

> Aber sch�ner Quelltext - frag mich nur ob du das f�r
> jede Query extra machst oder das irgendwie generalisierst, sonst w�re es
> doch ein ziemlicher Aufwand, oder?

Wie sollte ich es denn sonst machen? Jede Tabelle ben�tigt ihre ganz
eigenen SQL-Befehle. Davon abgesehen "f�ttern" meine Sortier-Proceduren
meist auch noch die Statuszeile mit entsprechendem Text wie "sortiert
nach Titel aufw�rts" etc. Davon abgesehen kannst du hier sinnvoll mit
Copy'n'Paste arbeiten, da sich die einzelnen Begin-End-Bl�cke innerhalb
des Case-Blocks meist sehr �hnlich sind.

Programmieren ist immer ein Aufwand. Lohnt sich aber meistens doch, wenn
man das Resultat mit dem h�ndischen Heraussuchen eines Records aus einer
ellenlangen Tabelle vergleicht.

0 new messages