![]() |
ClientDataSet und Indexdefs
Ich möchte in einer Anwendung dem Benutzer die Möglichkeit geben, die Daten eines DBGrids nach seinen Bedürfnissen zu sortieren.
Zur besseren Übersichtlichkeit soll auch über mehrere Spalten sowie auf- und absteigend sortiert werden können. Die Auswahl geschieht in einem eigenen Dialog. Da auch absteigend sortiert werden soll, fällt die Sortierung über IndexFieldNames weg. Ich habe nun folgenden Codeabschnitt realisiert:
Delphi-Quellcode:
Lasst Euch nicht von dem Namen täuschen IBQuery_Suche_Vertragsdaten ist ein TClientDataSet. Ich bin gerade dabei teile meines Programms von IBX-Komponenten auf DBX umzustellen.
procedure TDM_Datenbanken.SetSuchergebnisSortierung(
const IndexFelder: string; const Aufsteigend: boolean); var IndexName: string; begin if Aufsteigend then IndexName := 'IDX_A_' + IndexFelder else IndexName := 'IDX_D_' + IndexFelder; if IBQuery_Suche_Vertragsdaten.IndexDefs.IndexOf(IndexName) >= 0 then IBQuery_Suche_Vertragsdaten.IndexDefs.Delete(IBQuery_Suche_Vertragsdaten.IndexDefs.IndexOf(IndexName)); if Aufsteigend then IBQuery_Suche_Vertragsdaten.IndexDefs.Add(IndexName, IndexFelder, [ixCaseInsensitive]) else IBQuery_Suche_Vertragsdaten.IndexDefs.Add(IndexName, IndexFelder, [ixCaseInsensitive, ixDescending]); if IBQuery_Suche_Vertragsdaten.IndexDefs.IndexOf(IndexName) < 0 then IBQuery_Suche_Vertragsdaten.IndexDefs.Update; IBQuery_Suche_Vertragsdaten.IndexName := IndexName; end; procedure TDM_Datenbanken.SucheVertragsdatenClose; begin IBQuery_Suche_Vertragsdaten.IndexName := ''; IBQuery_Suche_Vertragsdaten.IndexDefs.Clear; IBQuery_Suche_Vertragsdaten.Close; end; Die Sortierung funktioniert grundsätzlich. Wählt man aber mehrere Spalten aus, so kommt es in der Zeile
Delphi-Quellcode:
zu einer Index existiert nicht. Exception. Wählt man nur eine Spalte aus bzw. zwei Spalten die z.B. nur sehr kurze Strings enthalten, kommt keine Fehlermeldung.
IBQuery_Suche_Vertragsdaten.IndexName := IndexName;
Ich vermute, dass der Index im Speicher noch nicht vollständig generiert wurde. Kann man das irgendwie abfragen? "IndexOf" liefert sofort nach dem "Add" die Position, obwohl er noch nicht zugewiesen werden kann. Ursprünglich wollte ich nur mit einem Index arbeiten, der modifiziert bzw. gelöscht wird. Leider funktioniert es nicht, wenn man
Delphi-Quellcode:
durchführt. Bei "Add" kommt eine Fehlermeldung, dass der Index mit besagtem Namen bereits existiert.
IndexFieldNames := '';
Delete(x); Clear; Ich habe auch versucht an verschiedenen Stellen ein Update zu integrieren. Hat aber auch nichts geholfen. In einigen Newsgroupbeiträgen wird das Update nach dem Add durchgeführt. Bei mir ging dadurch aber immer der gerade hinzugefügte Index wieder verloren. Kann mir jemand sagen, ob ich hier etwas falsch mache oder ob es eine andere Möglichkeit gibt. Ich muss auf jeden Fall mit CDS arbeiten, da die zugrundeliegende SQL-Abfrage sehr komplex sein kann und so wiederkehrende DB-Abfragen mit ORDER-BY aus Performancegründen ausscheiden. Ich arbeite mit D6 Enterprise Update Pack 2; Windows XP Prof. (alle Updates); Interbase 6.01 . Die Daten werden über eine TSQLQuery eingeladen. Gruß Markus |
Re: ClientDataSet und Indexdefs
Konnte das Problem lösen.:dancer2: Der Indexname war zu lang!
Für all diejenigen, die Interesse an der Lösung haben, hier der Quellcode. Gruß Markus
Delphi-Quellcode:
procedure TDM_Datenbanken.SetSuchergebnisSortierung(
const IndexFelder: string; const Aufsteigend: boolean); var IndexName: string; MaxIdx, i: integer; begin IBQuery_Suche_Vertragsdaten.IndexDefs.Update; { Fesstellen ob bereits ein Index mit den aktuellen Feldern existiert } for I := 0 to Pred(IBQuery_Suche_Vertragsdaten.IndexDefs.Count) do if (IBQuery_Suche_Vertragsdaten.IndexDefs.Items[I].Fields = IndexFelder) then begin if (not Aufsteigend) and (ixDescending in IBQuery_Suche_Vertragsdaten.IndexDefs.Items[i].Options) then begin { Diesen Index als aktuellen Index der Tabelle aktivieren } IBQuery_Suche_Vertragsdaten.IndexName := IBQuery_Suche_Vertragsdaten.IndexDefs.Items[i].Name; exit; end; if (Aufsteigend) and (not (ixDescending in IBQuery_Suche_Vertragsdaten.IndexDefs.Items[i].Options)) then begin { Diesen Index als aktuellen Index der Tabelle aktivieren } IBQuery_Suche_Vertragsdaten.IndexName := IBQuery_Suche_Vertragsdaten.IndexDefs.Items[i].Name; exit; end; end; { Neuen Namen finden } MaxIdx := 0; for i := 0 to Pred(IBQuery_Suche_Vertragsdaten.IndexDefs.Count) do if Copy(IBQuery_Suche_Vertragsdaten.IndexDefs.Items[i].Name, 1, 4) = 'AUT_' then MaxIdx := StrToInt(Copy(IBQuery_Suche_Vertragsdaten.IndexDefs.Items[i].Name, 5, 3)); Inc(MaxIdx); IndexName := 'AUT_' + IntToStr(MaxIdx); if Aufsteigend then IBQuery_Suche_Vertragsdaten.IndexDefs.Add(IndexName, IndexFelder, [ixCaseInsensitive]) else IBQuery_Suche_Vertragsdaten.IndexDefs.Add(IndexName, IndexFelder, [ixCaseInsensitive, ixDescending]); IBQuery_Suche_Vertragsdaten.IndexName := IndexName; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:52 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