Delphi-PRAXiS

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 20. Nov 2007 12:10

Datenbank: Absolute Database • Version: 5.14 • Zugriff über: ABSTable, DataSource

vorhandenen Index ermitteln
 
Hallo,
suche nach einer Möglichkeit, während der Laufzeit vorhandene Indexe zu ermitteln (IndexDefs) auslesen. Dieser Index soll dann in Table.IndexName eingesetzt werden.
Ist kein Index vorhanden so wird mit AddIndex... ein neuer Index erstellt und dort eingesetzt.
Hat die DatenTabelle keinen Index, so ist das OK. Index wird erstellt und die Daten erscheinen sortiert. Mein Problem ist es, einen vorhandenen Index zu ermitteln.
Mit Query sicher kein Problem, muß aber Table sein.
Hoffe auf entsprechende Hinweise.
Fritz

hoika 20. Nov 2007 12:25

Re: vorhandenen Index ermitteln
 
Hallo,

wo ist das Problem ?

http://www.componentace.com/help/abs..._indexdefs.htm

also

ABSTable.Update

und dann per Schleife (IndexDefs ist ja ein array) durdchsuchen.
Zeig mal deinen bisherigen Code.


Heiko

Fritz01 20. Nov 2007 14:25

Re: vorhandenen Index ermitteln
 
@hoika,
danke für die Antwort. Der Link hat mir nicht wirklich weiter geholfen.
Beim bisherigen Code gibts ja noch nicht viel zu sehen.

Delphi-Quellcode:
procedure TForm1.GridTitleClick(Column: TColumn);
var
 sName : String;
 begin
  sName := Column.Field.FieldName; // GridTitleName
  Label1.Caption := sName;
// vorhandenen Index suchen

// if {index für das Feld vorhanden} then
// begin
//     Label1.Caption := 'Index vorhanden';
//     Table.IndexFieldNames := //vorhandener Index;
// end
// else {Index nicht vorhanden} then
// begin
//   Index erstellen
     Table.AddIndex(sName, sName, []);
     Table.IndexFieldNames := sName;
// end;

// hier alle neu erstellten indexe löschen

 end;
das funktioniert, solange keine Indexe vorhanden sind. Dann kommt das Problem!
Sollte ich eine kl. Demo anhängen?
Fritz

hoika 20. Nov 2007 14:53

Re: vorhandenen Index ermitteln
 
Hallo,

ich benutze deine DB nicht.

Delphi-Quellcode:
var
  IndexDef : TIndexDef;
  iIndexDef : Integer;


bIndexExists:= False;

Table.Update;

//Table.IndexDefs ist ein array von Records,

for i:= Low(Table.IndexDefs) to High(Table.IndexDefs) do
begin
  IndexDef := Table.IndexDefs[iIndexDefs];
  if CompareText(IndexDef.Name,DeinGesuchterIndwxName)=0 then
  begin
    bIndexExists:= True;
    break;
  end;
end;
das ganze in die Funktion

