Solved

data into treeview

Posted on 2001-07-02
8
699 Views
Last Modified: 2010-04-06
does someone have code which can fill a treeview from an adoquery?

i have acces db in which field1 is title which would go in treeview ,field2 is the data which would go in dbmemo when treeview node is clicked.


ive looked at some free dbtreeviews but i cant find one to work good.(most i found were for d3 and too buggy)

any ideas welcomed ..
0
Comment
Question by:inthe
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
  • 2
  • +1
8 Comments
 
LVL 1

Expert Comment

by:bnemmers
ID: 6245809
Take a look at Duck Query Component at
http://www.DuckTech.com and run the demo this might
solve your problem.

Happy coding.
Bill.



0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6246035
hi barry,

a sample from my current project, (it don't use ado and may not match your needs,
but maybe you could it apply or  
but maybe it gives you a suggestion
(i used ttreent as treeview-control)

this sample goes over two tables, one holds the hiarchy and the other the user-data

-- part paste begin

Function TF_PResource.FindParent(Tree : TTreeNT; ID : Integer) : TTreeNTNode;
var I : Integer;
begin
  Result := Nil;
  I := 0;
  While (I < Tree.Items.Count) and (ID <> PItemInfo(Tree.Items[i].Data)^.ID) do
    Inc(i);
  If I < Tree.Items.Count then
    Result := Tree.Items[i];
end;

procedure TF_PResource.SB_RefreshClick(Sender: TObject);
var
  PForm  : TfrmProgress;  //a progessform
  PCount : Integer;
  ANode  : TTreeNTNode;
  List   : TList;
  I      : Integer;
  SCount : Integer;
begin
  PForm := TfrmProgress.Create(Self);
  TreeView1.Items.BeginUpdate;
  if Assigned(Parent) then
    Parent.Enabled := False;
  try
    Q_Count.SQL.Text := 'Select Count(PRG_ID) From PRG where PRG_ID > 0';  //count entrys
    Try
      Q_Count.Prepare;
      Q_Count.Open;
      PCount := Q_Count.Fields[0].AsInteger;
      Q_Count.Close;
    except
      Raise;
    end;
    PForm.ProgressBar1.Max := PCount;
    PForm.ProgressBar1.Position := 0;
    PForm.ProgressBar1.Step := 1;
    PForm.Label1.Caption := 'Lade Gruppen f?r ProduktionsResourcen';
    Application.ProcessMessages;
    PForm.Show;
    FTreeInsert := True;
    TreeView1.Items.Clear;
    List := TList.Create;
    Try
      //Caching Information
      Q_PRG.SQL.Text := 'Select PRG_ID,PRG_PID,PRG_NAME from PRG where PRG_ID > 0 order by PRG_NAME';
      Q_PRG.Prepare;
      try
        Q_PRG.Open;
      except
        raise;
      end;
      While Not Q_PRG.Eof do
      Begin
        New(ItemInfo);
        ItemInfo^.Typ := 0;
        ItemInfo^.ID  := Q_PRG.FieldByName('PRG_ID').AsInteger;
        If Q_PRG.FieldByName('PRG_PID').IsNull then
          ItemInfo^.PID := -1
        else
          ItemInfo^.PID := Q_PRG.FieldByName('PRG_PID').AsInteger;
        ItemInfo^.Name  := Q_PRG.FieldByName('PRG_NAME').AsString;
        List.Add(ItemInfo);
        Q_PRG.Next;
        PForm.ProgressBar1.StepIt;
      End;
      Q_PRG.Close;
      //Add Roots First
      I := 0;
      PForm.ProgressBar1.Max := PCount;
      PForm.ProgressBar1.Position := 0;
      PForm.ProgressBar1.Step := 1;
      PForm.Label1.Caption := 'Ordne Gruppen f?r ProduktionsResourcen';
      Application.ProcessMessages;
      While I < List.Count do
      Begin
        If PItemInfo(List[i])^.PID = -1 then
        begin
          ANode := TreeView1.Items.AddChild(NIL,PItemInfo(List[i])^.Name);
          ANode.Data := List[i];
          ANode.ImageIndex := 0;
          ANode.SelectedIndex := 1;
          List.Delete(i);
          PForm.ProgressBar1.StepIt;
        end
        else inc(i);
      end;
      //Add Rest of Group
      While List.Count > 0 do
      Begin
        SCount := List.Count;
        I := 0;
        While I < List.Count do
        Begin
          ANode := FindParent(TreeView1,PItemInfo(List[i])^.PID);
          If ANode <> Nil then
          Begin
            ANode := TreeView1.Items.AddChild(ANode,PItemInfo(List[i])^.Name);
            ANode.Data := List[I];
            ANode.ImageIndex := 0;
            ANode.SelectedIndex := 1;
            List.Delete(i);
            PForm.ProgressBar1.StepIt;
          end
          else inc(i);
        end;
        //Konnte nichts mehr zugeordnet werden,
        //und es liegen noch Eintr?ge vor,
        //dann kann was nicht stimmen
        If List.Count = SCount then
          Raise Exception.Create('Es liegt ein Dateninkonsistenz vor!'+#10+'Benachrichtigen Sie den Entwickler!');
      end;
    finally
      List.Free;
    end;
    //Nun zu den Nicht-Gruppen Eintr?gen
    i := 0;
    Q_Count.SQL.Text := 'Select Count(PR_ID) From PR where PR_ID > 0';
    Try
      Q_Count.Prepare;
      Q_Count.Open;
      PCount := Q_Count.Fields[0].AsInteger;
      Q_Count.Close;
    except
      Raise;
    end;
    PForm.ProgressBar1.Max := PCount;
    PForm.ProgressBar1.Position := 0;
    PForm.ProgressBar1.Step := 1;
    PForm.Label1.Caption := 'Lade und Ordne Items f?r ProduktionsResourcen';
    Application.ProcessMessages;
    while i < TreeView1.Items.Count do
    begin
      If PItemInfo(TreeView1.Items[i].Data)^.Typ = 0 then
      begin
        Q_PR.ParamByName('ID').AsInteger := PItemInfo(TreeView1.Items[i].Data)^.ID;
        Q_PR.Open;
        While Not Q_PR.Eof do
        begin
          New(ItemInfo);
          ItemInfo^.Typ := 1;
          ItemInfo^.ID := Q_PR.FieldByName('PR_ID').AsInteger;
          ItemInfo^.PID := 0;
          ItemInfo^.Name := Q_PR.FieldByName('PR_NAME').AsString;
          ANode := TreeView1.Items.AddChild(TreeView1.Items[i],ItemInfo^.Name);
          ANode.Data := ItemInfo;
          ANode.ImageIndex := 2;
          ANode.SelectedIndex := 3;
          PForm.ProgressBar1.StepIt;
          Q_PR.Next;
        end;
        Q_PR.Close;
      end;
      inc(i);
    end;
    FTreeInsert := False;
    TreeView1.FullCollapse;
    If TreeView1.Items.GetFirstNode <> Nil then
      TreeView1.Selected := TreeView1.Items.GetFirstNode
    else
      TreeView1.Selected := NIL;
    FPR_EditContext := PRG;
    FPR_EditState   := PR_Browse;
    AdJustNav;
  finally
    if Assigned(Parent) then
      Parent.Enabled := True;
    TreeView1.Items.EndUpdate;
    PForm.Release;
    Application.ProcessMessages;
  end;
end;

procedure TF_PResource.TreeView1Deletion(Sender: TObject; Node: TTreeNTNode);
begin
  If Node.Data <> Nil then
  begin
    Dispose(PItemInfo(Node.Data));
    Node.Data := Nil;
  end;
end;

-- part paste end

as you need  a dbmemo you could store it as a memorystream in the dataproperty of the node,
and stream it into a tmemo in the onchange event of the tree

i could code a more matching sample at next weekend if needed

meikl ;-)
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6246055
another possibilty could be to store the unique-key in the dataproperty
and use an locate on another query, where a tdbmemo is connected to it

meikl ;-)
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 13

