Delphi-PRAXiS
Seite 3 von 3     123   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi vorhandenen Index ermitteln (https://www.delphipraxis.net/103699-vorhandenen-index-ermitteln.html)

Fritz01 22. Nov 2007 12:39

Re: vorhandenen Index ermitteln
 
@ all,

schaut doch mal ab #15

Im ersten Teil werden Indizies benötigt und erstellt. Das ist OK!
Jeder neu erstellte Index wird in ListBox gespeichert. Auch OK
Im 2. Teil sollen die Indizies gemäß ListBox gelöscht werden.

zu #16
Die Fehlermeldung: Inkompatible Typen bezieht sich auf die Zeile
Delphi-Quellcode:
for cnt := 0 to Pred(lbIndex) do
Die Fehlermeldung: Klasse besitzt keine Standardeigenschaft bezieht sich wohl auf die [cnt] Klammern mit cnt in dieser Zeile
Delphi-Quellcode:
Table.DeleteIndex(lbIndex[cnt]);
Was ist cnt ich habe keine Ahnung, welche Klasse? In der DH habe ich nichts dazu gefunden.

Zitat:

Eine StringList recith doch, oder ?
Was ist StrinList, habe noch nichts damit gemacht. Meinst Du Memo?

Fritz

Progman 22. Nov 2007 12:52

Re: vorhandenen Index ermitteln
 
TStringList ist (grob gesagt) wie eine ListBox, nur eben unsichtbar im Speicher. Lässt sich aber ganz komfortabel handeln.
Jetzt hab ich deine Absicht erstmal geschnallt ;)
Du willst alle in der Liste befindlichen Indizes löschen.
Dazu gehst du die Liste durch mit
Delphi-Quellcode:
for cnt do 0 to lbIndex.Items.Count-1 do begin //cnt ist die Lauf-Variable vom Typ Integer
  Table.DeleteIndex(lbIndex.Items[cnt]); //das ergibt den ListBox-Eintrag, auf den cnt grad zeigt, als String,
  //sofern DeletIndex einen String übegeben haben will, ich kenne jetzt
  //die DB-spezifischen Funktionen nicht ausm Kopf
end;
Ich denke, das ist jetzt besser durchschaubar ;)

DeddyH 22. Nov 2007 12:57

Re: vorhandenen Index ermitteln
 
Lösche besser von hinten.
Delphi-Quellcode:
for cnt := lbIndex.Items.Count-1 downto 0 do begin
  Table.DeleteIndex(lbIndex.Items[cnt]);
end;

Fritz01 22. Nov 2007 19:08

Re: vorhandenen Index ermitteln
 
@ Progman
Zitat:

TStringList ist (grob gesagt) wie eine ListBox, nur eben unsichtbar im Speicher.
das hört sich gut an und wird meine nächste Aufgabe.

@ all
Soweit ist das ja eigentlich in Ordnung, aber...
Das sollte für alle Tabellen funktionieren, mit oder ohne Index und der vorhandene IndexName sollte auch keine Rolle spielen.
Ist kein Index vorhanden, so ist das super.
Ist für zB. ein Index, indiziert auf Nachname und Vorname vorhanden, so ist das auch OK. Bei entsprechendem Click wird dann ein neuer für Nachname oder auch für Vorname erstellt.
Handelt es sich aber um zB. PLZ und nur auf PLZ indiziert gibt es die Fehlermeldung: Cannot find index PLZ.
Hier ist sicher Code erforderlich. Das ist es, was dank der Forumhilfe entstanden ist.

Delphi-Quellcode:
procedure TForm1.GridTitleClick(Column: TColumn);
var
  sName : String;
  I : integer;
  bVorhanden: Boolean;
begin
  bVorhanden := False;
  sName := Column.Field.FieldName; // TitelName

  Table.IndexDefs.Update;
                                //---- 1) nach Index suchen
  for I := 0 to Table.IndexDefs.Count -1 do
   if Table.IndexDefs.Items[I].Fields = sName then
   begin
     bVorhanden := True;       //--- 2) Index vorhanden und gefunden
     break; // durchaus erlaubt, weil Forstezung der Suche nicht mehr sinnvoll
   end;

   if bVorhanden then
   begin
     Table.IndexName := sName; //vorhandener Index einsetzen auch bei geöffneter Tabelle!!!
   end
                                //---- 2) Index nicht vorhanden
   else
   begin
     Table.CLose;
     Table.Exclusive := true;
     Table.AddIndex(sName, sName,[]); // neuen Index einfügen
     Table.IndexName := sName;
     Table.Exclusive := False;
     Table.Open;
     ListBoxIndex.Items.Add(sName);  // Index in Liste schreiben
   end;
end;

procedure TForm1.bIndexDeleteClick(Sender: TObject);
var
 cnt : integer;
