Т.е. данные.
Тогда примерно так:
1. "Кладешь" TreeView.
2. При старте (открытии окна) загружаешь верхний уровень. Т.е. выполняешь запрос из Year и создаешь под него итемы. Для каждого итема в проперть Data кладешь ID соотв. записи и, ГЛАВНОЕ, создаешь подитем (пока пустой).
3. На открытие ветки (событие OnExpand) ставишь загрузку соотв. записей из дочерней таблицы, точно также ставя в Data ID и создавая подитемы (естественно, если уровнеь не последний).
4. Повторяешь с п.2., пока не будет написана загрузка всех уровней.
Тут есть еще один момент - как идентифицировать уровень. Я для этого обычно использую проперть StateIndex - она предназначена для хранения номера дополнительной картинки, так что можно вполне ею воспользоваться.
На самом деле это можно написать достаточно красиво и компактно, но при условии, что у тебя структура таблиц имеет некоторую однообразность.
Допустим, у тебя все таблицы имеют поля ID (уникальный идентификатор), ParentID (ссылка на родителя) и Name (собственно некоторое имя, которое и надо загрузить в TreeView).
Тогда будет что-то типа этого:
Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, DB, DBTables;
type
TForm1 = class(TForm)
TreeView1: TTreeView;
qQuery: TQuery;
procedure FormCreate(Sender: TObject);
procedure TreeView1Expanded(Sender: TObject; Node: TTreeNode);
private
procedure CreateItems(AParentNode: TTreeNode; AQuery: TDataSet; ALevel : Integer);
procedure InitLoad;
procedure Load(AParentNode : TTreeNode);
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
const
levCount = 3;
levYear = 1;
levMonth = 2;
levRealization = 3;
tableNames : Array [1..levCount] Of String = ('Year','Month','Realisation');
sqlQuery = 'SELECT ID, Name FROM Year';
sqlSubQuery = 'SELECT ID, Name FROM %s WHERE ParentID = %d';
procedure TForm1.CreateItems(AParentNode : TTreeNode; AQuery : TDataSet; ALevel : Integer);
var
ANode : TTreeNode;
begin
AParentNode.DeleteChildren;
ADataSet.First;
While Not ADataSet..EOF Do
Begin
ANode := TreeView1.Items.AddChild(AParentNode, AQuery.FieldByName('Name').AsString);
ANode.Data := Pointer(AQuery.FieldByName('Name').AsInteger);
ANode.StateIndex := ALevel;
If ALevel < levCount Then
TreeView1.Items.AddChild(ANode,'');
ADataSet.Next;
End;
end;
procedure TForm1.InitLoad;
begin
TreeView1.Items.Clear;
qQuery.Active := False;
qQuery.SQL.Clear;
qQuery.SQL.Add(sqlQuery);
qQuery.Active := True;
CreateItems(Nil,qQuery,levYear);
qQuery.Active := False;
end;
procedure TForm1.Load(AParentNode : TTreeNode);
var
ALevel, AParentID : Integer;
ASQL : String;
begin
ALevel := AParentNode.StateIndex;
AParentID := Integer(AParentNode.Data)
ASQL := Format(sqlSubQuery,[tableNames[ALevel + 1],AParentID]);
qQuery.Active := False;
qQuery.SQL.Clear;
qQuery.SQL.Add(ASQL);
qQuery.Active := True;
CreateItems(AParentID,qQuery,ALevel+1);
qQuery.Active := False;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
InitLoad;
end;
procedure TForm1.TreeView1Expanded(Sender: TObject; Node: TTreeNode);
begin
Load(Node);
end;
end.
Естественно, здесь нет ни подключения к БД, ни защиты от ошибок. Только канва.