AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Treeviewzugriff: Neuen Datensatz erstellen im Treeview
Thema durchsuchen
Ansicht
Themen-Optionen

Treeviewzugriff: Neuen Datensatz erstellen im Treeview

Ein Thema von IngoH · begonnen am 2. Sep 2005 · letzter Beitrag vom 3. Sep 2005
Antwort Antwort
Seite 1 von 2  1 2      
IngoH

Registriert seit: 22. Aug 2005
11 Beiträge
 
#1

Treeviewzugriff: Neuen Datensatz erstellen im Treeview

  Alt 2. Sep 2005, 08:53
Datenbank: Access 2000 • Zugriff über: ADOConnection
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.

Schon mal Danke für die Hilfe.
Gruß
Ingo
  Mit Zitat antworten Zitat
IngoH

Registriert seit: 22. Aug 2005
11 Beiträge
 
#2

Re: Treeviewzugriff: Neuen Datensatz erstellen im Treeview

  Alt 2. Sep 2005, 15:20
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:
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;
Woher nehme ich den Wert für iFileID (Das Node, das ich gerade angelegt habe)? Welchen Wert also Index?
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#3

Re: Treeviewzugriff: Neuen Datensatz erstellen im Treeview

  Alt 2. Sep 2005, 16:32
Hallo Ingo,

unabhängig von deinen anderen Problemen - du produzierst jede Menge Speicherlöcher, wenn du mit TTreeNode.Create() arbeitest.
Lies mal hier: klick

Grüße vom marabu
  Mit Zitat antworten Zitat
IngoH

Registriert seit: 22. Aug 2005
11 Beiträge
 
#4

Re: Treeviewzugriff: Neuen Datensatz erstellen im Treeview

  Alt 2. Sep 2005, 17:01
Ja, die Knoten werden doch korrekt angefügt.

Delphi-Quellcode:
/// 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;
Klicke ich auf das Folder-Image öffnet es sich.

Vielleicht anders initalisieren?
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#5

Re: Treeviewzugriff: Neuen Datensatz erstellen im Treeview

  Alt 2. Sep 2005, 17:17
Mein Hinweis bezieht sich auf diese Stelle in deinem Code:

Delphi-Quellcode:
...
while not ADOTable1.Eof do begin
  AktNode := TTreeNode.Create(TreeView1.Items);
...
Der von dir an dieser Stelle erzeugte Knoten AktNode verschwindet in den Untiefen des Speichermanagements. Mit dem Link wollte ich dir die Augen öffnen.

marabu

PS: Du möchtest XML-Dokumente aus einem Dateisystem in einer Access-Datenbank verwalten - verstehe ich das richtig?
  Mit Zitat antworten Zitat
IngoH

Registriert seit: 22. Aug 2005
11 Beiträge
 
#6

Re: Treeviewzugriff: Neuen Datensatz erstellen im Treeview

  Alt 2. Sep 2005, 17:50
Zitat von marabu:
PS: Du möchtest XML-Dokumente aus einem Dateisystem in einer Access-Datenbank verwalten - verstehe ich das richtig?
Ja ist nicht ganz richtig.

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:
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;
Vielleicht so.

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
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#7

Re: Treeviewzugriff: Neuen Datensatz erstellen im Treeview

  Alt 2. Sep 2005, 18:05
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
  Mit Zitat antworten Zitat
IngoH

Registriert seit: 22. Aug 2005
11 Beiträge
 
#8

Re: Treeviewzugriff: Neuen Datensatz erstellen im Treeview

  Alt 2. Sep 2005, 18:20
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
dmReport.DataModule1.InsertFile(sFolderName, TreeView1.Selected.SelectedIndex+1, TextAlsMemo); Ich weiss, klingt kompliziert. Ist aber eine gute Idee. Besser, als das der Anwedner selbst die Festplatte nach den Reports durchsuchen muss.

Gruß
Ingo
  Mit Zitat antworten Zitat
marabu

Registriert seit: 6. Apr 2005
10.109 Beiträge
 
#9

Re: Treeviewzugriff: Neuen Datensatz erstellen im Treeview

  Alt 2. Sep 2005, 19:30
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:
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;
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).

marabu
  Mit Zitat antworten Zitat
IngoH

Registriert seit: 22. Aug 2005
11 Beiträge
 
#10

Re: Treeviewzugriff: Neuen Datensatz erstellen im Treeview

  Alt 2. Sep 2005, 23:02
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.

while FieldValues['outline_id'].AsInteger = iParent do Ungültige Variant-Operation.

Gruß
Ingo
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:35 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