Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Обзор таблицы через TreeView1, Задача 
:(
    Опции темы
Ddddddelphi
Дата 9.12.2004, 23:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 1.12.2004

Репутация: нет
Всего: нет



Создал таблицу и псевдоним с именем Lavocka.
Таблица такая - таблица описывает предприятие, у каждого рабочего имеется свой универсальны код в таблице,
и дополнительный код, который означает - у кого в подчинение данный рабочий, вот таблица:
code name dopcode proffession
0033 bos 0000 director
0084 ivanov 0033 menejer
0085 vasichkin 0033 menejer
0097 ohlamonov 0084 menejer's p0moshnik
0097 ohlamonov 0085 menejer's p0moshnik

Мне нужно через дерево TreeView1, используя SQL -запросы отобразить базу данных,
следующим образом :

-bos
_ _ _-ivanov
_ _ _ _ _ _ohlamonov
_ _ _-vasichkin
_ _ _ _ _ _ohlamonov
подскажите пожалуйста, как нужно чего делать????????????? smile smile


PM MAIL   Вверх
SPrograMMer
Дата 10.12.2004, 13:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Спамер :)
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 5.11.2004
Где: Краснодар

Репутация: 1
Всего: 6



УУУ, чего захотел!
компонент TDBTree поищи в каком-нить яндексе.


--------------------
животное = зверь
законченный гентушник
PM MAIL ICQ Jabber   Вверх
Dimich
Дата 10.12.2004, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 247
Регистрация: 25.8.2004
Где: Брянск

Репутация: 3
Всего: 7



--------------------
Не работает - исправь, работает - не трогай!!!
PM MAIL ICQ Jabber   Вверх
BSV_Sergey
Дата 10.12.2004, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 19.11.2004
Где: г. Москва

Репутация: нет
Всего: 3



Для построения данного дерева нужно использовать рекурсию. Вариантов может быть несколько. Если БД на SQL сервере то могу предложить следующее:
Создать на сервере 2 хранимые процедуры, которые используя рекурсию сформируют промежуточную таблицу, на основании которой delphi построит дерево.
Процедура 1
Код

CAREATE PROCEDURE TREEADD
AS
BEGIN

DECLARE @TREEID AS INT,
@TREEUPID AS INT,
@DESC AS VARCHAR(255),
@POZ AS INT

CREATE TABLE #RESULT(TYPE VARCHAR(10),
      DESCR VARCHAR(255),
      IDREC INT)

DECLARE #PRIMARY_TREE CURSOR LOCAL FAST_FORWARD FOR
SELECT
TREEID,
TREEUPID,
DESCRIPTION
FROM STRUCTURE
WHERE TREEUPID = 0

OPEN #PRIMARY_TREE
WHILE @@ERROR=0
  BEGIN
   FETCH NEXT FROM #PRIMARY_TREE INTO @TREEID, @TREEUPID, @DESC
    IF @@FETCH_STATUS<>0 BREAK
