Форум: "Базы";
Текущий архив: 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
кстати, спасибо за затраченное время :-)
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2002.01.24;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.004 c