Announcement

Collapse
No announcement yet.

ClientDataSet und Indexdefs

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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.<BR>
    Zur besseren Übersichtlichkeit soll auch über mehrere Spalten sowie auf- und absteigend sortiert werden können. Die Auswahl geschieht in einem eigenen Dialog.<BR>
    Da auch absteigend sortiert werden soll, fällt die Sortierung über IndexFieldNames weg.<P>
    Ich habe nun folgenden Codeabschnitt realisiert:<BR>
    <PRE>
    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(Inde xName) >= 0 then
    IBQuery_Suche_Vertragsdaten.IndexDefs.Delete(IBQue ry_Suche_Vertragsdaten.IndexDefs.IndexOf(IndexName ));
    if Aufsteigend then
    IBQuery_Suche_Vertragsdaten.IndexDefs.Add(IndexNam e, IndexFelder, [ixCaseInsensitive])
    else
    IBQuery_Suche_Vertragsdaten.IndexDefs.Add(IndexNam e, IndexFelder, [ixCaseInsensitive,
    ixDescending]);
    if IBQuery_Suche_Vertragsdaten.IndexDefs.IndexOf(Inde xName) < 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;
    </PRE><P>
    Lasst Euch nicht von dem Namen täuschen <I>IBQuery_Suche_Vertragsdaten</I> ist ein TClientDataSet. Ich bin gerade dabei teile meines Programms von IBX-Komponenten auf DBX umzustellen.<P>
    Die Sortierung funktioniert grundsätzlich. Wählt man aber mehrere Spalten aus, so kommt es in der Zeile<PRE> IBQuery_Suche_Vertragsdaten.IndexName := IndexName;</PRE> zu einer <I>Index existiert nicht.</I> Exception. Wählt man nur eine Spalte aus bzw. zwei Spalten die z.B. nur sehr kurze Strings enthalten, kommt keine Fehlermeldung.<BR>
    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.<P>
    Ursprünglich wollte ich nur mit einem Index arbeiten, der modifiziert bzw. gelöscht wird.<BR>
    Leider funktioniert es nicht, wenn man
    <PRE>
    IndexFieldNames := '';
    Delete(x);
    Clear;
    </PRE>
    durchführt. Bei "Add" kommt eine Fehlermeldung, dass der Index mit besagtem Namen bereits existiert.<BR>
    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.<P>
    Kann mir jemand sagen, ob ich hier etwas falsch mache oder ob es eine andere Möglichkeit gibt.<BR>
    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.<P>
    Ich arbeite mit D6 Enterprise Update Pack 2; Windows XP Prof. (alle Updates); Interbase 6.01 . Die Daten werden über eine TSQLQuery eingeladen.<P>
    Gruß Markus

  • #2
    Hast du mal geschaut wielang die Indexnamen sein dürfen?<br>

    probiere mal a für Feld1 b für feld2 etc im Indexnamen <br>

    oder schaue mit dem Debugger nach dem erzeugen des Index den Indexnamen an<br>
    MfG Andrea

    Comment


    • #3
      Indizes prüfen:<br>
      Table1.Active := False;<br>

      Table1.Exclusive := True;<br>

      { Aktuell verfügbare Indizes abrufen }<br>

      Table1.IndexDefs.Update;<br>
      { Ermitteln, welcher Index "CustNo" und "OrderNo" kombiniert }<br>
      for I := 0 to Table1.IndexDefs.Count - 1 do<br>
      if Table1.IndexDefs.Items[I].Fields = 'CustNo;OrderNo' then<br>
      { Diesen Index als aktuellen Index der Tabelle aktivieren }<br>
      Table1.IndexName := Table1.IndexDefs.Items[I].Name;<br>
      Table1.Exclusive := False;<br>

      Table1.Active := True;<br>
      MfG Andrea

      Comment


      • #4
        Hallo Andreas,<BR>
        <BR>
        Danke für Deinen Tipp! Es lag an den langen Namen.<BR>
        Für all diejenigen, die Interesse an der Lösung haben, hier der Quellcode.<BR>
        <BR>
        Gruß Markus
        <PRE>
        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.IndexDef s.Items[i].Name, 5, 3));
        Inc(MaxIdx);
        IndexName := 'AUT_' + IntToStr(MaxIdx);
        if Aufsteigend then
        IBQuery_Suche_Vertragsdaten.IndexDefs.Add(IndexNam e, IndexFelder, [ixCaseInsensitive])
        else
        IBQuery_Suche_Vertragsdaten.IndexDefs.Add(IndexNam e, IndexFelder, [ixCaseInsensitive,
        ixDescending]);
        IBQuery_Suche_Vertragsdaten.IndexName := IndexName;
        end;
        </PRE&gt

        Comment

        Working...
        X