function IndexExists(theTable: TABSTabl; const theIndexName: String: Boolean;

kannst du wohl selber machen.

Ahja, nimm IndexName statt IndexFieldName, ist einfacher.


Heiko

Fritz01 20. Nov 2007 17:22

Re: vorhandenen Index ermitteln
 
Hallo hoika,
erstmal danke. Habs gleich testen wollen, aber gleich in der ersten Zeile
Delphi-Quellcode:
function IndexExists(theTable: TABSTabl; const theIndexName: String: Boolean;
gibt es schon Fehlermeldungen.

In dieser Zeile, sehe ich das richtig, muß man da einen Indexnamen vorgeben?

Delphi-Quellcode:
if CompareText(IndexDef.Name,DeinGesuchterIndwxName)=0 then
besser wäre, den vorhandenen Index für das Feld (ganz gleich welcher Name) auslesen und dann bei Table.IndexName eintragen.
Am Ende sollte das unabhängig von den Datentabellen und Feldnamen funktionieren.
Schau Dir das doch bitte nochmal an.
Gruß aus Ahlhorn
Fritz

hoika 20. Nov 2007 18:25

Re: vorhandenen Index ermitteln
 
Hallo,

> erstmal danke. Habs gleich testen wollen, aber gleich in der ersten Zeile
> Delphi-Quellcode: markieren
> function IndexExists(theTable: TABSTabl; const theIndexName: String: Boolean;

> gibt es schon Fehlermeldungen.

welche
nun TABSTabl muss heissen TABSTable

> In dieser Zeile, sehe ich das richtig, muß man da einen Indexnamen vorgeben?

Jepp, da du den Index erzeugst, warum umständlich,
der Name heisst z.B. idx_FeldName
also bei Name idx_Name


> besser wäre, den vorhandenen Index für das Feld (ganz gleich welcher Name) auslesen und dann bei
> Table.IndexName eintragen.

Warum ?

> Am Ende sollte das unabhängig von den Datentabellen und Feldnamen funktionieren.
> Schau Dir das doch bitte nochmal an.

Nuja, dann viel Spass beim Basteln.
Ich habe das IndexField.Name aus der Bde-Hilfe für TTable geholt,
dass soll ja kompatibel sein.

Suche mal nach TIndexDef (ohne das s)

Dort gibt es ein property Fields

Du musst beachten, dass es auch einen zusammengestezten Index geben kann.

Bsp.
Tabelle Person: Name,Vorname
Index idx_FullName -> Fields für Name und Vorname Name;Vorname


wenn es keine zusammengesetzten Indizes gibt,
kannst du über

Delphi-Quellcode:
if Pos(theFieldName, IndexField.Fields)=1
rausbekommen, ob dein Feld (theFieldName) im Index drinsteht.


Heiko

Fritz01 20. Nov 2007 18:42

Re: vorhandenen Index ermitteln
 
Hallo hoika,
danke für die schnelle Antwort.
Das muß ich erst mal verdauen, werde mich gleich dransetzen. Mal sehen was ich davon machen kann, der Abend ist noch lang.
Melde mich dann wieder.
Fritz

hoika 21. Nov 2007 06:23

Re: vorhandenen Index ermitteln
 
Hallo,

übrigens habe ich das alles über die normale Delphi-Hilfe
herausbekommen.
Absolute DB ist ja als BDE-Ersatz gedacht,
d.h. die meisten TTable-Methoden / - Properties sind auch vorhanden.


Heiko

Fritz01 21. Nov 2007 08:55

Re: vorhandenen Index ermitteln
 
Hallo,
habe gestern noch lange gelesen und gebastelt mit dem Ergennis:

Delphi-Quellcode:
procedure TForm1.GridTitleClick(Column: TColumn);
var
  sName : String;
  I : integer;
 begin
  sName := Column.Field.FieldName; // Feldname
  // vorhandenen Index suchen
  Table.Active := False;
  Table.Exclusive := True;
  Table.IndexDefs.Update;
//------------------- 1) Index für dieses Feld vorhanden
  for I := 0 to Table.IndexDefs.Count -1 do  // vorhandenen Index suchen

   if Table.IndexDefs.Items[I].Fields = sName then
   begin
     Table.IndexName := sName;          //vorhandener Index einsetzen;
     Table.Exclusive := False;
     Table.Open;
     Label1.Caption:= '';
     Label2.Caption:= '';
     Label1.Caption := 'Index vorhanden';
   end
//------------------- 2) Index nicht vorhanden
   else              //
   begin
     Label1.Caption:= '';
     Label2.Caption:= '';
     Label1.Caption:='Index nicht vorhanden';
     Label2.Caption:='Index erstellen';

//     Table.AddIndex(sName, sName,[]);  // <--
//     Table.IndexName := sName;         // <--

     Table.Exclusive := False;
     Table.Open;
   end;
 end;
end.
Das funktioniert aber nur teilweise, ich weiß nicht weiter!

Da steckt noch ein Fehler drin, den ich aber nicht sehen kann.
1. Ist in der Tabelle ein Index vorhanden, so dürfen die Zeilen <-- nicht aktiv sein
2. Ist in der Tabelle kein Index vorhanden und die Zeilen <-- sind aktiv, so wird ein Index erstellt, eingesetzt.
Die Label sind nur zur Kontrolle. If else end wird ignoriert, auch wenn Index vorhanden geht es immer in Teil 2) da muß wohl der Fehler sein!!??

Fritz

raiguen 21. Nov 2007 09:32

Re: vorhandenen Index ermitteln
 
Moin :)
Bei ABSTable kann der Index für ein Feld auch der Methode FindIndexForFields gefunden/gesucht werden:
Delphi-Quellcode:
    ABSTable1.IndexDefs.Update;
    //--alle vorhandenen Index auflisten
    ABSTable1.IndexDefs.GetItemNames(Combobox1.Items);
    try
      ABSTable1.IndexName := ABSTable1.IndexDefs.FindIndexForFields(FeldName).Name;
      //--oder
      ABSTable1.IndexFieldNames := ABSTable1.IndexDefs.FindIndexForFields(FeldName).Fields;
    except
      // Function zum Erstellen des Index aufrufen;
      p_IndexErstellen(ABSTable1, FeldName);
    end;
    ....

p_IndexErstellen(const Tabelle: TABSTable; const FeldNAme: String);
begin
  Tabelle.AddIndex('idx_'+FeldName, FeldName, []);
  //--Updaten, damit beim nächsten Überprüfen der neue Index gefunden wird
  Tabelle.IndexDefs.Update;
  Tabelle.IndexNAme := 'idx_'+FeldName;
end;
...
Der try---except-Block muss sein, weil sonst die ABS-DB bei nicht vorhandenem/gefundenen Index eine Fehlermeldung auf das Formular setzt.

[EDIT] zu #9
Diese Art der Schleife ist nicht unbedingt praktikabel - weil:
selbst bei passendem/gefundenem Index werden die weiteren Einträge in der IndexDef durchsucht - und es dürfte dann klar sein, dass dann nix (mehr) gefunden wird und der Index (zum wiederholten) Mal erstellt wird! Das dürfte mit sicherheit ne Fehlermeldung produzieren!
Besser wäre dann so:
Delphi-Quellcode:
procedure TForm1.GridTitleClick(Column: TColumn);
var
  sName : String;
  I : integer;
  bVorhanden: Boolean;
begin
  bVorhanden := false;
  sName := Column.Field.FieldName; // Feldname
  // vorhandenen Index suchen
  Table.IndexDefs.Update;
  for I := 0 to Table.IndexDefs.Count -1 do  // vorhandenen Index suchen
    if Table.IndexDefs.Items[I].Fields = sName then
      begin
        bVorhanden := True;
        break; //-- durchaus erlaubt, weil Forstezung der Suche ja nicht mehr sinnvoll *gg*
    end;

   if bVorhanden then
     begin
       Table.IndexName := sName;          //vorhandener Index einsetzen geht auch bei geöffneter Tabelle!!!
      end
     //------------------- 2) Index nicht vorhanden
     else              //
       begin
         Table.CLose;
         Table.Exclusive := true;
         Table.AddIndex(sName, sName,[]);  // <--
         Table.IndexName := sName;         // <--
         Table.Exclusive := False;
         Table.Open;
   end;
end;
[/EDIT]

Fritz01 21. Nov 2007 17:15

Re: vorhandenen Index ermitteln
 
Hallo,
an dieser Stelle erst einmal Dank an Alle die bei der Problemlösung behilflich waren.

@raiguen,
...Schleife nicht praktikabel, hat ja auch nicht funktioniert und die Fehlermeldung gab es auch noch dazu.
Habe nun den Code entsprechend geändert bzw. ergänzt und siehe da es funktioniert!!
Ganz so weit habe ich doch nicht daneben gelegen, und ich denke das ich noch im lernfähigen Alter bin!
Am Ende wäre noch gut, wenn die neu erzeugten Indexe gelöscht würden. Entweder nur temporär erstellen oder mit Form onClose löschen, will mal sehen vielleicht gibt es ja dazu noch einen Tipp.
Nochmal danke für die Hilfe und einen schönen Abend.
Mit den besten Grüßen aus Ahlhorn
Fritz

DeddyH 21. Nov 2007 17:37

Re: vorhandenen Index ermitteln
 
Hallo Fritz, ich frage mich die ganze Zeit, wozu Du unbedingt temporäre Indizes erstellen möchtest. :gruebel:

Fritz01 21. Nov 2007 18:12

Re: vorhandenen Index ermitteln
 
Hallo DeddyH,
temporär nicht unbedingt! Nur, wie schon geschrieben, sollten die neu erstellten Indizies am Ende nicht mehr vorhanden sein. Mit diesem Teil kann ich mir dann außerhalb meiner Anwendung auf jedes Feld einen Index setzen, ohne die eigentliche Tabelle zu verändern.
Damit ist dann die Suche nach irgendwelchen Daten deutlich vereinfacht. Habe schon oft genug in einer unsortierten Tabelle gesucht. Die hat zwar nur ca. 3500 Datensäte, aber durchsuch die mal.
So kann ich einzelne Felder, an die ich sonst nicht rankomme, direkt im Grid verädern. Das möchte ich, wenn es denn richtig fertig ist, in ein anderes Programm integrieren.
Schönen Abend noch
Fritz

DeddyH 21. Nov 2007 18:21

Re: vorhandenen Index ermitteln
 
Ja OK, in einer sortierten (oder besser indizierten) Tabelle sucht es sich schneller. Allerdings muss der Index aber auch erstmal erstellt werden, und das dauert ja auch seine Zeit. Ich weiß nicht, wie das bei ABS DB ist, aber ich denke, der Geschwindigkeitsvorteil wird dadurch wieder zunichte gemacht.

raiguen 21. Nov 2007 23:12

Re: vorhandenen Index ermitteln
 
Zitat:

Zitat von Fritz01
wenn die neu erzeugten Indexe gelöscht würden. ...

Zitat:

Zitat von Absolute Database Manual
Methode(n) von TABSTable:
procedure DeleteAllIndexes->Löscht ALLE Indexe der Tabelle
procedure DeleteIndex(const Name: String); -> Löscht NUR den Index mit dem übergegeben Namen!

1.Methode empfiehlt sich halt für die neu erstellten ('temporären') Inizies. Tipp: alle Namen der neu erstellten Indizes in einem Array oder StringList merken und beim Onclose anhand dieser Lise die Indizes löschen
Delphi-Quellcode:
  for cnt := 0 to Pred(IndexListe) do
    Tabelle.DeleteIndex(IndexListe[cnt]);
@DeddyH: Das ABS-Manual verweist (gerade bei SQL-STatements) auf die Möglichkeit, zur Beschleunigung von Such-/Sortiervorgängen zusätzliche Indizies auf die betreffenden Spalten zu setzen. Okay, bei GROSSEN TAbellen kann das natürlich etwas dauern...

Fritz01 22. Nov 2007 10:07

Re: vorhandenen Index ermitteln
 
@ raiguen,
danke, habs gleich probiert.

DeleteAllIndexes ist ja eine sehr radikale Sache. Alles weg.
Da ist für meine Anwendung die andere Möglichkeit DeleteIndex(const Name: String); optimal.
Da benutze ich eine Listbox und merke mir dort die neuen Indizies.
Delphi-Quellcode:
lbIndex.Items.Add(sName);
Zunächst habe ich die Procedure auf einen Button onClick gelegt, aber...

Delphi-Quellcode:
procedure TForm1.bIndexDeleteClick(Sender: TObject);
var
cnt : integer; // <-- sollte doch richtig sein oder??
begin
  for cnt := 0 to Pred(lbIndex) do
    Table.DeleteIndex(lbIndex[cnt]);
end;
Fehlermeldung beim compiliern: Inkompatible Typen und Klasse besitzt keine Standardeigenschaft.
Hilfe bitte nochmal erforderlich.
Fritz

Progman 22. Nov 2007 10:21

Re: vorhandenen Index ermitteln
 
Delphi-Quellcode:
    Table.DeleteIndex(lbIndex.Items[cnt]);
vielleicht?

Fritz01 22. Nov 2007 11:00

Re: vorhandenen Index ermitteln
 
Hallo Progman,
danke.
Nein, der Fehler muß hier liegen
Delphi-Quellcode:
for cnt := 0 to Pred(lbIndex) do
Die Zeile ist rot hinterlegt und der Cursor blinkt hinter ')' dieser Klammer.
Fritz

hoika 22. Nov 2007 11:03

Re: vorhandenen Index ermitteln
 
Halo,

was ist lbIndex ?
Eine Form-Variable ?
Wozu ?

Delphi-Quellcode:
for i:= 0 to ListBox1.Items.Count-1
Ausserdem wozu eine ListBox ?
Eine StringList recith doch, oder ?


Ich würde mal die pas-Datei mit dem Editor öffnen (Delphi zu).
Es kann sein, dass durch ein Paste falsche Zeilenumbrüche
in der Pas stehen, erkennbar durch schwarze Blöcke.


Heiko

Progman 22. Nov 2007 11:17

Re: vorhandenen Index ermitteln
 
Delphi-Quellcode:
for cnt := 0 to lbIndex.ItemsCount -1 do
(ich nehme mal an, lbIndex ist eine ListBox) ;)
Und wenn es nur darum geht, die Listbox zu löschen, einfach lbIndex.items.Clear.
Ein for-Schleife zum Löschen geht meist schief, weil sich ja die Anzahl nach Löschen eines Eintrags geändert hat, aber for ganz stur seine am Anfang ermittelt Durchlaufzahl machen will. Da nimmt man
Delphi-Quellcode:
while lbIndex.count > 0 do lbIndex.Delete(0);

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:07 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