begin
  for cnt := ListBoxIndex.Items.Count -1 downto 0 do begin
    Table.DeleteIndex(ListBoxIndex.Items[cnt]);  // neuen Index löschen
    ListBoxIndex.Items.Delete(cnt);              // neuen Index aus Liste löschen
 end;

end;
Ich ging davon aus, daß nur der Name interessant ist. Bei PLZ ist vorhanden PLZ_Idx, erstellt würde aber IndexName = Feldname.
Vielleicht schaut da nochmal jemand drauf. Danke
Fritz

raiguen 24. Nov 2007 10:42

Re: vorhandenen Index ermitteln
 
Wann erscheint die Felhlermelung? Bei Überprüfen im GridTitleClick oder in der Löschroutine?
Wenn beim Erstellen des Indexes der Name mit PLZ angegeben wurde, dann sollte dieser auch als solcher zu finden sein :gruebel: Ein evtl. bereits vorhandender Index auf das Feld PLZ mit einem anderen Namen (hier PLZ_idx) dürfte eigentlich nicht relevant sein bzw. 'Störungen' verursachen...
Noch ein, zwei kleine Änderung[en]:
Delphi-Quellcode:
procedure TForm1.GridTitleClick(Column: TColumn);
{... vorhandener Code}
                                //---- 2) Index nicht vorhanden
   else
   begin
     Table.CLose;
     Table.Exclusive := true;
     Table.AddIndex(sName, sName,[]); // neuen Index einfügen
     Table.IndexName := sName;
     Table.Exclusive := False;
     Table.Open;
     ListBoxIndex.Items.Add(sName);  // Index in Liste schreiben
///////---hinzufügen////////
     //--internes Array mit den Indexdefinitionen aktualisieren
     Table.IndexDefs.Update;
     //--evtl. Speichern der Definitionen verhindern
     Table.StoreDefs := false;            
   end;
end;
Delphi-Quellcode:
procedure TForm1.bIndexDeleteClick(Sender: TObject);
var
cnt : integer;
begin
  for cnt := ListBoxIndex.Items.Count -1 downto 0 do
    Table.DeleteIndex(ListBoxIndex.Items[cnt]);  // neuen Index löschen
  //--gesammte Listbox auf einen Schlag Löschen
  ListBoxIndex.Items.Clear;
  //--internes Array mit den Indexdefinitionen aktualisieren
  Table.IndexDefs.Update;
  //--evtl. Speichern der Definitionen verhindern
  Table.StoreDefs := false;            
end;
Zitat:

Zitat von Delphi-OH
Hinweis: Die in IndexDefs enthaltenen Definitionen berücksichtigen nicht immer die für die Tabelle verfügbaren Indizes. Rufen Sie vor der Überprüfung von IndexDefs die Methode Update auf, um die Liste zu aktualisieren.

Also von daher machen wir das ;)

Zitat:

Zitat von Delphi-OH
Wenn FieldDefs oder IndexDefs aktualisiert oder manuell bearbeitet wird, wird StoreDefs auf True gesetzt. Setzen Sie StoreDefs auf False, um zu verhindern, dass bearbeitete (oder importierte) Definitionen gespeichert werden.

Wobei nicht eindeutig herauszulesen ist, wann und wo diese Einstellungen im DataModul oder Formular gespeichert werden :gruebel: Aber es kann nicht schaden, es trotzdem auf false zu setzen, nach dem irgendwelche Indizies erstellt/gelöscht wurden...

Fritz01 24. Nov 2007 11:48

Re: vorhandenen Index ermitteln
 
@ raiguen,
danke für Deine Antwort und die Bemühungen.
Werde mir Deine Vorschläge heute ansehen, war aber auch schon selbst tätig.
Bin ja nur hobbymäßig mit Delphi beschäftigt und kann so nur folgendes vermuten:

Delphi-Quellcode:
Table.IndexDefs.Items[I].Name = sName then

Table.IndexDefs.Items[I].Fields = sName then
.Name verweist auf den Namen der Indexdatei .Fields verweist auf die indizierten Felder

1) .Fields, ist das angeclickte Feld bereits indiziert wird wohl nach dem Namen gesucht (sName), es erscheint dann, weil nicht vorhanden, die Fehlermeldung: kann Index nicht finden.

2) .Name , ist wohl der Name der IndexDatei. Üblicher Weise wird der Name mit dem Zusatz IDX o.ä. gewählt.
Die Var "sName" ist ja nur der Feldname ohne IDX, Feldname = Index Name ist demnach als IndexName nicht vorhanden.
Die IndexDatei wird also neu erstellt.

Delphi-Quellcode:
// vorhandenen Index suchen
  Table.IndexDefs.Update;
  for I := 0 to Table.IndexDefs.Count -1 do // vorhandenen Index suchen

   if Table.IndexDefs.Items[I].Name = sName then // .Name war vorher .Fields
   begin
     bVorhanden := True;
     break; //-- durchaus erlaubt, weil Forstezung der Suche ja nicht mehr sinnvoll
   end;
