![]() |
Datenbank: Access 2000 • Zugriff über: ADOConnection
Treeviewzugriff: Neuen Datensatz erstellen im Treeview
Hallo,
ich habe einen Treeview der super funktioniert erstellt. Icons funktionieren (selected) auch und es klappt auch das Einlesen der Master-Table in den Baum. Felder: ID, ParentID, FolderName Ich will jetzt eine Datei anlegen. Das klappt auch im ensprechenden Unterverzeichniss. Nur welche Werte muss ich der ADOTable in die Felder (ItemID, ParentID, ItemName, memFeld) übergeben und wie lese ich die Daten in den Child-Knoten wieder zurück? Konkret: ParentID= Index des Knoten ItemID=Autowert ItemName=DateiName memFeld=(Inhalt der Datei als XML-File) Ich muss irgendwie den Index des Elternknoten ermitteln, als ParentID für die Client-Table speichern und dann eine Prozedur finden um die Items(Dateien) wieder in den Master-Knoten einzulesen. :gruebel: Schon mal Danke für die Hilfe. Gruß Ingo |
Re: Treeviewzugriff: Neuen Datensatz erstellen im Treeview
Hier mal ein Stück vom Code...
Delphi-Quellcode:
... type TMyRecords = Record FolderID : Integer; ParentID : Integer; FolderName : String; ItemName : String; end; ... procedure TfrmMainProg.TreeViewInit; procedure MoveToParentNode(TheNode: TTreeNode); var x : Integer; begin for x := 0 to TreeView1.Items.Count-1 do begin if Assigned(TreeView1.Items[x].Data) then begin if PView(TreeView1.Items[x].Data).FolderID = PView(TheNode.Data).ParentID then begin TheNode.MoveTo(TreeView1.Items[x], naAddChild); Break; end; end; end; end; var Root,AktNode : TTreeNode; i : Integer; begin ADOTable1.First; TreeView1.Items.BeginUpdate; Root := TTreeNode.Create(TreeView1.Items); Root.Text := 'Root Dir'; Root.ImageIndex := IMG_NODE_ROOT; //Root.Data := nil; While NOT ADOTable1.eof do begin AktNode := TTreeNode.Create(TreeView1.Items); AktNode.Data := new(PView); PView(AktNode.Data).FolderID := ADOTable1.FieldByName('ID').AsInteger; PView(AktNode.Data).ParentID := ADOTable1.FieldByName('ParentID').AsInteger; PView(AktNode.Data).FolderName := ADOTable1.FieldByName('FolderName').AsString; PView(AktNode.Data).ItemName := tblItems.FieldByName('ItemName').AsString; /// Folder einlesen ... with TreeView1.Items.Add(AktNode, PView(AktNode.Data).FolderName) do begin Data:=AktNode.Data; ImageIndex := IMG_NODE_FOLDER_CLOSED; SelectedIndex := IMG_NODE_FOLDER_OPEN; end; { /// Das hier funzt irgendwie nicht, ///Files einlesen with TreeView1.Items.AddChild(AktNode, PView(AktNode.Data).ItemName) do begin Data:=AktNode.Data; ImageIndex := IMG_NODE_FILE_CLOSED; SelectedIndex := IMG_NODE_FILE_OPEN; end; tblItems.Next; } ADOTable1.Next; end; for i := 0 to TreeView1.Items.Count -1 do begin if Assigned(TreeView1.Items[i].Data) then begin if PView(TreeView1.Items[i].Data).ParentID <> 0 then MoveToParentNode(TreeView1.Items[i]); end; end; TreeView1.FullCollapse; TreeView1.Items.EndUpdate; end; Und die Procedure um eine neue Datei anzulegen und in die Datenbank zu schreiben lautet:
Delphi-Quellcode:
Woher nehme ich den Wert für iFileID (Das Node, das ich gerade angelegt habe)? Welchen Wert also Index?
procedure TDataModule1.InsertFile (sFile :string; iFileID :integer);
begin With ADOQuery1 do begin Insert; FieldByName('FolderName').AsString := sFile; FieldByName('ParentID').AsInteger := iFileID; //FieldByName('memFeld').xxxxxxxx??? ///hier die xml-Datei als Stream??? :wall: Post; end; end; |
Re: Treeviewzugriff: Neuen Datensatz erstellen im Treeview
Hallo Ingo,
unabhängig von deinen anderen Problemen - du produzierst jede Menge Speicherlöcher, wenn du mit TTreeNode.Create() arbeitest. Lies mal hier: ![]() Grüße vom marabu |
Re: Treeviewzugriff: Neuen Datensatz erstellen im Treeview
Ja, die Knoten werden doch korrekt angefügt.
Delphi-Quellcode:
Klicke ich auf das Folder-Image öffnet es sich.
/// Folder einlesen ...
with TreeView1.Items.Add(AktNode, PView(AktNode.Data).FolderName) do begin Data:=AktNode.Data; ImageIndex := IMG_NODE_FOLDER_CLOSED; SelectedIndex := IMG_NODE_FOLDER_OPEN; end; Vielleicht anders initalisieren? |
Re: Treeviewzugriff: Neuen Datensatz erstellen im Treeview
Mein Hinweis bezieht sich auf diese Stelle in deinem Code:
Delphi-Quellcode:
Der von dir an dieser Stelle erzeugte Knoten AktNode verschwindet in den Untiefen des Speichermanagements. Mit dem Link wollte ich dir die Augen öffnen.
...
while not ADOTable1.Eof do begin AktNode := TTreeNode.Create(TreeView1.Items); ... marabu PS: Du möchtest XML-Dokumente aus einem Dateisystem in einer Access-Datenbank verwalten - verstehe ich das richtig? |
Re: Treeviewzugriff: Neuen Datensatz erstellen im Treeview
Zitat:
Ich will die Reports von FastReport (die ähnlich einem Text/bzw. XML-Dokument sind) in einem BLOB-Feld meiner ACCESS-Datenbank ablegen. Das müsste eigentlich sehr gut gehen, da es sich nur um Text-Dokumente handelt.
Delphi-Quellcode:
Vielleicht so.
ms:=TMemoryStream.Create;
try Report.SaveToStream(ms); ms.Position:=0; Conn.Connected:=true; Qry.SQL.Text:=Format('SELECT FROM WHERE', []); Qry.Open; try BlobField:=TBlobField(Qry.Fields[xxx]); if Qry.RecordCount=0 then Qry.Append else Qry.Edit; BlobField.LoadFromStream(ms); Qry.Post; finally Qry.Close; Conn.Connected:=false; end; finally if ms<>nil then ms.Free; if Qry.Active then Qry.Close; if Conn.Connected then Conn.Connected:=false; end; Aber dazu muss ich erstmal die Reports in der Client-Tabelle vernüftig mit meinem Folder im Treeview verknüpfen. Und das klappt noch nicht. Bzw. schaffe ich es nicht die ID des TreeView dem entsprechendem Folder beim Speichern zuzuordnen. Das Laden in den Tree klappt dann ganz gut wieder, wenn ich die Werte von Hand in die Tabelle eintrage. Gruß Ingo |
Re: Treeviewzugriff: Neuen Datensatz erstellen im Treeview
Verständnisfragen:
Die Knoten deines Baumes tragen die Namen von Ordnern im Dateisystem? Die Ordnung in deinem Baum ist alphabetisch? ID ist automatisch erzeugter Primärschlüssel deiner Tabelle? PARENTID ist ein Fremdschlüssel auf die gleiche (selbstrekursive) Tabelle? Müssen nicht mehrere XML-Dateien mit einem Knoten / Folder verknüpft werden? marabu |
Re: Treeviewzugriff: Neuen Datensatz erstellen im Treeview
Nein es handelt sich lediglich um ein "virtuelles Dateisystem".
Der Anwender kann Ordner anlegen, Unterordne, Unter-unter-Ordner usw. Dort speichert er dann den Report in einem Memofeld. (das habe ich im Code noch nicht implementiert). SELECT [ID], [ParentID], [FolderName], [Report] FROM DBTree; Report ist da MEMO-Feld, wo der FR abgelegt werden soll. Nur weiss ich nicht wie ich der Tabelle dbTree den Speicherort des Reports im Tree (Hier: ParentID) übergeben soll. Index.selected ?? Irgendwie. Aber das geht nicht. Pseudo-Code
Delphi-Quellcode:
Ich weiss, klingt kompliziert. Ist aber eine gute Idee. Besser, als das der Anwedner selbst die Festplatte nach den Reports durchsuchen muss.
dmReport.DataModule1.InsertFile(sFolderName, TreeView1.Selected.SelectedIndex+1, TextAlsMemo);
Gruß Ingo |
Re: Treeviewzugriff: Neuen Datensatz erstellen im Treeview
Dein virtuelles Filesystem heißt bei mir Gliederung. Die anderen Fragen hast du noch nicht beantwortet. Üblich ist eine selbstrekursive Tabelle für die Gliederung (Outline). Dazu würde ich dann eine Tabelle Reports verwenden, in der jedem (leaf-)node beliebig viele Reports zugeordnet werden können.
Der folgende Code zeigt dir sinngemäß das rekursive Aufbauen einer Gliederung aus einer Tabelle:
Delphi-Quellcode:
Jetzt wäre interessant zu wissen, ob du deine Reports als Unterknoten im Baum visualisieren willst, oder lieber bei einer Knotenart (folder) bleibst und die reports in einer ListView anzeigst (explorer style - mein Favorit).
const
SEL_NODES = 'select id, folder, outline_id ' + 'from outline ' + 'order by outline_id, folder ' ; SEL_REPORT = 'select report from reports ' + 'where outline_id = %d'; function TMainForm.TreeNodes: TTreeNodes; begin Result := TreeView.Items; end; procedure TMainForm.LoadNodes(nParent: TTreeNode; iParent: integer; recursive: boolean = true); var i, id: integer; folder: string; bm: TBookmark; n: TTreeNode; begin with QOutline do begin if Locate('outline_id', iParent, []) then while FieldValues['outline_id'].AsInteger = iParent do begin id := FieldValues['id'].AsInteger; n := TreeNodes.AddChildObject(nParent, folder, Pointer(id)); if recursive then begin bm := GetBookmark; LoadNodes(n, id, recursive); GotoBookmark(bm); FreeBookmark(bm); end; Next; end; end; end; procedure TMainForm.miLoadClick(Sender: TObject); begin // QOutline.SQL.Text := SEL_NODES; // QOutline.Open; LoadNodes(nil, 0); // QOutline.Close; end; marabu |
Re: Treeviewzugriff: Neuen Datensatz erstellen im Treeview
Ja, richtig. Soll in einem Listview dargestellt werden. Die Synchronisation funzt auch schon.
Aber leider nicht dein Beispiel. Vieleicht habe ich die Falschen Tabellen angelgt. Jetzt schmeiss ich bald die Flinte in Korn.
Delphi-Quellcode:
Ungültige Variant-Operation.
while FieldValues['outline_id'].AsInteger = iParent do
Gruß Ingo |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:34 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