Accepted Solution

by:
Epsylon earned 250 total points
ID: 6246135
It's not great, but I can email the project if you want me to:


procedure TForm1.ADOQuery1AfterOpen(DataSet: TDataSet);
begin
  BuildTree;
end;

procedure TForm1.ADOQuery1BeforeClose(DataSet: TDataSet);
begin
  ClearTree;
end;

procedure TForm1.TreeView1Change(Sender: TObject; Node: TTreeNode);
begin
  ADOQuery1.RecNo := Integer(Node.Data);
end;

procedure TForm1.ADOQuery1AfterInsert(DataSet: TDataSet);
begin
  BuildTree;
end;

procedure TForm1.BuildTree;
var node: TTreeNode;
begin
  TreeView1.Items.BeginUpdate;
  TreeView1.Items.Clear;
  ADOQuery1.First;
  while not ADOQuery1.Eof do
  begin
    node := TreeView1.Items.Add(nil, ADOQuery1['TRIPNAME']);
    node.Data := Pointer(ADOQuery1.RecNo);
    ADOQuery1.Next;
  end;
  TreeView1.Items.EndUpdate;
end;

procedure TForm1.ClearTree;
begin
  TreeView1.Items.BeginUpdate;
  TreeView1.Items.Clear;
  TreeView1.Items.EndUpdate;