Habe nun entsprechend geändert, und soweit ich das bisher getestet habe ist es OK.
Das dazu.
StringList statt ListBox wurde ja auch genannt. Habe etwas in der DH gelesen und es ist bereits in meiner Anwendung integriert.
Der Artikel war scheinbar interessant, er wurde ja sehr oft angeclickt, und ich habe viel dazu gelernt. Dank nochmal an die vielen Helfer und Euch allen ein schönes Wochenende
Fritz

Fritz01 24. Nov 2007 17:15

Re: vorhandenen Index ermitteln
 
@ raiguen,

zu #25 geht das?
Delphi-Quellcode:
procedure TForm1.bIndexDeleteClick(Sender: TObject);
var
cnt : integer;
begin
  for cnt := ListBoxIndex.Items.Count -1 downto 0 do
    Table.DeleteIndex(ListBoxIndex.Items[cnt]);  // neuen Index löschen
  //--gesammte Listbox auf einen Schlag Löschen
  ListBoxIndex.Items.Clear;            <-----------------!!!
  //--internes Array mit den Indexdefinitionen aktualisieren
  Table.IndexDefs.Update;
  //--evtl. Speichern der Definitionen verhindern
  Table.StoreDefs := false;            
end;
Es sind zB. 10 Indexe vorhanden und auch zu löschen.
In der Schleife wird der 1 Eintrag gefunden, der dazugehörige Index wird gelöscht. Beim Durchlauf der Schleife wird dann der ges. Inhalt mit ListBoxIndex.Items.Clear; gelöscht. Beim nächsten Durchlauf ist nichts mehr in der Liste, weil vollständig gelöscht.
Es verbleiben also noch 9 von den ursprüngichen 10 Indexen irgendwo im Speicher.
Sehe ich das richtig? Habe das auch nicht getestet.

Die ListBox benutze ich nicht mehr, stattdessen eine StringList und ich glaube, daß das Erstellen der Indexe deutlich schneller geht.
Ansonsten läuft das Teil super und völlig fehlerfrei.

Fritz

raiguen 25. Nov 2007 10:39

Re: vorhandenen Index ermitteln
 
Zitat:

Zitat von Fritz01
...Sehe ich das richtig? ....

Nein, da hast du einen Verständnisfehler: zuerst wird die Schleife durchlaufen, danach werden die Einträge in der ListBox (oder StringList) mit einem Schlag gelöscht.

Zitat:

Zitat von Fritz01
...Ansonsten läuft das Teil super und völlig fehlerfrei. ...

und wie ist das mit dem nicht gefundenen Index für PLZ? (siehe #24)
Das hier
Delphi-Quellcode:
if Table.IndexDefs.Items[I].Fields = sName
'ermittelt' den ersten Index, in dem das Feld sName vorhanden ist (in deinem Beispiel wäre das PLZ_idx) und somit ist die Bedingung wahr. Allerdings versuchst du dann die Tabelle auf den Index mit dem Feldnamen zu indizieren...und das kann ja nicht funktionieren ;)
Aber so:
Delphi-Quellcode:
procedure TForm1.GridTitleClick(Column: TColumn);
{...vorhandener Code}
   if bVorhanden then
   begin
     Table.IndexName := Table.IndexDefs.Items[I].Name;
   end
{...}
end;
Was bewirkt das? ein Index mit dem Feld PLZ wurde gefunden und dessen Name (hier PLZ_idx) wird nun verwendet, um die Tabelle hierauf zu indizieren..

Fritz01 25. Nov 2007 12:45

Re: vorhandenen Index ermitteln
 
@ raiguen,

ja, habe das auch getestet, ist OK mit der Schleife und den ges. Inhalt löschen.

Mit Click auf den Grid Titelnamen, das ist ja auch der Feldname meiner Datentabelle, mache ich diesen Namen auch zum Namen der IndexDatei.
Nun wird dieses Feld indiziert und erhält den Feldnamen auch als IndexNamen, dh. zB. FeldName=PLZ, IndexName=PLZ, indiziertes Feld=PLZ
Habe nochmal . Name gegen .Fields vertauscht und schon ist der Fehler wieder da. Das macht keinen Fehler mehr. Schau doch nochmal nach #26
Zitat:

.Name verweist auf den Namen der Indexdatei .Fields verweist auf die indizierten Felder
Es funktioniert mit .Name, das war da wohl ein Denkfehler meinerseits.
Noch einen schönen Sonntag
Fritz

raiguen 25. Nov 2007 13:30

Re: vorhandenen Index ermitteln
 
Zitat:

Zitat von Fritz01
Es funktioniert mit .Name, das war da wohl ein Denkfehler meinerseits.

Ähm, andererseits auch ein Denkfehler bei mir -> suche/finde alle Indizies, in denen das Feld sName vorhanden ist...


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:10 Uhr.
Seite 3 von 3     123   

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