Datenbank: Absolute Database • Version: 5.14 • Zugriff über: Table / DataSource
Indexfehler ??
Hallo,
in meinem Prog. werden im Grid Daten angezeigt, die mit onTitleClick einen Index erhalten und sortiert im Grid erscheinen.
Delphi-Quellcode:
Die neu erzeugten Indizies werden in einer Liste ‚gesammelt’.
Table.Close;
Table.Exclusive := true; Table.AddIndex(sName, sName,[]); // (IndexName, indiziertes Feld[optionen]); Table.IndexName := sName; Table.Exclusive := False; Table.Open; sIndexList.Add(sName); // neuer Index in StringListe Damit die Tabelle nicht geändert wird, werden die neu erstellten Indizies gemäß dieser Liste wieder gelöscht.
Delphi-Quellcode:
Das ist auch soweit OK.
Table.DeleteIndex(sIndexList[cnt]); // index aus table
sIndexList.Delete(cnt); // index aus stringlist Table.IndexDefs.Update; // indexdefinition aktualisieren Table.StoreDefs := False; Nun habe ich mein Prog. erweitert, die Table werden in TreeView dargestellt. Mit Click auf die entsprechende Tabelle wird die Table geöffnet, die Daten im Grid angezeigt und man kann so zwischen den Tabellen hin und her schalten. Auch OK. Aber clicke ich im Grid und erstelle so einen neuen Index zb. Name, der vor dem Tabellenwechsel wieder gelöscht wird, so erscheint bei Tabellenwechsel die Fehlermeldung Cannot find index NAME Der Tabellenwechsel: Index der aktiven Table löschen, aktive Tabelle schließen (Table.Close), neue Tabelle öffnen.
Delphi-Quellcode:
Warum wird da ein nicht mehr vorhandenr Index gesucht, wo liegt da eventuell der Fehler?
SelectTable(TreeView.Selected.Text);
Table.Close; // active Table schließen Table.TableName := TreeView.Selected.Text; // neue Tabelle Table.Open; Habe schon einige Zeit mit Fehlersuche verbracht und nichts gefunden, vielleicht hat ja von Euch eine eine hilfreiche Idee dazu. Danke Fritz aus Ahlhorn |
Re: Indexfehler ??
Hallo nochmal,
habe in der Zwischenzeit noch gesucht. Der Tabellenwechsel: Index der aktiven Table löschen, aktive Tabelle schließen (Table.Close), neue Tabelle öffnen.
Delphi-Quellcode:
Da muß doch noch ein Index der alten Tabelle sein, der in der neuen Tabelle nicht vorhanden ist.
procedure TfrmMain.TreeViewChange(Sender: TObject; Node: TTreeNode);
begin if TreeView.Selected.IsFirstNode then exit else begin SelectTable(TreeView.Selected.Text); Table.Close; // active Table schließen Table.TableName := TreeView.Selected.Text; // neue TabellenName Table.Open; <================== Hier liegt der Fehler iRecordCount.Caption := IntToStr(Table.RecordCount); // Datensätze zählen und anzeigen end; end; Wie kriege ich den da weg, was muß ich da machen? Fritz |
Re: Indexfehler ??
Zitat:
Delphi-Quellcode:
Was verbirgt sich hinter der Funktion/Prozedur SelectTable()?
procedure TfrmMain.TreeViewChange(Sender: TObject; Node: TTreeNode);
begin if TreeView.Selected.IsFirstNode then exit else begin SelectTable(TreeView.Selected.Text); Table.Close; // active Table schließen Table.IndexName := ''; // <<---hier könnte noch ein zugewiesener Index vom Vorgänger drin sein!Deswegen erstmal blank machen ;) Table.TableName := TreeView.Selected.Text; // neue TabellenName Table.Open; //--wird mit dem PrimärIndex(sofern vorhanden) geöffnet //--für die neue Tabelle sicherheitshalber mal die Indexliste aktualisieren Table.IndexDefs.Update; Table.StoreDefs := false; iRecordCount.Caption := IntToStr(Table.RecordCount); // Datensätze zählen und anzeigen end; end; |
Re: Indexfehler ??
Hallo,
ist schon spät geworden. Habe es mal so gemacht und es hat sich nur etwas verändert. Die erste Tabelle wird geöffnet, ein Index auf PLZ und Index gelöscht. Eine Andere läßt sich nun öffnen, aber kommt dann der Click für den Index kommt die Fehlermeldung: Zugriffsverletzung Ich kriegs nicht gebacken, aber nur nicht aufgeben! Zitat:
Delphi-Quellcode:
Erst mal genug für heute, morgen werde ich weitersehen.
procedure TfrmMain.SelectTable(Name: String='');
var i: Integer; begin if (name <> '') then for i:=1 to TreeView.Items.Count-1 do if AnsiUpperCase(TreeView.Items[i].Text) = AnsiUpperCase(Name) then begin TreeView.Selected := TreeView.Items[i]; Break; end; end; Fritz |
Re: Indexfehler ??
Hallo Fritz,
vom Prinzip her solltest du folgende Struktur verwenden können:
Delphi-Quellcode:
Getippt und nicht getestet.
unit DemoFrm;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, DB, ABSMain, Grids, DBGrids, ComCtrls; type TDemoForm = class(TForm) TreeView: TTreeView; DBGrid: TDBGrid; ABSDatabase: TABSDatabase; ABSTable: TABSTable; DataSource: TDataSource; procedure TreeViewChange(Sender: TObject; Node: TTreeNode); procedure DBGridTitleClick(Column: TColumn); private procedure SwitchTable(const tblName: string); procedure SwitchIndex(const idxName: string); end; var DemoForm: TDemoForm; implementation {$R *.dfm} uses StrUtils; procedure TDemoForm.SwitchIndex(const idxName: string); begin with AbsTable do if not SameText(idxName, IndexFieldNames) then begin DisableControls; try IndexFieldNames := idxName; finally EnableControls; end; end; end; procedure TDemoForm.SwitchTable(const tblName: string); begin with AbsTable do if not SameText(tblName, TableName) then begin DisableControls; try if Active then Close; SwitchIndex(''); TableName := tblName; if TableName <> '' then Open; finally EnableControls; end; end; end; procedure TDemoForm.TreeViewChange(Sender: TObject; Node: TTreeNode); begin SwitchTable(IfThen(Assigned(Node), Node.Text)); end; procedure TDemoForm.DBGridTitleClick(Column: TColumn); begin SwitchIndex(Column.FieldName); end; end. Freundliche Grüße |
Re: Indexfehler ??
Hallo marabu,
habe Deinen Text mal so übernommen um zu schauen was da passiert. Nach OpenDialog und procedure (siehe #4) erscheint in der TreeView 'Demo.Abs mit einem + davor. Mit dem ersten Click in TreeView erscheint die Fehlermeldung Table Demo.Abs not exists ABSDatabase hat den Namen Demo.abs, eine Table Demo.abs gibt es wirklich nicht. Was ist das ? Gruß Fritz |
Re: Indexfehler ??
@ marabu
Hallo Achim, habe Deinen Code versucht zu verstehen. Die mit * gezeichneten Zeilen habe ich bei 'SwitchTable' hinzu gefügt. Das ist nun OK, hat aber einen kleinen Schönheitsfehler: wenn zb. 3 Einträge in TreeView sind kann man den ersten Eintrag nicht öffnen. Clickt man den 2. oder den 3. Eintrag an, kann man danach auch den 1. öffnen. Mal sehen.Vielleicht finde ich da ja noch was.
Delphi-Quellcode:
Bei 'SwitchIndex' kann ich nur bereits vorhandene Indizies nutzen! (Aber der Tabellenwechsel ist OK.)
begin
* if TreeView.Selected.IsFirstNode then exit * else begin with Table do Clicke ich aber auf einen Titel, bei dem kein Index vorhanden ist wird das Prog mit eine Fehlermeldung beendet. Es sollte so sein: Ist ein Index vorhanden, diesen auch benutzen. Ist kein Index da, so sollte ein neuer Index für dieses Feld erstellt werden. Damit am Ende die Table nicht verändert ist muß der neu erstellte Index entweder mit dem nächsten TitleClick oder vor SwitchTable gelöscht werden. Weiß nich so recht wie ich das in SwitchTable unterbringen kann. Mal sehen. Mit den besten Grüßen aus Ahlhorn Fritz |
Re: Indexfehler ??
Ich würde die Logik umdrehen:
Delphi-Quellcode:
if not TreeView.Selected.IsFirstNode then
begin ... end; |
Re: Indexfehler ??
Hallo mkinzler,
danke für den Hinweis, aber was bringt das? Habs gemacht, sehe darin keinen Vorteil und ich muß trotzdem um den ersten Eintrag zu öffnen zuerst auf den 2. oder 3. Clicken. Danach geht alles. Vielleicht ein Tipp wie man sofort den ersten öffnen kann? Mit freundlichem Gruß Fritz |
Re: Indexfehler ??
Hallo,
du darfst Table.Refresh nicht vergessen vor dem Table.Open. Heiko |
Re: Indexfehler ??
Hallo,
die Sache mit dem in #7 genannten 'Schönheitsfehler' hat sich erledigt. Kann auch nicht nachvollziehen warum das nun so ist. Liegt auch nicht an Table.Refresh ! Bleibt 'nur' noch das Problem mit SwitchIndex wie in #7 schon beschrieben. Da komme ich einfach nicht weiter. Hoffe mal wieder auf Euere Hilfe. Übrigens: AbsoluteDatabase 5.15 ist verfügbar. Mit freundlichem Gruß Fritz |
Re: Indexfehler ??
Hallo Fritz,
ich hatte angenommen, dass beim Setzen von IndexFieldNames (anstelle von IndexName) das ständige Erzeugen und Vernichten von Index-Dateien entfallen kann. Wenn dem nicht so ist, dann muss ich die beiden Switch-Prozeduren noch etwas erweitern. Die Kunst dabei liegt darin es so zu tun, dass du den "unnötigen" Code beim Wechsel auf einen freien SQL-Server über bedingte Kompilierung abschalten kannst. Freundliche Grüße |
Re: Indexfehler ??
Hallo Achim,
habe schon in Sachen Index einige Zeit verbracht, alles vergeblich. Wie schon geschrieben: Ist ein Index vorhanden, diesen auch benutzen. Ist kein Index da, so sollte ein neuer Index für dieses Feld erstellt werden. Damit am Ende die Table nicht verändert ist müssen die neu erstellten Indizies vor oder in SwitchTable gelöscht werden. Für die Erweiterung der Proceduren wäre ich dankbar. Mit freundlichem Gruß Fritz |
Re: Indexfehler ??
Hallo schon wieder,
Neues von Fritz! Die Sache beschäftigt mich immer noch und auch mit Erfolg. Im Prinzip ist es eigentlich so geblieben. Schaut das doch bitte mal an. Wenn nicht vorhanden: Index neu
Delphi-Quellcode:
Wenn Index nicht mehr benötigt: Index erntfernen
//------------------- 2) Index nicht vorhanden
else // begin tTable.CLose; tTable.Exclusive := true; tTable.AddIndex(idxName, idxName,[]); tTable.IndexName := idxName; tTable.Exclusive := False; tTable.Open; label3.Caption := ''; label3.Caption := idxName; <- nur zur Anzeige sIndexList.Add(idxName); bIndexDelete.Enabled := True; //--internes Array mit den Indexdefinitionen aktualisieren tTable.IndexDefs.Update; //--evtl. Speichern der Definitionen verhindern tTable.StoreDefs := False; end; wird z.Zt. noch per Click gemacht
Delphi-Quellcode:
Das funktioniert auch wenn in TreeView Table gewechselt wird.
procedure TfrmMain.bIndexDeleteClick(Sender: TObject);
var cnt : integer; begin for cnt := ListBox.Count -1 downto 0 do begin tTable.DeleteIndex(sIndexList[cnt]); // index aus table sIndexList.Delete(cnt); // index aus stringlist tTable.IndexName := ''; // falls da noch was ist tTable.IndexDefs.Update; // indexdefinition aktualisieren tTable.StoreDefs := False; //speichern der definitionen verhindern bIndexDelete.Enabled := False; end; end;
Delphi-Quellcode:
Soviel dazu!
procedure TfrmMain.TreeViewChange(Sender: TObject; Node: TTreeNode);
begin if TreeView.Selected.IsFirstNode then exit else begin // angeclickte Tabelle öffnen und Daten in Grid zeigen SelectTable(TreeView.Selected.Text); // neuer TableName // DisableControls; <-[Fehler] uMain.pas(147): Undefinierter Bezeichner: try tTable.Close; // active Table schließen // <========== hier sollte die procedure Index löschen eigefügt werden tTable.IndexName := ''; tTable.TableName := TreeView.Selected.Text; // neue Tabelle tTable.Open; finally // EnableControls; <-[Fehler] uMain.pas(147): Undefinierter Bezeichner: end; Label1.Caption:=TreeView.Selected.Text; tTable.IndexDefs.Update; tTable.StoreDefs := false; // neue Tabelle öffnen iRecordCount.Caption := IntToStr(tTable.RecordCount); // Datensätze zählen und anzeigen end; end; Und hier mein Anliegen 1) DisableControls / EnableControls gibt Fehlermeldung: undefinierter Bezeichner ??? 2) Die procedure bIndexDeleteClick würde ich gerne ind der procedure TreeViewChange unterbringen. wie geht das, habs noch nie gemacht! Danke Fritz |
Re: Indexfehler ??
zu 1) DisableControls bzw EnableControls ist eine Methode von TDataSet.
Das ständige Neuzeichnen der Bildschirmnanzeige von datensensitive Steuerlemeneten (DBGrid. DBEdit, etc) bei grossen Datenmengen ist zeitaufwändig; DisbaleControls 'friert' die Anzeige ein und nach dem Aktualisieren (in deinem Fall das Wechseln der Tabelle) wird durch EnableControls die Anzeige auf den neuesten Stand gebracht. zu 2)
Delphi-Quellcode:
Ich habe die Löschroutine stark vereinfacht (wie ich es ja schon mal vorgeschlagen habe ;) )
procedure TfrmMain.TreeViewChange(Sender: TObject; Node: TTreeNode);
var cnt: Integer; begin if TreeView.Selected.IsFirstNode then exit else begin // angeclickte Tabelle öffnen und Daten in Grid zeigen SelectTable(TreeView.Selected.Text); // neuer TableName //--Anzeige im Grid 'einfrieren DBGrid1.DataSource.DataSet.DisableControls; {oder vereinfacht:} tTable.DisableControls; try tTable.Close; // active Table schließen tTable.IndexName := ''; // falls da noch was ist //--alle Indizes löschen for cnt := sIndexList.Count -1 downto 0 do tTable.DeleteIndex(sIndexList[cnt]); // index aus table sIndexList.Clear; // stringliste komplett leeren tTable.IndexDefs.Update; // indexdefinition aktualisieren tTable.StoreDefs := False; //speichern der definitionen verhindern tTable.TableName := TreeView.Selected.Text; // neue Tabelle tTable.Open; finally DBGrid1.DataSource.DataSet.EnableControls; {oder vereinfacht:} tTable.EnableControls; end; Label1.Caption:=TreeView.Selected.Text; iRecordCount.Caption := IntToStr(tTable.RecordCount); // Datensätze zählen und anzeigen end; end; |
Re: Indexfehler ??
@ raiguen,
danke für Deine Mithilfe, das hat sich aber in der Zwischenzeit erledigt. Die Lösung sieht so aus, im Prinzip wie Dein Vorschlag:
Delphi-Quellcode:
und die procedure IndexDelete:
procedure TfrmMain.TreeViewChange(Sender: TObject; Node: TTreeNode);
begin with tTable do if TreeView.Selected.IsFirstNode then exit else begin // angclickte Tabelle öffnen und Daten in Grid zeigen SelectTable(TreeView.Selected.Text); // neuer TableName DisableControls; try if Active then Close; // active Table schließen IndexDelete(sIndexList); // procedure IndexDelete TableName := TreeView.Selected.Text; // neue Tabelle If TableName <> '' then Open; finally EnableControls; end; Label1.Caption:=TreeView.Selected.Text; IndexDefs.Update; StoreDefs := false; // neue Tabelle öffnen iRecordCount.Caption := IntToStr(tTable.RecordCount); // Datensätze zählen und anzeigen end; end;
Delphi-Quellcode:
Weiter habe ich hinzugefügt:
procedure TfrmMain.IndexDelete(sIndexList: Tstringlist);
var cnt : integer; begin with tTable do for cnt := sIndexList.Count -1 downto 0 do begin //sIndexList DeleteIndex(sIndexList[cnt]); // index aus table (sIndexList[cnt]) tTable.IndexDefs.Update; // indexdefinition aktualisieren IndexFieldNames := ''; IndexName := ''; end; tTable.StoreDefs := False; //speichern der definitionen verhindern sIndexList.Clear; end;
Delphi-Quellcode:
So werden erstellte Indizies beim Beenden auch noch entfernt.
procedure TfrmMain.FormClose(Sender: TObject; var Action: TCloseAction);
begin IndexDelete(sIndexList); // procedure IndexDelete end; Ich denke das Thema ist damit beendet. Nochmal danke für die Mithilfe und noch einen schönen Abend. Fritz |
Re: Indexfehler ??
Jo, wir helfen doch gerne, vor allem dann, wenn der Hilfesuchende auch aktiv an der Lösung seines Problems mitarbeitet :-D
Bezüglich deiner IndexLösch-Prozedure darf ich zum Anschluss noch eine Änderung anbringen (ich weiss, ich bin penetrant-nervig :roll: )
Delphi-Quellcode:
Ansonsten weiterhin viel Erfolg und einen schönen Rest-(1.Advents)Abend
procedure TfrmMain.IndexDelete(sIndexList: Tstringlist);
var cnt : integer; begin with tTable do IndexName := ''; {IndexName setzen reicht aus, da IndexName und IndexFieldName sich gegenseitig ausschliessen IndexFieldNames := '';} //** diese Minimalschleife ist ausreichend, alle temp. erstellten Indizes zu löschen for cnt := sIndexList.Count -1 downto 0 do //sIndexList DeleteIndex(sIndexList[cnt]); // index aus table (sIndexList[cnt]) ***// {in einer Schleife nicht sinnvoll, da JEDESMAL die Indizes neu ausgelesen werden, aber zum Schluss auf jeden Fall} IndexDefs.Update; // indexdefinition aktualisieren //--evtl. ist das hier auch möglich, da für die aktuelle Tabelle ja nicht mehr benötigt wird //-- und die Indizes für die neue Tabelle ja neu eingelesen werden IndexDefs.Clear {bin mir z.Zt. nicht ganz sicher, ob diese MEthode vorhanden ist} StoreDefs := False; //speichern der definitionen verhindern end; sIndexList.Clear; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:49 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz