| 
| 
 | Вопрос # 1 856/ вопрос открыт / | 
 |  Здравствуйте! Помогите пожалуйста с такой задачкой:Есть база данных подразделений, где PODR_ID-идентификатор, PARENT_ID-идент. родительского подразделения, PODR_NAME-название подразделения и TreeView в котором отображаются данные таблицы:
 Главный узел
 |
 |---------Узел1
 |            |------------Цех1
 |                            |------Подразд1
 |---------Узел2
 |------------Цех1
 |------Подразд1
 Помогите пожалуйста связать имена ветвей дерева с базой данных, при каком запросе это можно сделать, если можете пришлите пожалуйста исходник. У меня при запросах например Найти Подразд1 прога ищет первый в списке а не тот что нужен. А ведь в разных цехах может быть подразд. с одинаковыми названиями. Пишу код выгрузки в дерево:
 
 Заранее спасибо.
 Приложение:Переключить в обычный режим procedure TDM.LoadTreeView;typePItemData=^TItemData;TItemData=recordindex: Integer;end;varTNNew: TTreeNode;idNewItem: PItemData;i: Integer;beginMainForm.TreeView1.Items.Clear;with DM.PodrQuery do  begin  Active:=False;  SQL.Clear;  SQL.Add('SELECT * FROM PODR');  SQL.Add('ORDER BY PODR_ID, PODR_NAME');  Active:=True;  if DM.PodrTable.IsEmpty then    begin     Exit;    end    else  First;  end;    while DM.PodrQuery.Eof<>True do    begin    TNNew:=Nil;    if DM.PodrQuery.Fields[1].AsInteger>0 then    for i:=0 to MainForm.TreeView1.Items.Count-1 do    if PItemData(MainForm.TreeView1.Items[i].Data).index=    DM.PodrQuery.Fields[1].AsInteger then    TNNew:=MainForm.TreeView1.Items[i];  with MainForm.TreeView1.Items.AddChild(TNNew, DM.PodrQuery.Fields[0].AsString) do  begin  ImageIndex:=1;  SelectedIndex:=0;  idNewItem:=new(PItemData);  Data:=idNewItem;  idNewItem.index:=DM.PodrQuery.Fields[0].AsInteger;  end;    DM.PodrQuery.Next;    end;    MainForm.TreeView1.Items[0].Selected:=True;end; 
|  |   Вопрос задал: Димон (статус: Посетитель)Вопрос отправлен: 27 августа 2008, 21:43
 Состояние вопроса: открыт, ответов: 1.
 |  Ответ #1. Отвечает эксперт: Вадим К Здравствуйте, Димон!Таким хитрым образом как Вы добавляете, Вы будете это делать долго. А как только понадобиться функциональность типа "переименовать" - утоните в строках кода. Всё делается на порядок проще.
 Писать готовый код не буду (так как в таком случае програмист стаёт ленивым и не может даже одну строку заменить). Но набросок схематический кода сделаю.
 Итак, первое, что надо сделать, это отказаться от использования имён нод в качестве опорной точки. В структуру TItemData надо добавить поле которое будет ассоциироваться с id строки для этого поля в базе. (возможно Ваш index это и есть).
 Второе - это добавлять методом рекурсии. в таком случае код заметно упрощается.
 Допустим, что у нашей таблички такие поля id - ключевое, text - имя, выводимое пользователю, parentid - id родительского элемента. Для элементов верхнего уровня он равен 0.
 Ну где то так.
 
 Procedure AddNodesLevel(parentNode:TTreeNode; ParentId:integer);
var node:TTreeNode;
  rs :_RecordSet;
begin
  ADOCommand.Command :='select id, text from mytable where parentid = ' + inttostr(Parentid);
  rs := ADOCommand.Execute;
  while not rs.eof do begin
    Node := TreeView.addChild(parentNode);
    Node.text := rs.Fieldbyname[1];
   AddNodesLevel(Node, rs.Fieldbyname[0]);
  end;
rs.close;
end;Я писал применимо к АДО. Вариант с БДЕ я просто не рассматриваю - это тихий ужас. В этом случае прийдётся создавать в процедуре компонент TQuery, так как процедура запускает себя рекурсивно.
 Код написан схематически и напильником доводиться до той кондиции, до которой нужно. Как видно, я вообще опустил создание записей - они просто не нужны. Но можете добавить (и даже нужно, если хочеться делать поиск и подобное).
 Если уточните компоненты/базу - уточню детали кода:)
 И на последнее. строка вида
 
  for i:=0 to MainForm.TreeView1.Items.Count-1 doЭто самое худшее, что можно написать. при кол-ве итемов порядка сотни, загрузка будет происходит минут 10. 
 Это всё было лично испытано на себе:)
 
|  | Ответ отправил: Вадим К (статус: Академик)Время отправки: 28 августа 2008, 02:32
 Оценка за ответ: 5
 |  
 Мини-форум вопросаМини-форум пуст. Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте. |