向TListView插入数据太慢,有什么方法提高速度?

haifengs 2003-05-06 09:39:23
向TListView插入数据太慢,有什么方法提高速度?

如插入一万条记录时,会很慢。

各位大侠, 有什么好方法吗

我不想分页
...全文
200 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
copy_paste 2003-05-07
  • 打赏
  • 举报
回复
TreeView好像没有提供Virtual的东西,reallike你不会说在CustomDraw进行画吧?

好像ListView才有,自带的组件。

第三方组件是有TreeView的Virtual的,但自带的我倒是一直没找到过有。
copy_paste 2003-05-07
  • 打赏
  • 举报
回复
reallike
TreeView自带的能提供Virtual技术吗?

有没例子?
reallike 2003-05-07
  • 打赏
  • 举报
回复
网友建议他们用普通技术插入50000条记录需要7分钟,而用virtual需要45秒。
reallike 2003-05-07
  • 打赏
  • 举报
回复
用Virtual 技术。不管ListView 还是TreeView最好都用Virtual技术。
copy_paste 2003-05-07
  • 打赏
  • 举报
回复
http://61.132.118.185:8080/datanew/myreader1.02.zip

那里有个ListView,你看看,就是个例子。
copy_paste 2003-05-07
  • 打赏
  • 举报
回复
用Vistual List 技术。

将ListView1.OwnerData 设为True,然后看OwnerData, OnData的帮助,很简单。。。速度N快。。。
gytyl 2003-05-07
  • 打赏
  • 举报
回复
我记得好像可以用一个TListItem的东西
先将所有的数据写进去
然后一次将TListItem里面的东西写到ListView中
不过估计也快不了多少。
myyanghua 2003-05-07
  • 打赏
  • 举报
回复
ListView本来就很慢,如果想快就别用它。
可以用StringGrid
踢踏 2003-05-07
  • 打赏
  • 举报
回复
确实是这样的,数据量太大,还是使用数据控件好。你使用ListView不知道要达到什么特殊效果?
haifengs 2003-05-07
  • 打赏
  • 举报
回复
抱歉 打到了 BEGINUPDATE
ENDUPDATE
可是
效果不如意
踢踏 2003-05-07
  • 打赏
  • 举报
回复
myListview.Items.BeginUpdate;
try
......
finally
myListView.Items.EndUpdate;
end;
xiaoyuer0851 2003-05-07
  • 打赏
  • 举报
回复
呵呵,楼上的各位,
在给别人做一个 listview 时,我也遇到了同样的问题

谢谢各位了,请指点 ~~~
meiwn 2003-05-07
  • 打赏
  • 举报
回复
同意上面的
haifengs 2003-05-07
  • 打赏
  • 举报
回复
BEGINUPDATE
ENDUPDATE
我是想要这个功能
可是 没有发现有这个两个函数

也就是说
现在大概是每插入一条记录都要更新一次画面了
reallike 2003-05-07
  • 打赏
  • 举报
回复
对了,你可以下在那个OnlyPackage那个。不大。

你下载的1M的那个里面有demo的。
reallike 2003-05-07
  • 打赏
  • 举报
回复
嗬嗬,要不要我给你把关键的贴出来?
copy_paste 2003-05-07
  • 打赏
  • 举报
回复
那玩意太大了,1M,

以前记得下载过,也是1M多,累啊,想着ListView有Virtual就凑和着用,可没想到TreeView也是如此。。。算了。。。先不管了,遇到真要用的时候,再去研究
reallike 2003-05-07
  • 打赏
  • 举报
回复
你说的我理解有错误的。好像自带的确实没有。
reallike 2003-05-07
  • 打赏
  • 举报
回复
给的那个是第三方组件的网址。

源代码:

Type PItemInfo = ^TItemInfo;
TItemInfo = Record
Typ : Integer; //folder or item
ID : Integer; //RecordID
PID : Integer; //ParentID
Name : String[50];
end;



Function TF_AG.FindParent(Tree : TVirtualStringTree; ID,TYP : Integer) : PVirtualNode;
var I : Integer;
Node : PVirtualNode;
AData : PItemInfo;
found : Boolean;
begin
Result := Nil;
Node := Tree.GetFirstNode;
found := False;
while (Node <> nil) and not(found) do
begin
Adata := Tree.GetNodeData(Node);
found := (AData.ID = ID) and
(AData.Typ = Typ);
if not Found then
Node := Tree.GetNext(Node);
end;
If found then
result := Node;
end;


