我有此数据库表:
client1 bank1 test1
client1 bank1 test2
client1 bank2 test1
clientx bank2 test2
我应该得到像这样的树
client1 - bank1 - test1
- test2
- bank2 - test1
clientX - bank2 - test2
但是我无法按文本进行分组,而我会得到像
这样的树 client1 - bank1 - test1
client1 - bank1 - test2
client1 - bank2 - test1
clientX - bank2 - test2
代码我有:
repeat
RootNode := TreeAnaliza.Items.AddObject(nil, q.FieldByName('Client').AsString, nil);
MiddleNode := TreeAnaliza.Items.AddChildObject(RootNode, q.FieldByName('bank').AsString, nil);
LowestNode:= TreeAnaliza.Items.AddChildObject(ParentNode, q.FieldByName('test').AsString, nil);
q.Next;
until q.Eof;
我认为我应该检查每个节点,如果在该级别上有相同文本的节点。我该如何实现?
答案 0 :(得分:1)
您每次都添加一个根节点。如果客户端发生更改,则仅应添加一个根节点。中间节点也是如此。假设您的数据库按您的意愿进行了排序,那么就足够了:
RootNode := nil;
MiddleNode := nil;
repeat
if assigned(RootNode) then
begin
if not SameText( RootNode.Text, q.FieldByName('Client').AsString) then
begin
RootNode := TreeAnaliza.Items.AddObject(nil, q.FieldByName('Client').AsString, nil);
MiddleNode := nil;
end;
end
else
begin
// not assigned so definitely required
RootNode := TreeAnaliza.Items.AddObject(nil, q.FieldByName('Client').AsString, nil);
MiddleNode := nil;
end;
if assigned( MiddleNode ) then
begin
if not SameText( MiddleNode.Text, q.FieldByName('bank').AsString) then
begin
MiddleNode := TreeAnaliza.Items.AddChildObject(RootNode, q.FieldByName('bank').AsString, nil);
end;
end
else
begin
MiddleNode := TreeAnaliza.Items.AddChildObject(RootNode, q.FieldByName('bank').AsString, nil);
end;
LowestNode:= TreeAnaliza.Items.AddChildObject(ParentNode, q.FieldByName('test').AsString, nil);
q.Next;
until q.Eof;
您可能可以整理一下。
答案 1 :(得分:1)
是的,您确实需要检查现有节点,然后才能在给定级别添加具有相同文本的新节点,例如:
function EnsureNode(ATree: TTreeView; AParent: TTreeNode; const AText: string);
var
LNode: TTreeNode;
begin
Result := nil;
if AParent <> nil then
LNode := AParent.getFirstChild
else
LNode := ATree.Items.GetFirstNode;
while LNode <> nil do
begin
if LNode.Text = AText then
begin
Result := LNode;
Exit;
end;
end;
if AParent <> nil then
Result := ATree.Items.AddChild(AParent, AText)
else
Result := ATree.Items.Add(nil, AText);
end;
...
while not q.Eof do
begin
RootNode := EnsureNode(TreeAnaliza, nil, q.FieldByName('Client').AsString);
MiddleNode := EnsureNode(TreeAnaliza, RootNode, q.FieldByName('bank').AsString);
LowestNode := EnsureNode(TreeAnaliza, MiddleNode, q.FieldByName('test').AsString);
q.Next;
end;
或者,使用TDictionary
来跟踪已经添加的节点,例如:
var
Dict: TDictionary<string, TTreeNode>;
LKey, LText: string;
begin
...
Dict := TDictionary<string, TTreeNode>.Create;
try
while not q.Eof do
begin
LText := q.FieldByName('Client').AsString;
LKey := LText;
if not Dict.TryGetValue(LKey, RootNode) then
begin
RootNode := TreeAnaliza.Items.Add(nil, LText);
Dict.Add(LKey, RootNode);
end;
LText := q.FieldByName('bank').AsString;
LKey := LKey + #1 + LText;
if not Dict.TryGetValue(LKey, MiddleNode) then
begin
MiddleNode := TreeAnaliza.Items.AddChild(RootNode, LText);
Dict.Add(LKey, MiddleNode);
end;
LText := q.FieldByName('test').AsString;
LKey := LKey + #1 + LText;
if not Dict.TryGetValue(LKey, LowestNode) then
begin
LowestNode := TreeAnaliza.Items.AddChild(MiddleNode, LText);
Dict.Add(LKey, LowestNode);
end;
q.Next;
end;
finally
Dict.Free;
end;
...
end;