Форум: "Базы";
Текущий архив: 2004.06.20;
Скачать: [xml.tar.bz2];
ВнизИерархическая БД и TreeView Найти похожие ветки
← →
V l a d i m i r (2004-05-26 21:20) [0]Уважаемые мастера, подскажите, пожалуйста, в чем ошибка в ниже приведенном коде... С иерархическими базами столкнулся впервые и поэтому смысл рекурсивного запроса, который я взял в одной статье, понимаю, а в чем ошибка - это уже загадка, которую могу только методом тыка исправить.:))Вот выдержка статьи и ошибка в реализации процедуры GetExpandingItems (помечено жирным):
Для реализации перечитывания записей по "распахиванию" ветви дерева можно использовать приведенный ниже запрос с выборкой элементов одной ветви.procedure TMainForm.NodeViewExpanding(Sender: TObject; Node: TTreeNode;
var AllowExpansion: Boolean);
begin
GetExpandingItems(Node);
end;
Допустим, что у нас на форме есть компонент Query1, который содержит запросSELECT * FROM OBJECTS
WHERE PARENT = :Parent
Процедура GetExpandingItems может быть реализована следующим образом:procedure TMainForm.GetExpandingItems(var Node: TTreeNode)
var NewNode: TTreeNode;
begin
{ если не передан "раскрываемый" узел, то это самый первый узел.
иначе нужно в качестве Parent передать в запрос идентификатор
элемента, который мы не совсем корректно будем хранить в
Node.Data
как целое число а не как указатель на структуру данных)}
if Node = nil then
Query1.ParamByName("Parent").asInteger:=0
else
begin
Query1.ParamByName("Parent").asInteger:=integer(Node.Data);
Node.DeleteChildren; { удалить "подэлементы" если они были }
end;
Query1.Open;
Query1.First;
while not Query1.EOF do
begin
NewNode:=TreeView1.Items.AddChildObject(Query1.FieldByName("NAME").asString);
integer(NewNode.Data):=Query1.FieldByName("ID").asInteger;
Query1.Next;
end;
Query.Close;
end;
После выполнения этой функции создаются элементы, дочерние для указанного Node, или корневые элементы если Node=nil.
← →
jack128 © (2004-05-26 21:29) [1]
> NewNode:=TreeView1.Items.AddChildObject(Query1.FieldByName("NAME").asString);
>
> integer(NewNode.Data):=Query1.FieldByName("ID").asInteger;
>
> Query1.Next;
NewNode.HasChildren := True;
← →
V l a d i m i r (2004-05-26 21:35) [2]К сожалению, у меня сейчас нет рядом Delphi, но ошибка компиляции примерно следующая: "Не могу сравнить типы String и Node"...
← →
jack128 © (2004-05-26 21:38) [3]угу и еще вот это
> NewNode:=TreeView1.Items.AddChild(Node, Query1.FieldByName("NAME").asString);
>
← →
V l a d i m i r (2004-05-26 21:43) [4]Спасибо, приду домой-попробую...
А вот вinteger(NewNode.Data):=Query1.FieldByName("ID").asInteger
что ему (компилятору) не понравилось?
← →
jack128 © (2004-05-26 21:49) [5]Когда дайдешь домой, компильнёшь исходник - тогда и увидешь что там ему не понравилось. Будет английским по белому написано..
← →
V l a d i m i r (2004-05-26 21:51) [6]Ок, спасибо за помощь..
← →
Vlad © (2004-05-26 21:55) [7]asInteger это проперть вобще-то.
Ты пытаешься присвоить указатель на проперть.
Вобще это не так делается.
Нужно создавать самому указатель, ручками выделять под него память, и делать AddObject(node, pointer)
← →
jack128 © (2004-05-26 21:58) [8]
> asInteger это проперть вобще-то.
> Ты пытаешься присвоить указатель на проперть.
AsInteger тут вообще не причем. Ты тоже почитай сообщение об ошибке ;-)
← →
Vlad © (2004-05-26 22:22) [9]
> jack128 © (26.05.04 21:58) [8]
то сообщение которое он привел возникает вот в этой строчке:
NewNode:=TreeView1.Items.AddChildObject(Query1.FieldByName("NAME").asString);
И это понятно, в качестве ноды ему пытаются передать свойство типа String, а так же отсутствует второй параметр pointer
Но в [4] возникает уже другая ошибка :-)
← →
jack128 © (2004-05-26 22:28) [10]
> Vlad © (26.05.04 22:22)
-Семён Семёныч..
-A-a-a!!!!(с) :-))
← →
Vlad © (2004-05-26 22:34) [11]Есть же вредители, которые такие статьи пишут.
Вот где бы синий карандашик пригодился...
← →
jack128 © (2004-05-26 22:38) [12]
> Вот где бы синий карандашик пригодился...
Вот оно - идейное падение ;-))
← →
Vlad © (2004-05-26 22:41) [13]
> jack128 © (26.05.04 22:38) [12]
> идейное падение
В каком смысле ? :-)
← →
jack128 © (2004-05-26 22:50) [14]
> В каком смысле ? :-)
насколько я помню ты выступал против синих карандашей? Или мя глючит?
← →
Vlad © (2004-05-26 22:59) [15]
> jack128 © (26.05.04 22:50) [14]
(рискуя быть удаленным)
Да, это так, мое мнение не изменилось.
По поводу карандаша это я смайлик забыл добавить.
Но автор сказал, что этот код он взял из какой-то статьи.
Статья - не форум, там не пообсуждаешь ошибки. Так что... такие статьи нужно либо не публиковать либо... то что я забыл смайликом выделить :-)
← →
jack128 © (2004-05-26 23:11) [16]
> По поводу карандаша это я смайлик забыл добавить
зато я не забыл ;-)
Во искупление нашего оффтопа:
> integer(NewNode.Data):=Query1.FieldByName("ID").asInteger
сообщение говорит, что этому выражению integer(NewNode.Data) не может быть пресвоено значение. Почему? Потому что на самом деле это выражение эквивалентно примерно такому Integer(NewNode.GetData()) := ... то есть налицо попытка присвоить значение результату функции - очевидный бред.
А вот такое выражение Integer(NewNode) := 0 компилятор пропустит..
← →
Vlad © (2004-05-26 23:17) [17]
> jack128 © (26.05.04 23:11) [16]
угу...точно.
Семен Семеныч :-)
← →
Vlad © (2004-05-26 23:24) [18]Вот, как крутые пацаны делают (из справки, по скольку автору лень туда заглянуть)
The following code defines a record type of TMyRec and a record pointer type of PMyRec.
type
PMyRec = ^TMyRec;
TMyRec = record
FName: string;
LName: string;
end;
Assuming these types are used, the following code adds a node to TreeView1 as the last sibling of a specified node. A TMyRec record is associated with the added item. The FName and LName fields are obtained from edit boxes Edit1 and Edit2. The Index parameter is obtained from edit box Edit3. The item is added only if the Index is a valid value.
procedure TForm1.Button1Click(Sender: TObject);
var
MyRecPtr: PMyRec;
TreeViewIndex: LongInt;
begin
New(MyRecPtr);
MyRecPtr^.FName := Edit1.Text;
MyRecPtr^.LName := Edit2.Text;
TreeViewIndex := StrToInt(Edit3.Text);
with TreeView1 do
begin
if Items.Count = 0 then
Items.AddObject(nil, "Item" + IntToStr(TreeViewIndex), MyRecPtr)
else if (TreeViewIndex < Items.Count) and (TreeViewIndex >= 0) then
Items.AddObject(Items[TreeViewIndex], "Item" + IntToStr(TreeViewIndex), MyRecPtr);
end;
end;
After an item containing a TMyRec record has been added, the following code retrieves the FName and LName values associated with the item and displays the values in a label.
procedure TForm1.Button2Click(Sender: TObject);
begin
Label1.Caption := PMyRec(TreeView1.Selected.Data)^.FName + " " +
PMyRec(TreeView1.Selected.Data)^.LName;
end;
Единственное, чего тут нехватает, так это Dispose при уничтожении дерева.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2004.06.20;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.037 c