Форум: "Базы";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.01.24;
Скачать: [xml.tar.bz2];




Вниз

Забавный глюк... (наверно у меня...) 


Boo   (2001-12-17 10:26) [0]

Если кому не лень, посмотрите мой ответ на http://delphi.mastak.ru/cgi-bin/forum.pl?look=1&id=1008457411&n=1

Дык вот. если вызывать рекурсию InsertTree(nil, 0);, то все нормально неограниченное количество раз...

А если: InsertTree(Rub.Selected, Pred);, где Rub.Select - ветка TTreeNode, то после формирования ветки (когда выполняется последний в рекурсии Rubr.Free) прога вылетает вообще (ни здрасти не досвиданья, вот она была, а теперь и следов нету)... В Дельфе выдает регистры процессора и все...

Может у меня руки не оттуда растут?

Советы есть?



Boo   (2001-12-17 10:45) [1]

Решил на всякий случай сюда кинуть код:

procedure TForm12.InsertTree(Tec:TTreeNode; Ident:Integer);
Var Rubr:TQuery;
Ne:TTreeNode;
begin
{Занесение}
Rubr:=TQuery.Create(nil);
Rubr.databaseName:="DB";
Rubr.SQL.Clear;
Rubr.SQL.Add("Select * from PMRazdel where Predoc=:Pre order by Ident");
Rubr.Params[0].asInteger:=Ident;
Rubr.Open;
While not Rubr.EOF do begin
Ne:=Rub.Items.AddChild(Tec, Rubr.FieldByName("Ident").asString+" "+Rubr.FieldByName("Name").asString);
InsertTree(Ne, Rubr.FieldByName("Ident").asInteger);
Rubr.Next;
end;
Rubr.Close;
Rubr.Free;
end;



Boo   (2001-12-17 11:10) [2]

Отладчик Дельфы выдает:
Access violation at adress 40003470 in module "vck50.bpl". Write of adress 02E91000. Круто, не правдали?



gek   (2001-12-17 11:19) [3]

А зачем Rubr:=TQuery.Create(nil);
Сделай Rubr:=TQuery.Create(self);



Boo   (2001-12-17 11:23) [4]

> gek
Не помогает...



gek   (2001-12-17 11:29) [5]

А где ты Ne содаешь я что-то не вижу
И я так понимаю эта ошибка в цикле у тебя происходит



Boo   (2001-12-17 13:11) [6]

А зачем его создавать-то? (все равно потом присвоение идет)
Ошибка вылетает при окончании рекурсии на инструкции Rubr.Free, почему - ХЗ
Тут самое интересное в том, что при создании ВСЕГО дерева (с nil), все нормально. а вот когда только какую-нибудь ветку - очень грубый вылет :-)
Кстати, вызов перерисовки ветки:

Rub.Selected.DeleteChildren;
InsertTree(Rub.Selected, Pred);

Может здесь ошибка?



gek   (2001-12-17 13:28) [7]

Я вообще-то по-другому бы написал.
Ну зачем содавать в runtime кинь на форму TQuery
и юзай все че надо
И еще смотри ты постоянно создаешь кучу TQuery а освобождаешь только один раз Rubr.Free;
да и рекурсия какая-то странная зачем постоянно делать запросы это ж так тормозить будет
создавай TQuery один раз



Boo   (2001-12-17 13:33) [8]

угу, и постоянно по ней (ТQuery) бегать (искать записи для текущего уровня дерева)?
А так получается просто: для каждого уровня свой TQuery, и надо просто пробежаться по нему...
Хотя не спорю, памяти и времени жрет... но код проще для понимания...
да и Rub.Free выполняется (должен выполняться) на каждой ступеньке рекурсии, так что по идее ВСЕ TQUERY должны изчезнуть...



gek   (2001-12-17 13:41) [9]

Вот как-раз таки Rub.Free будет выполнен только один раз



Boo   (2001-12-17 14:00) [10]

Почему? ведь она теле процедуры рекурсии...



gek   (2001-12-17 14:20) [11]

Попробуй поставить проверку типа
if Rubr <> nil then
Rubr:=TQuery.Create(self);
и в самом конце
Rubr.free;
Rubr:=nil;



AlexSV   (2001-12-18 11:37) [12]

Позвольте подсоединиться к диспуту.
А если процедуру немного модифицировать?
Думаю сразу все откроется.

procedure TForm12.InsertTree(Tec:TTreeNode; Ident:Integer);
Var Rubr:TQuery;
Ne:TTreeNode;
begin
{Занесение}
Rubr:=TQuery.Create(nil);
// вообще-то не помешает
try

Rubr.databaseName:="DB";
Rubr.SQL.Clear;
Rubr.SQL.Add("Select * from PMRazdel where Predoc=:Pre order by Ident");
Rubr.Params[0].asInteger:=Ident;
// и здесь
try
Rubr.Open;
While not Rubr.EOF do begin
Ne:=Rub.Items.AddChild(Tec, Rubr.FieldByName("Ident").asString+" "+Rubr.FieldByName("Name").asString);
InsertTree(Ne, Rubr.FieldByName("Ident").asInteger);
Rubr.Next;
end;
Rubr.Close;
except
// здесь, надеюсь, понятно
end;
// и закрываем
finally
Rubr.Free;
end;