procedure TF_AG.SB_RefreshClick(Sender: TObject);
var
PForm : TfrmProgress;
PCount : Integer;
SNode,ANode : PVirtualNode;
List : TList;
I : Integer;
SCount : Integer;
SData,AData : PItemInfo;
begin
PForm := TfrmProgress.Create(Self);
TreeView1.BeginUpdate;
if Assigned(Parent) then
Parent.Enabled := False;
try
Q_Count.SQL.Text := 'Select Count(AGG_ID) From AGG';
Try
Q_Count.Prepare;
Q_Count.Open;
PCount := Q_Count.Fields[0].AsInteger;
Q_Count.Close;
except
Raise;
end;
PForm.ProgressBar1.Max := PCount;
PForm.ProgressBar1.Position := 0;
PForm.ProgressBar1.Step := 1;
PForm.Label1.Caption := 'Lade Gruppen für Arbeitsgänge';
Application.ProcessMessages;
PForm.Show;
FTreeInsert := True;
TreeView1.Clear;
List := TList.Create;
Try
//Caching Information
Q_AGG.SQL.Text := 'Select AGG_ID,AGG_PID,AGG_NAME from AGG order by AGG_PID,AGG_NAME';
Q_AGG.Prepare;
try
Q_AGG.Open;
except
raise;
end;
While Not Q_AGG.Eof do
Begin
New(ItemInfo);
ItemInfo^.Typ := 0;
ItemInfo^.ID := Q_AGG.FieldByName('AGG_ID').AsInteger;
If Q_AGG.FieldByName('AGG_PID').IsNull then
ItemInfo^.PID := -1
else
ItemInfo^.PID := Q_AGG.FieldByName('AGG_PID').AsInteger;
ItemInfo^.Name := Q_AGG.FieldByName('AGG_NAME').AsString;
List.Add(ItemInfo);
Q_AGG.Next;
PForm.ProgressBar1.StepIt;
End;
Q_AGG.Close;
//Add Roots First
I := 0;
PForm.ProgressBar1.Max := PCount;
PForm.ProgressBar1.Position := 0;
PForm.ProgressBar1.Step := 1;
PForm.Label1.Caption := 'Ordne Gruppen für Arbeitsgänge';
Application.ProcessMessages;
While I < List.Count do
Begin
If PItemInfo(List[i])^.PID = -1 then
begin

ANode := TreeView1.AddChild(NIL);
AData := TreeView1.GetNodeData(ANode);
AData.ID := PItemInfo(List[I])^.ID;
AData.PID := PItemInfo(List[I])^.PID;
AData.Typ := PItemInfo(List[I])^.Typ;
AData.Name := PItemInfo(List[I])^.Name;
try
Dispose(PItemInfo(List[i]));
except
end;
List.Delete(i);

PForm.ProgressBar1.StepIt;
end
else inc(i);
end;
//Add Rest of Group
While List.Count > 0 do
Begin
SCount := List.Count;
I := 0;
While I < List.Count do
Begin
ANode := FindParent(TreeView1,PItemInfo(List[i])^.PID,0);
If ANode <> Nil then
Begin
ANode := TreeView1.AddChild(ANode);
AData := TreeView1.GetNodeData(ANode);
AData.ID := PItemInfo(List[I])^.ID;
AData.PID := PItemInfo(List[I])^.PID;
AData.Typ := PItemInfo(List[I])^.Typ;
AData.Name := PItemInfo(List[I])^.Name;
try
Dispose(PItemInfo(List[i]));
except
end;
List.Delete(i);
PForm.ProgressBar1.StepIt;
end
else inc(i);
end;
//Konnte nichts mehr zugeordnet werden,
//und es liegen noch Einträge vor,
//dann kann was nicht stimmen
If List.Count = SCount then
Raise Exception.Create('Es liegt ein Dateninkonsistenz vor!'+#10+'Benachrichtigen Sie den Entwickler!');
end;
finally
List.Free;
end;
//Nun zu den Nicht-Gruppen Einträgen
i := 0;
Q_Count.SQL.Text := 'Select Count(AG_ID) From AG';
Try
Q_Count.Prepare;
Q_Count.Open;
PCount := Q_Count.Fields[0].AsInteger;
Q_Count.Close;
except
Raise;
end;
PForm.ProgressBar1.Max := PCount;
PForm.ProgressBar1.Position := 0;
PForm.ProgressBar1.Step := 1;
PForm.Label1.Caption := 'Lade und Ordne Items für Arbeitsgänge';
Application.ProcessMessages;
Q_AG.Open;
try
While Not Q_AG.Eof do
begin
SNode := FindParent(TreeView1,Q_AG.FieldByName('AG_AGG_ID').AsInteger,0);
if assigned(SNode) then
begin
ANode := TreeView1.AddChild(SNode);
AData := TreeView1.GetNodeData(ANode);
AData.Typ := 1;
AData.ID := Q_AG.FieldByName('AG_ID').AsInteger;
AData.PID := 0;
AData.Name := Q_AG.FieldByName('AG_NAME').AsString;
PForm.ProgressBar1.StepIt;
end
else
Raise Exception.Create('Es liegt ein Dateninkonsistenz vor!'+#10+'Benachrichtigen Sie den Entwickler (2)!');
Q_AG.Next;
end;
finally
Q_AG.Close;
end;
FTreeInsert := False;
TreeView1.FullCollapse;
If TreeView1.GetFirstNode <> Nil then
begin
TreeView1.Selected[TreeView1.GetFirstNode] := True;
TreeView1.FocusedNode := TreeView1.GetFirstNode;
end;
FAG_EditContext := AGG;
FAG_EditState := AG_Browse;
AdJustNav;
finally
if Assigned(Parent) then
Parent.Enabled := True;
TreeView1.EndUpdate;
PForm.Release;
Application.ProcessMessages;
end;
end;

注释是德文,我也看不懂。:)

reallike 2003-05-07
  • 打赏
  • 举报
回复
Treeview可以的。

真的。有个人问了从数据库往节点上加的问题。我正好知道。

一个德国网友给我提出,太慢了。给我这么一个网站,

http://www.delphi-gems.com/VirtualTreeview/VT.php

还有,他写的一些代码。先看看再说吧。
加载更多回复(4)

5,916

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