INSERT INTO #RESULT
VALUES('Nil',@DESC,@TREEID)
SET @POZ = (SELECT COUNT(*) FROM #RESULT)-1
EXECUTE RECURSADD @TREEID,@POZ
  END  
CLOSE #PRIMARY_TREE
DEALLOCATE #PRIMARY_TREE

SELECT * FROM #RESULT

DROP TABLE #RESULT
END


Процедура 2

Код

PROCEDURE RECURSADD
@TREEID INT,
@POZITION INT
AS

DECLARE #REVERS CURSOR LOCAL FAST_FORWARD FOR
SELECT TREEID, TREEUPID, DESCRIPTION
FROM  STRUCTURE
WHERE TREEUPID = @TREEID

OPEN #REVERS

DECLARE @TRID AS INT,
@TRUPID AS INT,
@DESCR AS VARCHAR(255),
@POZ AS INT

WHILE @@ERROR=0
  BEGIN
FETCH NEXT FROM #REVERS INTO @TRID, @TRUPID, @DESCR
       IF @@FETCH_STATUS <>0 BREAK
INSERT INTO #RESULT VALUES(CAST(@POZITION AS VARCHAR),@DESCR,@TRID)
SET @POZ = (SELECT COUNT(*) FROM #RESULT)-1
EXECUTE RECURSADD @TRID,@POZ
  END  

CLOSE #REVERS
DEALLOCATE #REVERS



В Delphi пишем процудеру формирования дерева:

Код

with ADOQuery2 do
 begin
  SQL.Clear;
  SQL.Add('exec TREEADD');
  Open;
 end;
ADOQuery2.First;
TreeView1.Items.Clear;
TreeView1.Items.BeginUpdate;
while not ADOQuery2.Eof do
 begin
    IF ADOQuery2.FieldByName('TYPE').AsString = 'Nil' then
       Begin
TreeView1.Items.AddChildObject(nil,  ADOQuery2.FieldByName('DESCR').AsString,  Pointer(ADOQuery2.FieldByName('IDREC').AsInteger));
       End
    Else
       Begin
TreeView1.Items.AddChildObject(TreeView1.Items[ADOQuery2.FieldByName('TYPE').AsInteger],ADOQuery2.FieldByName('DESCR').AsString,Pointer(ADOQuery2.FieldByName('IDREC').AsInteger));
       End;
   ADOQuery2.Next;
 End;
TreeView1.Items.EndUpdate;


При этом всю основную нагрузку по формированию данных выполняет SQL сервер а Delphi лишь остается нарисовать дерево пройдясь по всем строчкам в возвращенном наборе данных.
Либо можно организовать рекурсивное построение дерева средствами самого Delphi. каму как больше нравится.

Это сообщение отредактировал(а) BSV_Sergey - 10.12.2004, 14:43
PM MAIL   Вверх
Ddddddelphi
Дата 10.12.2004, 23:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 1.12.2004

Репутация: нет
Всего: нет



BSV_Sergey, спасибо, но я сделал бд используя BDE,

извиняюсь, что неполностью всё не описал, как с помощью компонентов DataSourse и Query добиться решения задачи?



Это сообщение отредактировал(а) Ddddddelphi - 10.12.2004, 23:16
PM MAIL   Вверх
SPrograMMer
Дата 11.12.2004, 12:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Спамер :)
**


Профиль
Группа: Участник
Сообщений: 442
Регистрация: 5.11.2004
Где: Краснодар

Репутация: 1
Всего: 6



Ну, берешь, Query, которые выбирает сотрудников первого уровня - саамых главных, - из этого списка, создаешь, узлы первого уровня, затем берешь первый узел, смотришь сотрудников, которые ему подчиняются, - это узелы второго уровня для первого узла, затем, берешь первый узел второго уровня, для первого начальника, смотришь какие люди ему подчиняются,... и т.д.
Вот и построишь дерево.


--------------------
животное = зверь
законченный гентушник
PM MAIL ICQ Jabber   Вверх
BSV_Sergey
Дата 16.12.2004, 15:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 19.11.2004
Где: г. Москва

Репутация: нет
Всего: 3



Алгоритм формирования дерева можно организовать используя код приведенный ниже. Возможно его удастся улучшить, это первое решение, которое пришло мне в голову;
Структура таблицы используемой в примере:
REPORTTREE
treeid description treeupid
1 tree1 0
2 tree2 1
3 tree3 1 и тд
Текст модуля:
Код

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, DB, ADODB, StdCtrls, ComCtrls;

type
 TForm1 = class(TForm)
   ADOQuery1: TADOQuery;
   TreeView1: TTreeView;
   Button1: TButton;
   procedure Button1Click(Sender: TObject);
 private
   { Private declarations }
 public
   { Public declarations }
   gNOM:integer;
//Глобальный счетчик количества ветвей в дереве
 end;

var
 Form1: TForm1;

procedure treeadd();
Function recursADD(id:string;nomer:integer):Boolean;

implementation

{$R *.dfm}

procedure treeadd();
var     sSQL,treeid:string;
       n,i:integer;

begin
Form1.gNOM := -1;
sSQL := 'select count(*) as counttree from REPORTTREE where treeupid = 0';
with form1.ADOQuery1 do
begin
 Close;
 SQL.Clear;
 SQL.Add(sSQL);
 Open;
end;
treeid := '';
n := Form1.ADOQuery1.FieldByName('counttree').AsInteger;
for i:=1 to n do
begin
 if treeid = '' then
   sSQL := 'Select top 1 * from REPORTTREE where treeupid = 0'
 else
   sSQL := 'Select top 1 * from REPORTTREE where treeupid = 0 and treeid not in ('+treeid+')';
  with form1.ADOQuery1 do
   begin
    Close;
    SQL.Clear;
    SQL.Add(sSQL);
    Open;
   end;
  if treeid = '' then
    treeid :=Form1.ADOQuery1.FieldByName('treeid').Asstring
  else
    treeid := treeid + ','+Form1.ADOQuery1.FieldByName('treeid').Asstring;
   Form1.TreeView1.Items.BeginUpdate;
   Form1.TreeView1.Items.Add(nil,Form1.ADOQuery1.FieldByName('DESCRIPTION').AsString);
   Form1.gNOM := Form1.gNOM + 1;
   recursADD(Form1.ADOQuery1.FieldByName('treeid').AsString,Form1.gNOM);
end;
Form1.TreeView1.Items.EndUpdate;
end;


Function recursADD(id:string;nomer:integer):Boolean;
var     sSQL,treeid:string;
       i,n:integer;
begin
sSQL := 'select count(*) as counttree from REPORTTREE where treeupid = '+id;
with form1.ADOQuery1 do
begin
 Close;
 SQL.Clear;
 SQL.Add(sSQL);
 Open;
end;
treeid := '';
n := Form1.ADOQuery1.FieldByName('counttree').AsInteger;
if n > 0 then
for i:=1 to n do
begin
 if treeid = '' then
   sSQL := 'Select top 1 * from REPORTTREE where treeupid = '+id
 else
   sSQL := 'Select top 1 * from REPORTTREE where treeupid = '+id+' and treeid not in ('+treeid+')';
  with form1.ADOQuery1 do
   begin
    Close;
    SQL.Clear;
    SQL.Add(sSQL);
    Open;
   end;
  if treeid = '' then
    treeid :=Form1.ADOQuery1.FieldByName('treeid').Asstring
  else
   treeid := treeid + ','+Form1.ADOQuery1.FieldByName('treeid').Asstring;
  Form1.TreeView1.Items.AddChild(Form1.TreeView1.Items[nomer],Form1.ADOQuery1.FieldByName('DESCRIPTION').AsString);
  Form1.gNOM := Form1.gNOM + 1;
  recursADD(Form1.ADOQuery1.FieldByName('treeid').AsString,Form1.gNOM);
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
treeadd();
end;

end.


Ddddddelphi Надеюсь, я не слишком опоздал с ответом и мое решение smile еще актуальною

Это сообщение отредактировал(а) BSV_Sergey - 16.12.2004, 15:01
PM MAIL   Вверх
Ddddddelphi
Дата 16.12.2004, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 1.12.2004

Репутация: нет
Всего: нет



BSV_Sergey,
актуально, я учусь для себя поками-сь....
cпасибо!!!!! поработаю...

глупые вопросы, а:

Структура таблицы используемой в примере:
REPORTTREE
это из стандартных? не нашёл...c этим ладно

treeid description treeupid
1 tree1 0
2 tree2 1
3 tree3 1 и тд
чё воще означает?

Это сообщение отредактировал(а) Ddddddelphi - 16.12.2004, 15:55
PM MAIL   Вверх
BSV_Sergey
Дата 16.12.2004, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 19.11.2004
Где: г. Москва

Репутация: нет
Всего: 3



Таблица REPORTTREE - содержит 3 столбца:
treeid - id ветви дерева
description - название ветви дерева
treeupid - какой ветви дерева подчиняется.
В случае если treeupid = 0 - ветвь является контевой ветвью дерева и не кому не подчиняется.
Я назвал таблицу REPORTTREE, в твоей программе она может называться по другому. В твоем примере, если я правильно понял code - это treeid в моей таблице name - description, dopcode - treeupid.
К примеру дерево на основе следующих данных:

treeid description treeupid
1 Иванов 0
2 Петров 1
3 Сидоров 1
4 Смирнов 3
5 Наумов 2

будет выглядеть так
- Иванов
----Петров
-------Наутов
----Сидоров
-------Смирнов

Это сообщение отредактировал(а) BSV_Sergey - 16.12.2004, 17:13
PM MAIL   Вверх
BSV_Sergey
Дата 16.12.2004, 17:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 33
Регистрация: 19.11.2004
Где: г. Москва

Репутация: нет
Всего: 3



Я посмотрел твой пример. У тебя есть возможность, что у одного сотрудника могут быть несколько руководителей. В данной ситуации я еще посоветовал бы слегка изменить структуру таблиц, чтобы избежать избыточности данных. Можно создать таблицу с информацией о сотрудниках, к примеру Employee (employeeid(ID сотрудника), lastname, firstname, post и тд) и таблицу Hierarchy (employeeid, chiefid) в которой будет прописана орг структура предприяпия. В поле employeeid будет храниться ID сотрудника из таблицы employee, а в поле chiefid – ID сотрудника из таблица employee, который является руководителем первого.
Example:
Employee
1 ivanov ivan Manager
2 petrov ivan Chief of Branch of Department
3 sidorov petr Director

Hierarchy
3 0
1 3
2 3
1 2

Дерево будет выглядеть так
--sidorov
----ivanov
----petrov
--------ivanov
Хотя мож это и лищнее, смотри сам..smile

PM MAIL   Вверх
Akella
Дата 18.12.2004, 11:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 29
Всего: 329



Еще проще
Ставищ EhLib 3.5, если еще не стоит
В оэтой библиотеке много полезного, в том числе есть и такая фича, которая тебе нужна, по трем полям построить дерево.
PM MAIL   Вверх
Akella
Дата 21.12.2004, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 29
Всего: 329



попытался отсканировать пару страниц из книги "Мир Interbase"
получилось кривовато smile

есть таблица

[ID_GOODS] [ID_PARENT_GOODS] [GOOD_NAME]
1 0 GOODS
2 1 Бытовая техника
3 1 Компьютеры и комплектующие
4 2 Холодиль ники
5 2 Стиральные машины
6 4 Трехкамерные
7 4 Двухкамерные
8 4 Однокамерные
9 5 Вертикальные
10 5 Фронтальные
11 10 Узкие
12 10 Классические

DECLARE VARIABLE CURR_CHILD_NAME VARCHAR(80);
BEGIN
/*Организуем внешний цикл FOR SELECT no непосредственным потомкам товара с ID_GOOD=ID_GOOD2SHOW */
FOR SELECT gt1.id_good, gt1.good_name
FROM GoodsTree gt1
WHERE gt1.id_parent_good=:ID_good2show
INTO:ID_CHILD_G00D, :full_goods_name
DO
BEGIN
/*Проверка с помощью функции EXISTS, которая возвращает
TRUE, если запрос в скобках вернет хотя бы одну строку.
Если у найденного узла с ID_PARENT_GOOD = ID_CHILD_GOOD нет потомков,
то он является "листом" дерева и попадает в результаты */
IF (NOT EXISTS(
SELECT * FROM GoodsTree
WHERE GoodsTree.id_parent_good=:id_child_good))
THEN BEGIN
/* Передаем "лист" дерева в результаты */
SUSPEND;
END
ELSE
/* Для узлов, у которых есть потомки*/
BEGIN
/*сохраняем имя узла-родителя во временной переменной */
CURR_CHILD_NAME=full_goods_name;
/ * рекурсивно запускаем эту процедуру */
FOR
SELECT ID_CHILD_GOOD, full_goods_name
FROM GETFULLNAME (:ID_CHILD_GOOD)
INTO:ID_CHILD_GOOD, :full_goods_name
DO BEGIN
/*добавляем имя узла-родителя к найденному имени потомка с помощью операции конкатенации строк || */
full_goods_name=CURR_CHILD_NAME||' '||full_goods_name;
SUSPEND; /* возвращаем полное имя товара*/
END
END
END
END
Если мы выполним данную процедуру с входным параметром ID_GOOD2SHOW=1, то получим следующее:
FULL_GOODS_NAME FULL_GOODS_NAME
Бытовая техника Холодильники Трехкамерные 6
Бытовая техника Холодильники Двухкамерные 7
Бытовая техника Холодильники Однокамерные 8
и т.д.

Это сообщение отредактировал(а) dsergey - 21.12.2004, 12:57
PM MAIL   Вверх
Ddddddelphi
Дата 22.12.2004, 19:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 48
Регистрация: 1.12.2004

Репутация: нет
Всего: нет



@dsergey
"Мир Interbase"-что за книга? специально для Дельфи или? До изучения Interbase по книге ещё не дошёл, надо будет твой код рассмотреть, когда дойду.
PM MAIL   Вверх
Akella
Дата 23.12.2004, 09:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 29
Всего: 329



"Мир Interbase (вторая редакция)" это, насколько я знаю единственная книга на русском языке по Interbase, для Delphi там не очень много, еще продается с ней компакт-диск, там прилочно информации, компонентов, а также кроме IB7, есть "огненная утка"
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Базы данных и репортинг"
Vit
Петрович

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами


Обязательно указание:

1. Базы данных (Paradox, Oracle и т.п.)

2. Способа доступа (ADO, BDE и т.д.)


  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • Вопросы по SQL и вопросы по базам данных не связанные с Дельфи задавать здесь

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Vit, Петрович.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Базы данных и репортинг | Следующая тема »


 




[ Время генерации скрипта: 0.0562 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.