end;

procedure TForm1.ADOQuery1AfterScroll(DataSet: TDataSet);
var i: Integer;
begin
  for i := 0 to TreeView1.Items.Count - 1 do
    if Integer(TreeView1.Items.Item[i].Data) = ADOQuery1.RecNo then
    begin
      TreeView1.Selected := TreeView1.Items.Item[i];
      break;
    end;
end;
0
 
LVL 17

Author Comment

by:inthe
ID: 6247742
epsylon ,
thanks thats ok for me to get on with
i just need to change the tree to work across many tables

table1
  field1
table2
  field1
table3
  field1
etc..
but i figure i can do

AdoConnection1.GetTableNames(sl);
and add a for loop into the buildtree code to add all tables. would that work ?

cheers also meikl ;-)
0
 
LVL 17

Author Comment

by:inthe
ID: 6247764
note my fields names are the same as table name with title,code,note added like:

table1
table1 title
table1 code
table1 note

so i assuming i can do

for i := 0 to sl.count -1 do begin
node := TreeView1.Items.Add(nil, ADOQuery1[sl[i]+' Title']);
0
 
LVL 13

Expert Comment

by:Epsylon
ID: 6247862
> i just need to change the tree to work across many tables

You would get into trouble because RecNo can only reference a single TADOQuery while you need multiple. RecNo is needed when you click on a node.


You can also put all tables in a single query:

  select field1 from Table1 UNION ALL select field1 from table2 UNION ALL select field1 from Table3

You can build this query string at runtime and then open (activate) the query.
0
 
LVL 27

Expert Comment

by:kretzschmar
ID: 6248067
? why not use the tree as navigation

store the tablename and the unique_id in the data_prooerty as record and on nodechange prepare a select like

select * from (dataproperty->tablename) where id = (dataproperty->unique_id)

to retrieve all the other datas directly from the db

(just my thought-> i don't know for what you are after, specially after grading eps comment, which is really not this what i thought you need)

meikl ;-)
0

Featured Post

[Webinar] Learn How Hackers Steal Your Credentials

Do You Know How Hackers Steal Your Credentials? Join us and Skyport Systems to learn how hackers steal your credentials and why Active Directory must be secure to stop them. Thursday, July 13, 2017 10:00 A.M. PDT

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
There are cases when e.g. an IT administrator wants to have full access and view into selected mailboxes on Exchange server, directly from his own email account in Outlook or Outlook Web Access. This proves useful when for example administrator want…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
Suggested Courses
Course of the Month5 days, 17 hours left to enroll

627 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question