Форум: "Базы";
Текущий архив: 2004.06.06;
Скачать: [xml.tar.bz2];
ВнизДерево в БД Найти похожие ветки
← →
goozman (2004-05-06 10:12) [0]Помогите пожалуйста, есть таблица, главные поля (ID, PARENT_ID) по ним строится дерево- по полю ID я могу добратся к самому верхнему родителю, а теперь вопрос помогите создать запрос по которому можно по родителю (самому верхнему) узнать все дочерние его ветки! Очень надеюсь на Вашу помощь!
← →
Соловьев © (2004-05-06 10:16) [1]
> самому верхнему родителю, а теперь вопрос помогите создать
> запрос по которому можно по родителю (самому верхнему) узнать
> все дочерние его ветки! Очень надеюсь на Вашу помощь!
www.ibase.ru
← →
goozman (2004-05-06 10:19) [2]Наверное я неправильно выразился, мне надо не количество веток, а все записи с их ID
← →
Соловьев © (2004-05-06 10:25) [3]
> goozman (06.05.04 10:19) [2]
там все это есть
← →
Курдль © (2004-05-06 11:06) [4]Это не решается запросом (разве что на Оракле).
← →
Соловьев © (2004-05-06 11:10) [5]
> Курдль © (06.05.04 11:06) [4]
ХП
← →
Мунька (2004-05-06 11:13) [6]Одним запросом не решается. Я строила дерево из таблицы Access - дерево подразделений, находила также предков-потомков, но одним запросом это не решается, если интересно, могу кусок кода поиска потомков кинуть
← →
Соловьев © (2004-05-06 11:15) [7]
> Мунька (06.05.04 11:13) [6]
в Access - не решается в ИБ решается.
← →
Курдль © (2004-05-06 11:16) [8]
> Соловьев ©
На ХП можно построить дерево с цепью, русалкой и ученым котом впридачу! Автор просил запрос. Но я считаю, что ради "дерева" не следует мучать сервер. Ведь все, что он сможет вернуть - последовательность деревянно-отсортированных записей! Преобразовывать их в стволы, ветки и узлы придется все равно на клиенте.
← →
Мунька (2004-05-06 11:19) [9]>последовательность деревянно-отсортированных записей! >Преобразовывать их в стволы, ветки и узлы придется все равно на >клиенте.
Не вижу проблем такого преобразования
← →
Соловьев © (2004-05-06 11:21) [10]
> Курдль © (06.05.04 11:16) [8]
а оракл вернет что? не
> последовательность деревянно-отсортированных записей!
?
← →
Курдль © (2004-05-06 11:22) [11]
> Мунька (06.05.04 11:19) [9]
> Не вижу проблем такого преобразования
Так я более того - не вижу проблем разложения древовидно-заточенного набора данных в дерево вовсе на клиенте! Это рекурсия в 10 строк!
← →
Курдль © (2004-05-06 11:24) [12]
> Соловьев © (06.05.04 11:21) [10]
> а оракл вернет что? не
> > последовательность деревянно-отсортированных записей!
Ее самую, а где противоречия? Только оракл вернет по запросу, а не из ХП. Но я повторяю - чаще всего удобнее "делать дерево" на клиенте.
← →
gu_est (2004-05-06 11:26) [13]>Курдль © (06.05.04 11:16) [8]
Что значит не мучать сервер? А кого мучать? Клиента?
Загнать на клиента ВСЕ и там строить дерево? А на кой тогда сервер вообще нужен?
← →
Соловьев © (2004-05-06 11:28) [14]
> Только оракл вернет по запросу, а не из ХП
Просто разработчики Оракла уже это реализовали. Вот тебе и запрос. Но не вижу сложности в ХП...
не будем спорить, автор и сам решит что ему нужно...
Противоречие здесь.
> Преобразовывать их в стволы, ветки и узлы придется все равно
> на клиенте.
Таким образом я понял что Оракл вернет уже типа готовой компоненты... Значит я не понял ответа.
Но имхо ХП самое оно.
← →
Sergey_Masloff (2004-05-06 11:28) [15]Курдль © (06.05.04 11:24) [12]
В запросе надо отобрать все счета клиента а клиент это иерархическая структура - центральный офис, представительства и так далее. Куда ты в этой задаче засунешь свое дерево на клиенте?
Это только самый простой пример реально деревью могут использоваться на сервере и покруче.
← →
Курдль © (2004-05-06 11:29) [16]
> gu_est (06.05.04 11:26) [13]
> Загнать на клиента ВСЕ и там строить дерево? А на кой тогда
> сервер вообще нужен?
Именно загнать на клиента ВСЕ! Ведь от перестроения записей их количество не изменится! А сервер БД нужен вовсе не для того, чтобы заниматься бантиками клиентского интерфейса.
← →
Курдль © (2004-05-06 11:34) [17]
> Соловьев © (06.05.04 11:28) [14]
> Таким образом я понял что Оракл вернет уже типа готовой
> компоненты... Значит я не понял ответа.
> Но имхо ХП самое оно.
Нифига похожего оно не вернет! Только root-node-subnode...node-subnode-subsubnode... и т.д. Еще поле LEVEL.
Компонент визуальный наполнять все равно придется со стороны клиента - иначе никак!
← →
Соловьев © (2004-05-06 11:34) [18]
> Ведь от перестроения записей их количество не изменится!
>
это если один клиент :)
А если много? У меня ветка строится когда пользователь решил ее рскрыть. И сразу выполняется запрос к БД. А в твоем варианте данные не актуальны.
← →
Johnmen © (2004-05-06 11:36) [19]>Именно загнать на клиента ВСЕ!
Да ? А если их много ? А нас много не интересует ?
>Ведь от перестроения записей их количество не изменится!
А где здесь "перестроение" ?
← →
Курдль © (2004-05-06 11:37) [20]
> У меня ветка строится когда пользователь решил ее рскрыть.
Это разумно. Не спорю. Но я, чаще всего, беру TdxDBTreeList, подставляю ему набор данных и не парюсь :)
← →
gu_est (2004-05-06 11:43) [21]Автор вообще не заострял внимание на визуализации дерева как такового (может полученный в результате запроса набор данных он собарается использовать для дальнейших вычислений, а не для визуализации в виде дерева).
Посему ХП (ИМХО) это то, что "доктор прописал"
← →
Мунька (2004-05-06 11:46) [22]Ладно, ловите. Суть такая. Таблица, как я понимаю, как у нашего вопрошающего. Сначала я извлекаю данные все, а уж потом строю дерево, результат, то бишь дерево, скидываю в StringList
//---------------------------------------------------------------
//Извлечение всех записей и скидывание их в StringList при помощи рекурсивной функции RecursDepartment, для идентификаторов используется отдельный TStringList * DepListId
bool TDM::SelectAllDepartment(WideString ConnectionADO, TStringList * DepList, TStringList * DepListId)
{
int RecNo;
if(ADOQDepart->Active)
ADOQDepart->Close();
ADOConnection1->Connected = false;
ADOConnection1->ConnectionString = ConnectionADO;
ADOConnection1->Connected = true;
ADOQDepart->Connection = ADOConnection1;
ADOQDepart->SQL->Clear();
ADOQDepart->SQL->Add("SELECT * FROM tdivision ORDER BY id_parent, id_division");
try{
ADOQDepart->Open();
}
catch(...)
{
return false;
}
ADOQDepart->First();
DepList->Clear();
if(DepListId!=NULL)
DepListId->Clear();
while(!ADOQDepart->Eof&&(ADOQDepart->FieldByName("id_parent")->AsInteger==-1 ) )
{
DepList->Add(ADOQDepart->FieldByName("name_division")->AsString);
if(DepListId!=NULL)
DepListId->Add(IntToStr(ADOQDepart->FieldByName("id_division")->AsInteger));
RecNo =ADOQDepart->RecNo;
RecursDepartment(DepList, ADOQDepart->FieldByName("id_division")->AsInteger, DepListId);
ADOQDepart->RecNo=RecNo;
ADOQDepart->Next();
}
return true;
}
//сама рекурсивная функция
void TDM::RecursDepartment(TStringList * DepList, int id_parent, TStringList * DepListId)
{
int RecNo;
while(!ADOQDepart->Eof)
{
if(ADOQDepart->FieldByName("id_parent")->AsInteger==id_parent)
{
DepList->Add(ADOQDepart->FieldByName("name_division")->AsString);
if(DepListId!=NULL)
DepListId->Add(IntToStr(ADOQDepart->FieldByName("id_division")->AsInteger));
RecNo = ADOQDepart->RecNo;
RecursDepartment(DepList, ADOQDepart->FieldByName("id_division")->AsInteger, DepListId);
ADOQDepart->RecNo=RecNo;
}
ADOQDepart->Next();
}
}
← →
Мунька (2004-05-06 11:47) [23]// и кусок кода, для вызова всего этого хозяйства, одна функция выводит в грид SetStringListToGrig, вторая - в дерево
DM->SelectAllDepartmentToTree
...........................................
DeparmentList = new TStringList();
DeparmentListId = new TStringList();
DM->SelectAllDepartment(ConnectionADO, DeparmentList, DeparmentListId);
ClearGrid(SGDivision, MIN_ROWCOUNT_DEPARTMENT);
SetStringListToGrig(SGDivision, DeparmentList, MIN_ROWCOUNT_DEPARTMENT, 0);
SGDivisionSelectCell(Sender, 0, 1,CanSelect);
DM->SelectAllDepartmentToTree(ConnectionADO, TreeViewDep);
.......... дальше по коду...........................
//----------------------SetStringListToGrig вывод извлеченного дерева в грид------
void SetStringListToGrig(TStringGrid *sg, TStringList *sl, int min_rowcount, int col_num)
{
int i;
for(i=0; i< sl->Count; i++)
{
if(i==(sg->RowCount-sg->FixedRows ))
sg->RowCount +=min_rowcount;
sg->Cells[col_num][i+sg->FixedRows] = sl->Strings[i];
}
}
← →
Мунька (2004-05-06 11:48) [24]
//Вывод в дерево
bool TDM::SelectAllDepartmentToTree(WideString ConnectionADO, TTreeView *TreeViewDep)
{
int RecNo;
if(ADOQDepart->Active)
ADOQDepart->Close();
ADOQDepart->ConnectionString = ConnectionADO;
ADOQDepart->SQL->Clear();
ADOQDepart->SQL->Add("SELECT * FROM tdivision ORDER BY id_parent, id_division");
try{
ADOQDepart->Open();
}
catch(...)
{
return false;
}
ADOQDepart->First();
TreeViewDep->Items->Clear();
while(!ADOQDepart->Eof&&(ADOQDepart->FieldByName("id_parent")->AsInteger==-1 ) )
{
// DepList->Add(ADOQDepart->FieldByName("name_division")->AsString);
TreeViewDep->Items->Add(NULL, ADOQDepart->FieldByName("name_division")->AsString);
RecNo =ADOQDepart->RecNo;
// RecursDepartmentList(DepList, ADOQDepart->FieldByName("id_division")->AsInteger, DepListId);
RecursDepartmentList(TreeViewDep, ADOQDepart->FieldByName("id_division")->AsInteger, TreeViewDep->Items->Item[TreeViewDep->Items->Count-1]);
ADOQDepart->RecNo=RecNo;
ADOQDepart->Next();
}
// ADOQDepart->
return true;
}
//рекурсия построения дерева
void TDM::RecursDepartmentList(TTreeView *TreeViewDep, int id_parent, TTreeNode *NodeParent)
{
int RecNo;
while(!ADOQDepart->Eof)
{
if(ADOQDepart->FieldByName("id_parent")->AsInteger==id_parent)
{
TreeViewDep->Items->AddChild(NodeParent, ADOQDepart->FieldByName("name_division")->AsString);
RecNo = ADOQDepart->RecNo;
RecursDepartmentList(TreeViewDep, ADOQDepart->FieldByName("id_division")->AsInteger, TreeViewDep->Items->Item[TreeViewDep->Items->Count-1]);
ADOQDepart->RecNo=RecNo;
}
ADOQDepart->Next();
}
}
← →
Мунька (2004-05-06 11:48) [25]
//И напоследок, есть предок, извлечь всех его потомков
bool TDM::SelectLastLevel(WideString ConnectionADO, int id_parent)
{
TStringList *Id= new TStringList(), *list_parent = new TStringList() ;
int i; // * list_id = new [1], size_list_id = 1,
AnsiString InString;
if(ADOQLastLevel->Active)
ADOQLastLevel->Close();
ADOQLastLevel->ConnectionString = ConnectionADO;
list_parent->Add(IntToStr(id_parent));
do{
ADOQLastLevel->SQL->Clear();
ADOQLastLevel->SQL->Add("SELECT id_division, id_parent FROM tdivision WHERE id_parent IN(");
InString = "";
for(i=0; i<list_parent->Count; i++)
{
if ( ((i+1)%100)==0)
{
ADOQLastLevel->SQL->Add(InString);
InString = "";
}
InString += list_parent->Strings[i];
if(i<(list_parent->Count-1) )
InString +=", ";
else InString +=")";
}
ADOQLastLevel->SQL->Add(InString);
ADOQLastLevel->SQL->Add("ORDER BY id_parent, id_division");
try{
if(!ADOQLastLevel->Prepared)
ADOQLastLevel->Prepared = true;
ADOQLastLevel->Open();
}
catch(...)
{
delete Id;
delete list_parent;
return false;
}
for(i=0; i<list_parent->Count; i++)
{
ADOQLastLevel->Filtered = false;
ADOQLastLevel->Filter = "id_parent = "+ list_parent->Strings[i];
try{
ADOQLastLevel->Filtered = true;
}
catch(...)
{
continue;
}
if(ADOQLastLevel->RecordCount==0)
Id->Add(list_parent->Strings[i]);
}//end for
list_parent->Clear();
ADOQLastLevel->Filtered = false;
ADOQLastLevel->First();
while(!ADOQLastLevel->Eof)
{
list_parent->Add(ADOQLastLevel->FieldByName("id_division")->AsString);
ADOQLastLevel->Next();
}
}
while(ADOQLastLevel->RecordCount>0);
ADOQLastLevel->SQL->Clear();
ADOQLastLevel->SQL->Add("delete from tdivision_tmp");
try{
if(!ADOQLastLevel->Prepared)
ADOQLastLevel->Prepared = true;
ADOQLastLevel->ExecSQL();
}
catch(...)
{
delete Id;
delete list_parent;
return false;
}
ADOQLastLevel->SQL->Clear();
ADOQLastLevel->SQL->Add("INSERT INTO tdivision_tmp ");
ADOQLastLevel->SQL->Add("SELECT * FROM tdivision WHERE id_division IN(");
InString = "";
for(i=0; i<Id->Count; i++)
{
if ( ((i+1)%100)==0)
{
ADOQLastLevel->SQL->Add(InString);
InString = "";
}
InString += Id->Strings[i];
if(i<(Id->Count-1) )
InString +=", ";
else InString +=")";
}
ADOQLastLevel->SQL->Add(InString);
try{
if(!ADOQLastLevel->Prepared)
ADOQLastLevel->Prepared = true;
ADOQLastLevel->ExecSQL();
}
catch(...)
{
delete Id;
delete list_parent;
return false;
}
delete Id;
delete list_parent;
return true;
}
← →
Соловьев © (2004-05-06 11:49) [26]
> DepListId->Add(IntToStr(ADOQDepart->FieldByName("id_division")->AsInteger));
слабенько :) А как насчет AddObject? ИМХО возможностей больше. И для ИБ есть уже готовые с исходниками. Брать на www.fibplus.com.ua в старье
← →
Мунька (2004-05-06 11:55) [27]>>слабенько :) А как насчет AddObject?
Никак. Не помню из каких соображений, но вариант с добавлением объекта был отброшен. Наверное, из-за того, что объект должен быть наследником TObject, все-таки, а не просто целым числом.
← →
Курдль © (2004-05-06 11:55) [28]
> Мунька
Это все об одном дереве????????!!!!!!! 8-()
Я же сказал 10 строк, а не 510!
← →
Соловьев © (2004-05-06 11:59) [29]
> Это все об одном дереве????????!!!!!!! 8-()
> Я же сказал 10 строк, а не 510!
конечно когда за тебя все сделали
> Но я, чаще всего, беру TdxDBTreeList, подставляю ему набор
> данных и не парюсь :)
> Мунька (06.05.04 11:55) [27]
> >>слабенько :) А как насчет AddObject?
> Никак. Не помню из каких соображений, но вариант с добавлением
> объекта был отброшен. Наверное, из-за того, что объект должен
> быть наследником TObject, все-таки, а не просто целым числом.
При использовании AddObject можно в узле хранить ссылку на структуру где хранить об узле кучи инфы, котора облегчает построение.
← →
Мунька (2004-05-06 11:59) [30]>Это все об одном дереве????????!!!!!!! 8-()
>Я же сказал 10 строк, а не 510!
Там разные варианты - вывод в грид, в дерево, поиск потомков.. то есть это еще и визуальная обработка
← →
Мунька (2004-05-06 12:01) [31]>При использовании AddObject можно в узле хранить ссылку на >структуру где хранить об узле кучи инфы, котора облегчает >построение.
Можно, но в данной программе хрен редьки не слаще
← →
Курдль © (2004-05-06 12:03) [32]
> Мунька (06.05.04 11:48) [24]
ЗАЧЕМ ВЫ ЭТО ВЫЛОЖИЛИ???
Неужели чтобы "передать опыт"? То, что Вы понаписали внутри ХП - чудовищно! Какие-то временные таблицы, бесчисленные селекты...
Что Вы хотели показать?
← →
Соловьев © (2004-05-06 12:06) [33]
> То, что Вы понаписали внутри ХП - чудовищно!
это как раз клиент :)
← →
Курдль © (2004-05-06 12:08) [34]Вот клиент:
//------------------------------------------------------------------------------
procedure TfrmAccounts.SortAccList(aList: TList);
var y, iy: Integer; py: ptrAcc;
procedure BuildLink(var ptr: ptrAcc; var Index: Integer);
var x: Integer; px: ptrAcc;
begin
inc(Index);
for x:=0 to aList.Count-1 do
begin
px:=aList.Items[x];
if (px.pr = ptr.id) and (px.index = 0) then
begin
px.index:=Index;
px.level:=ptr.level+1;
BuildLink(px, Index);
ptr.dt0:=ptr.dt0+px.dt0;
ptr.kt0:=ptr.kt0+px.kt0;
end;
end;
end;
begin
if aList = nil then Exit;
iy:=1;
for y:=0 to aList.Count-1 do
begin
py:=aList.Items[y];
if py.pr = 0 then
begin
py.index:=iy;
BuildLink(py,iy);
end;
end;
aList.Sort(SortCompareIndex);
end;
//------------------------------------------------------------------------------
← →
Соловьев © (2004-05-06 12:08) [35]
> Можно, но в данной программе хрен редьки не слаще
ну-ну... советую взглянуть на исходники готовых DBTreeView
← →
Johnmen © (2004-05-06 12:09) [36]>Курдль © (06.05.04 12:03) [32]
>Что Вы хотели показать?
А то ты не понял ? :)
Показать, что CB круче D, и эту крутизну успешно штурмовал тов. Мунька
Кстати, что-то текста маловато он привел... Требую продолжения банкета !
← →
Соловьев © (2004-05-06 12:11) [37]
> aList.Sort(SortCompareIndex);
странно...
aList.Sort(@SortCompareIndex);?
и вообще не понятно к чему твой код :)
← →
}|{yk © (2004-05-06 12:14) [38]http://delphimaster.net/view/3-1083829796/
← →
Мунька (2004-05-06 12:18) [39]>Неужели чтобы "передать опыт"? То, что Вы понаписали внутри ХП -> чудовищно! Какие-то временные таблицы, бесчисленные селекты...
>Что Вы хотели показать?
Всего-навсего ответила на вопрос, где при построении дерева не использовалась НИКАКАЯ специфика СУБД, все в рамках Ansi - стандарта. Если за вас УЖЕ извлечены все потомки - это хорошо, здесь показано все с 0 (почти, как format c:).
Не считаю CB круче Делфи, просто пишу на нем, мне удобнее.
И еще не штурмовал, а штурмовалА
← →
Курдль © (2004-05-06 12:18) [40]
> aList.Sort(@SortCompareIndex);
Не обязательно - можно и без @.
> и вообще не понятно к чему твой код :)
Да "не вынесла душа поэта" :))) Привел код, который выстраивает данные в древовидную структуру и еще суммирует остатки по счетам "вверх по иерархии". Это не 10 строк, а аж 30...
← →
Курдль © (2004-05-06 12:29) [41]
> Мунька (06.05.04 12:18) [39]
> Всего-навсего ответила на вопрос, где при построении дерева
> не использовалась НИКАКАЯ специфика СУБД, все в рамках Ansi
> - стандарта. Если за вас УЖЕ извлечены все потомки - это
> хорошо, здесь показано все с 0 (почти, как format c:).
Про "никакую специфику". А если Ваш юзер не имеет привелегий на создание временных таблиц?
И как Вы сами-то оцениваете "select в цикле" с клиента? Это нормально?
← →
Johnmen © (2004-05-06 12:37) [42]>Мунька
>Всего-навсего ответила на вопрос, где при построении дерева не использовалась НИКАКАЯ специфика СУБД,
Неужели ? А что по поводу временной таблицы ? Откуда она ? И что с ней ?
И насколько это эффективно ?
>все в рамках Ansi - стандарта.
В смысле ?
>И еще не штурмовал, а штурмовалА
Виноват. Сразу не сообразил...:)
← →
Мунька (2004-05-06 12:46) [43]>А если Ваш юзер не имеет привелегий на создание временных таблиц?
Таблица создается в шаблоне базе данных не юзером
>И как Вы сами-то оцениваете "select в цикле" с клиента? Это нормально?
Это нормально, поскольку приведенный код не есть клиент-серверное приложение, а программа, функционирующая на одном компе, создание деревьев подразделей - не ее цель, а так, утилита для удобства юзера, не более того
← →
Мунька (2004-05-06 12:47) [44]Вернее сама программа клиент... но в совершенно другом смысле, к БД не имеющем отношение
← →
Курдль © (2004-05-06 12:56) [45]
> Это нормально, поскольку приведенный код не есть клиент-серверное
> приложение, а программа, функционирующая на одном компе,
> создание деревьев подразделей - не ее цель, а так, утилита
> для удобства юзера, не более того
Создание деревьев - это всегда не цель. Чаще всего цель - автоматизация какого-нибудь процесса.
А то, что Ваша программа не гоняет "select + Набор данных" и "insert + Набор данных" тысячи раз за единичный цикл построения дерева по сети, а лишь внутри отдельно взятого компа Вы считаете хорошим основанием?..
← →
Мунька (2004-05-06 13:02) [46]> а лишь внутри отдельно взятого компа Вы считаете хорошим >основанием?..
Скорее не являющимся критичным - из поставленной задачи. Поскольку известно, что дерево подразделений не будет большим, соответсвенно не будет тысяч Select и Insert + требования к ресурсам компа (в силу других решаемых задач) достаточно высоки. Хотя, действительно, использование временной таблицы не есть хорошо в принципе,но в данном случае допустимо - учитывая временные рамки разработки и полное отсутсвие времени на оптимизацию
← →
Соловьев © (2004-05-06 13:04) [47]
> Мунька (06.05.04 12:47) [44]
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=488
тоже не привязано к серверу. Очень поучительная статья
← →
}|{yk © (2004-05-06 13:04) [48]Посмотри код по ссылке. После выполнения 1 запроса далее идет один цикл по полученному результату и строится дерево. Время выполнения и построения минимально
← →
Курдль © (2004-05-06 13:11) [49]
> Скорее не являющимся критичным - из поставленной задачи.
> Поскольку известно, что дерево подразделений не будет большим,
> соответсвенно не будет тысяч Select и Insert + требования
> к ресурсам компа (в силу других решаемых задач) достаточно
> высоки.
А Вы, девушка, не в Microsoft работаете с Вашим замахом на ресурсы? :) Я же привел пример кода, который в тысячи раз эффективнее Вашего. Что может быть проще?
Разве что сканировать ChildLevel только при раскрытии узла, как писал Соловьев © (06.05.04 11:34) [18]
(И это наиболее экономичный способ, если не надо делать никаких "восходящих расчетов", как в моем случае).
← →
Мунька (2004-05-06 13:32) [50]Смею заметить, что Вы не привели кусок кода формирования вашего листа, содержащего дерево
← →
Курдль © (2004-05-06 13:35) [51]
> Мунька (06.05.04 13:32) [50]
> Смею заметить, что Вы не привели кусок кода формирования
> вашего листа, содержащего дерево
Оно немного больше того, которое строите Вы (по функциональности а не размеру кода) - включает в себя разнообразные признаки и графические элементы, но если Вы подтвердите свое желание - след. постом выложу.
← →
}|{yk © (2004-05-06 13:42) [52]Кстати функция формирования дерева
procedure TFormCUST2TREE.GenerateTree(ID: Integer);
var
column: Integer;
Node: tdxTreeListNode;
find: Boolean;
pid: string;
begin
DataModuleMain.APP_CUST2_TREE.Active:=False;
DataModuleMain.APP_CUST2_TREE.ParamByName("VSET_ID").AsInteger:=ID;
DataModuleMain.APP_CUST2_TREE.Active:=True;
DataModuleMain.APP_CUST2_TREE.First;
column:=dxTreeListCUST2TREEMEM_ID.Index;
while not DataModuleMain.APP_CUST2_TREE.Eof do
begin
pid:=DataModuleMain.APP_CUST2_TREEMEM_PID.AsString;
dxTreeListCUST2TREE.StartSearch(column, pid);
find:=dxTreeListCUST2TREE.FocusedNode<>nil;
if (find) then
node := dxTreeListCUST2TREE.FocusedNode.AddChild
else
node := dxTreeListCUST2TREE.Add;
SetNodeValues(Node,DataModuleMain.APP_CUST2_TREEMEM_ID.AsString,DataModuleMain.APP_CUST2_TREEMEM_NAME.AsString,pid);
DataModuleMain.APP_CUST2_TREE.Next;
end;
dxTreeListCUST2TREE.GotoFirst;
end;
← →
Соловьев © (2004-05-06 13:44) [53]
> }|{yk © (06.05.04 13:42) [52]
> Кстати функция формирования дерева
procedure TForm1.FormActivate(Sender: TObject);
begin
DBVirtualStringTree1.LoadTree;
end;
И все :)))
← →
Курдль © (2004-05-06 13:46) [54]
> }|{yk © (06.05.04 13:42) [52]
> Кстати функция формирования дерева
Забавная методика построения дерева методами древовидного компонента :)
← →
Курдль © (2004-05-06 14:03) [55]Ладно, чтобы не быть голословным к своим разглагольствованиям о пользе построения дерева на клиенте приложу код, который был создан несколько лет назад и вместе с [34] успешно реализовывал отображение набора данных, единожды полученного от бд и переписанного в List:
//------------------------------------------------------------------------------
procedure TfrmAccounts.ListToTree(aList: TList);
var i, act, lev: Integer; P: ptrAcc;
dxnArr: array [0..63] of TdxTreeListNode;
begin
dxt1.ClearNodes;
dxnArr[0]:=dxt1.AddFirst; if dxnArr[0]<>nil then dxnArr[0].MakeVisible;
dxnArr[0].Data:=Ptr(0);
dxnArr[0].ImageIndex:=0;
dxnArr[0].SelectedIndex:=1;
dxnArr[0].Strings[0]:="Ðååñòð ñ÷åòîâ";
dxnArr[0].Strings[1]:=dmSB.SelfUlName;
if aList = nil then Exit;
dxt1.Visible:=False;
for i:=0 to aList.Count-1 do
begin
P:=aList.Items[i];
lev:=P.level;
dxnArr[lev]:=dxnArr[lev-1].AddChild; if dxnArr[lev]<>nil then dxnArr[lev].MakeVisible;
dxnArr[lev].Data:=Ptr(P.id);
dxnArr[lev].Strings[0]:=P.num;
dxnArr[lev].Strings[1]:=P.name;
case P.act of
-1: begin
dxnArr[lev].ImageIndex:=2;
dxnArr[lev].SelectedIndex:=3;
dxnArr[lev].Strings[2]:="Àêòèâ";
end;
0: begin
dxnArr[lev].ImageIndex:=4;
dxnArr[lev].SelectedIndex:=5;
dxnArr[lev].Strings[2]:="Àêòèâ/ïàññèâ";
end;
1: begin
dxnArr[lev].ImageIndex:=6;
dxnArr[lev].SelectedIndex:=7;
dxnArr[lev].Strings[2]:="Ïàññèâ";
end;
end;
case P.col of
1: begin
dxnArr[lev].StateIndex:=8;
dxnArr[lev].Strings[3]:="Áàëàíñîâûé";
end;
2: begin
dxnArr[lev].StateIndex:=9;
dxnArr[lev].Strings[3]:="Çàáàëàíñîâûé";
end;
3: begin
dxnArr[lev].StateIndex:=10;
dxnArr[lev].Strings[3]:="Âñïîìîãàòåëüíûé";
end;
else begin
dxnArr[lev].StateIndex:=10;
dxnArr[lev].Strings[3]:="Íå îïðåäåëåí";
end;
end;
if P.dt0<>0 then dxnArr[lev].Values[4]:=P.dt0;
if P.kt0<>0 then dxnArr[lev].Values[5]:=P.kt0;
if lev>1 then dxnArr[lev-1].Collapse(false);
end;
dxt1.FullCollapse;
dxnArr[0].Expand(false);
dxt1.Visible:=True;
end;
//------------------------------------------------------------------------------
← →
}|{yk © (2004-05-06 14:12) [56]>Забавная методика построения дерева методами древовидного компонента :)
Чем забавная? Нет у этого компонента функции загрузки дерева
← →
Курдль © (2004-05-06 14:17) [57]
> }|{yk © (06.05.04 14:12) [56]
> >Забавная методика построения дерева методами древовидного
> компонента :)
> Чем забавная? Нет у этого компонента функции загрузки дерева
Тем и забавная, что применяются методы самого же компонента типаStartSearch
. Я не сказал, что плохая. А о том, что нет метода загрузки мне рассказывать и не надо - см. [55]
← →
goozman (2004-05-14 09:00) [58]Знаете, я почитал ....-Все это полнейший бред!
Вот я решил свою проблему процедурой рекурсии
ВХОД (ROTT)
ИСХОД (ID)
ПЕР(CUR_NODE)
begin
for select d.id
from department d
where d.parent_id = :root
into :id do
begin
suspend;
cur_node = id;
for select id from temp(:CUR_NODE)
into :id do suspend;
end
end
← →
gu_est (2004-05-14 09:28) [59]о чем я и говорил [21], а все уперлись в визуализацию...
← →
Соловьев © (2004-05-14 09:29) [60]
> 59] gu_est
см. первый пост. Там все это уже давно было.
← →
Digitman © (2004-05-14 13:16) [61]
> goozman (14.05.04 09:00) [58]
все верно) ... для концептуального решения задачи достаточно реализации вот такой вот рекурс.ХП
клиент, обращаясь к такой ХП, получает курсор НД и волен двигать его как угодно - хоть для позиционирования/выборки одной нужной ему записи, хоть для позиц-я/выборки всего результирующего НД .. а уж как клиент будет всю эту бодягу визуализировать - это не проблема сервера)
← →
}|{yk © (2004-05-14 13:43) [62]А в [38] и [48] я что предлагал, не рекурсию?
Страницы: 1 2 вся ветка
Форум: "Базы";
Текущий архив: 2004.06.06;
Скачать: [xml.tar.bz2];
Память: 0.68 MB
Время: 0.044 c