end;



Boo   (2001-12-18 16:29) [13]

>AlexSV
Все намного хуже: прога не вылетает (с ошибкой) как обычно, а улетает (в неизвестность), т.е. просто изчезает...
Следовательно try-except здесь не помогут (хотя я попробовал)

Да и вылетает именно на Rubr.Free, а вот почему - ХЗ, может всетаки из-за Rub.Selected.DeleteChildren, т.е. удаляется вся ветка, а потом заполняется...



AlexSV   (2001-12-19 16:39) [14]

предыдущее предложение сделал по общему виду.
А теперь решил попробовать.

На форму бросил TreeView.
Самой форме:
procedure TForm1.FormShow(Sender: TObject);
begin
InsertTree(nil, 0);
end;

Собственно TreeView:
procedure TForm1.TVExpanding(Sender: TObject; Node: TTreeNode;
var AllowExpansion: Boolean);
begin
Node.DeleteChildren;
InsertTree(Node, Integer(Node.Data));
end;

И саму процедуру:
procedure TForm1.InsertTree(Tec:TTreeNode; Ident:Integer);
Var Rubr:TQuery;
Ne:TTreeNode;
begin
{Занесение}
Rubr:=TQuery.Create(nil);
try
Rubr.databaseName:=".\DB";
Rubr.SQL.Clear;
Rubr.SQL.Add("Select * from DB where Predoc=:Pre order by Ident");
Rubr.Params[0].asInteger:=Ident;
try
Rubr.Open;
While not Rubr.EOF do begin
Ne:=TV.Items.AddChild(Tec, Rubr.FieldByName("Ident").asString+" "+Rubr.FieldByName("Name").asString);
// Вот это я добавил (чтоб привязать как то Ident к Node) Ne.Data := Pointer(Rubr.FieldByName("Ident").asInteger);
InsertTree(Ne, Integer(Ne.Data));
Rubr.Next;
end;
Rubr.Close;
except
ShowMessage("Exeption");
end;
finally
Rubr.Free;
end;
end;

Работает без вопросов (только в таблице записей 15 :( лень набирать больше)

PS: Для скорости приделал таблицу Paradox поэтому проверь настройки Query.

Пока.



Boo   (2001-12-20 09:09) [15]

Отличие (принципиальное) лиш в
Ne.Data := Pointer(Rubr.FieldByName("Ident").asInteger);
И всегда работает? Даже когда только одна ветка делается?

У себя щас попробую...



Boo   (2001-12-20 09:14) [16]

:-) Полный даун...

>AlexSV
Может дело не в коде? а скажем в системе... у меня Win2000



AlexSV   (2001-12-20 14:41) [17]

Давай по порядку:

1. Я тестировал на парадоксе + количество записей 15 - 20.
2. Количество Child-ов - 3,4 (соответственно рекурсия малая).

Что рекомендую посмотреть:
1. Все таки глубину рекурсии - установи в модуле счетчик
и Inc при входе, Dec при выходе. (Где-то его смотри).
2. Поскольку MSSQL то посмотри его настройки на connect-ы и sesstion-ы.
3. Где DataSet - на клиенте или сервере?

Вообщем рекомендую сначала минимизировать набор данных, а потом смотреть.

PS:
1. А все-же лучше получить набор целиком, а потом при обработке фильтровать (если на фильтре и потери, то во всяком случае разгрузка траффика и все то-же количество TQuery)
2. Если дерево целиком грузится, то система не при чем.
Пока.



Boo   (2001-12-21 09:42) [18]

Круто!
кол-во записей около сотни
максимум 4 уровня вложенности
максимальная глубина рекурсии: 5 (проверял трассировкой, хотя енто было лишнее)

Чуть позже попробую с одним TQuery (а то правду запрос до фени :-))



Boo   (2001-12-21 09:44) [19]

>AlexSV
кстати, спасибо за затраченное время :-)




Форум: "Базы";
Поиск по всему сайту: delphimaster.net;
Текущий архив: 2002.01.24;
Скачать: [xml.tar.bz2];




Наверх





Память: 0.76 MB
Время: 0.019 c
1-75589           Vacheslav             2002-01-07 13:21  2002.01.24  
Как обработать


3-75512           Igo                   2001-12-20 17:27  2002.01.24  
сумма в подчин. ..Grid


1-75573           Lotus                 2002-01-05 15:27  2002.01.24  
Проверка выражения на true/false НУЖНА ПОМОЩЬ!!!


7-75696           Алексей Саньков       2001-10-05 21:55  2002.01.24  
Как сделать в Винде 256 цветов 640х480 на видюхе Acumos


7-75704           Lizard                2001-10-07 15:55  2002.01.24  
Как остановить отправку сообщения ?