我有一个数据库结构如下:
字段名 字段类型
编号 字符型
部门名称 字符型数据库中的记录如下:
编号 部门名称
0001 创业公司软件部
000101 业务部
00010101 业务部一号小组
00010102 业务部二号小组
000102 开发部 问题一、
现在我需要把数据库中记录在Treeview中按以下结构显示出来,
用Query数据控件(我以前是用Table不太好用),我对SQL语法不是很熟。
创业公司软件部
|---业务部
| |
| |-----业务部一号小组
| |
| |-----业务部二号小组
|
|---开发部 问题二、
我要在创业公司软件部下面在增加子项时编号要求自动生成,
或要在开发部下面增加子项时编号要求自动生成,
例如:在一个窗体上有一个Edit框中输入部门名称,编号不用输入自动生成,
这个树形结构是用部门名称来产生的,上面的数据库编号记录已有0001、000101、00010101、00010102、000102,
那如果我在树形结构中点击 0001 创业公司软件部增加子项时那产生的是记录编号和记录就是000103 资源部;
那如果我在树形结构中点击000102 开发部增加子项时那产生的记录编号和记录就是00010201 开发部一号小组,
也就是说不能产生重复的编号,数据增加完毕后要在树形结构中显示出来(就是要把数据添加进数据库);
请高手指教!
字段名 字段类型
编号 字符型
部门名称 字符型数据库中的记录如下:
编号 部门名称
0001 创业公司软件部
000101 业务部
00010101 业务部一号小组
00010102 业务部二号小组
000102 开发部 问题一、
现在我需要把数据库中记录在Treeview中按以下结构显示出来,
用Query数据控件(我以前是用Table不太好用),我对SQL语法不是很熟。
创业公司软件部
|---业务部
| |
| |-----业务部一号小组
| |
| |-----业务部二号小组
|
|---开发部 问题二、
我要在创业公司软件部下面在增加子项时编号要求自动生成,
或要在开发部下面增加子项时编号要求自动生成,
例如:在一个窗体上有一个Edit框中输入部门名称,编号不用输入自动生成,
这个树形结构是用部门名称来产生的,上面的数据库编号记录已有0001、000101、00010101、00010102、000102,
那如果我在树形结构中点击 0001 创业公司软件部增加子项时那产生的是记录编号和记录就是000103 资源部;
那如果我在树形结构中点击000102 开发部增加子项时那产生的记录编号和记录就是00010201 开发部一号小组,
也就是说不能产生重复的编号,数据增加完毕后要在树形结构中显示出来(就是要把数据添加进数据库);
请高手指教!
请留下E-Mail址,我把源代码发给你,谢谢。
问题1:因为节点的位置信息都存在编号字段中,所以可以根据它就可以显示treeview了,先select 编号,部门名称,(select count(*) from 你的表 where 编号<=left(编号,len(编号)-2)) as theparent from 你的表 order by 编号
这样就会按照treeview节点的绝对index的顺序排序了,然后一个节点一个节点的添加就行了,添加时他的父节点的绝对index就是theparent字段值,这样就应该ok了
问题2:添加时可以先在treeview中添加,然后根据新加的节点信息再生成编号值插到库中就行了,这你可以再写一个函数,参数是节点的index 返回string类型的编号值。
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids, DBGridEh, ComCtrls, ExtCtrls, DB, ADODB,
DBGrids, Menus, DBCtrls;type
PMyRec = ^TMyRec;
TMyRec = record
DepartName : string;
DepartNo : string;
end;
TForm1 = class(TForm)
DataSource1: TDataSource;
Panel2: TPanel;
Panel3: TPanel;
TreeView1: TTreeView;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
tmp: TADOTable;
PopupMenu1: TPopupMenu;
N1: TMenuItem;
N2: TMenuItem;
ADOConnection1: TADOConnection;
N3: TMenuItem;
N4: TMenuItem;
N5: TMenuItem;
N6: TMenuItem;
N7: TMenuItem;
procedure InsertNode;
procedure delNode;
procedure fetchdata(DepartNo: string; CurNode:TTreeNode);
procedure deletedata(DepartNo: string);
procedure updatedata(DepartNo, departname: string);
procedure AddDataToTable(DEPARTNAME,DEPARTNO,PREDEPART:String);
procedure FormShow(Sender: TObject);
procedure N1Click(Sender: TObject);
procedure N2Click(Sender: TObject);
procedure N4Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure N5Click(Sender: TObject);
procedure TreeView1Edited(Sender: TObject; Node: TTreeNode;
var S: String);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.AddDataToTable(DEPARTNAME,DEPARTNO,PREDEPART:String);
begin
if not tmp.Active then
tmp.Active := true; tmp.Append;
tmp.FieldByName('DEPARTNAME').Value := DEPARTNAME;
tmp.FieldByName('DEPARTNO').Value := DEPARTNO;
tmp.FieldByName('PREDEPART').Value := PREDEPART;
tmp.Post; if tmp.Active then
tmp.Close;
tmp.Active := true;
end;procedure TForm1.fetchdata(DepartNo: string; CurNode:TTreeNode);
var
MyRecPtr: PMyRec;
zIndex : integer;
tmpStr:String;
Node1 : TTreeNode;
tmpadq:TADOQuery;
begin
tmpadq := TADOQuery.Create(nil);
try
tmpadq.Connection := ADOConnection1;
tmpStr:= ' SELECT * FROM DEPART2 WHERE PREDEPART = ' + QuotedStr(DepartNo) + ' ORDER BY PREDEPART, DEPARTNO';
tmpadq.Close;
tmpadq.SQL.Clear;
tmpadq.SQL.Add(tmpStr);
tmpadq.Open;
tmpadq.First;
if tmpadq.RecordCount > 0 then
begin
for zindex:= 1 to tmpadq.RecordCount do
begin
NEW(MyRecPtr);
MyRecPtr.DepartName := tmpadq.FieldByName('DEPARTNAME').AsString;
MyRecPtr.DepartNo := tmpadq.FieldByName('DEPARTNO').AsString;
TreeView1.Selected := CurNode;
Node1 := TreeView1.Items.AddChildObject(CurNode, tmpadq.FieldByName('DEPARTNAME').AsString,MyRecPtr);
fetchdata(tmpadq.FieldByName('DEPARTNo').AsString, Node1);
tmpadq.Next;
end;
end else
begin
exit;
end;
finally
tmpadq.Close;
tmpadq.Free;
end;end;procedure TForm1.FormShow(Sender: TObject);
begin
if not tmp.Active then
tmp.Active := true;
//读入树
fetchdata('0',TreeView1.TopItem);
end;procedure TForm1.InsertNode;
var
MyRecPtr: PMyRec;
CHNode : TTreeNode;
StrName : String;
begin
if not Assigned(Pointer(TreeView1.Selected)) then
exit; case TreeView1.Selected.Level of
0:
StrName:=InputBox('新增公司','请输入公司名称:','');
1:
StrName:=InputBox('新增部门','请输入部门名称:','');
2:
StrName:=InputBox('新增项目组','请输入项目组名称:','');
else
exit;
end;
if Trim(StrName) = '' then
exit;
NEW(MyRecPtr);
MyRecPtr.DepartName := StrName;
MyRecPtr.DepartNo := IntToStr(TreeView1.Items.Count);
CHNode := TreeView1.Items.AddChildObject(TreeView1.Selected, StrName, MyRecPtr); if TreeView1.Selected.Level = 0 then
begin
AddDataToTable(StrName, IntToStr(TreeView1.Items.Count -1), '0');
end else
begin
AddDataToTable(StrName, IntToStr(TreeView1.Items.Count - 1), PMyRec(TreeView1.Selected.Data)^.DepartNo);
end;
TreeView1.Refresh;
TreeView1.Selected := CHNode;
end;procedure TForm1.N1Click(Sender: TObject);
begin
TreeView1.FullExpand;
end;procedure TForm1.N2Click(Sender: TObject);
begin
TreeView1.FullCollapse;
end;
procedure TForm1.N4Click(Sender: TObject);
begin
InsertNode;
end;procedure TForm1.delNode;
var
tmpStr:STring;
begin
if Assigned(Pointer(TreeView1.Selected)) and (TreeView1.Selected.Level > 0)then
begin
case TreeView1.Selected.Level of
1:
tmpStr := '是否删除公司及下属部门数据';
2:
tmpStr := '是否删除部门及下属工作组数据';
3:
tmpStr := '是否删除工作组及下属数据';
end;
if (MessageBox(Handle, PChar(tmpStr), PChar('提示信息'), MB_YESNO or MB_ICONSTOP) = IDYES) then
begin
deletedata(PMyRec(TreeView1.Selected.Data)^.DepartNo);
TreeView1.Selected.Delete;
end;
end;end;procedure TForm1.Button1Click(Sender: TObject);
begin
InsertNode;
end;procedure TForm1.Button3Click(Sender: TObject);
begin
delNode;
end;procedure TForm1.N5Click(Sender: TObject);
begin
delNode;
end;procedure TForm1.deletedata(DepartNo: string);
var
tmpStr:String;
tmpadq:TADOQuery;
begin
tmpadq := TADOQuery.Create(nil);
try
tmpadq.Connection := ADOConnection1;
tmpStr:= ' DELETE FROM DEPART2 WHERE PREDEPART = ' + QuotedStr(DepartNo) + ' or DepartNo =' + QuotedStr(DepartNo);
tmpadq.Close;
tmpadq.SQL.Clear;
tmpadq.SQL.Add(tmpStr);
tmpadq.ExecSQL;
finally
tmpadq.Close;
tmpadq.Free;
end;end;procedure TForm1.updatedata(DepartNo, departname: string);
var
tmpStr:String;
tmpadq:TADOQuery;
begin
tmpadq := TADOQuery.Create(nil);
try
tmpadq.Connection := ADOConnection1;
tmpStr:= ' update DEPART2 set DEPARTNAME = ' + QuotedStr(departname) + ' where DepartNo = ' + QuotedStr(DepartNo);
tmpadq.Close;
tmpadq.SQL.Clear;
tmpadq.SQL.Add(tmpStr);
tmpadq.ExecSQL;
finally
tmpadq.Close;
tmpadq.Free;
end;end;procedure TForm1.TreeView1Edited(Sender: TObject; Node: TTreeNode;
var S: String);
begin
updatedata(PMyRec(Node.Data)^.DepartNo, s);
end;procedure TForm1.Button2Click(Sender: TObject);
begin
ShowMessage(PMyRec(TreeView1.Selected.Data)^.DepartNo);
end;end.
Left = 310
Top = 166
BorderStyle = bsSingle
Caption = #26641#31034#20363
ClientHeight = 250
ClientWidth = 337
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 13
object Panel2: TPanel
Left = 0
Top = 209
Width = 337
Height = 41
Align = alBottom
BevelInner = bvLowered
TabOrder = 0
object Button1: TButton
Left = 8
Top = 9
Width = 75
Height = 25
Caption = #22686#21152
TabOrder = 0
OnClick = Button1Click
end
object Button2: TButton
Left = 88
Top = 9
Width = 75
Height = 25
Caption = #20462#25913
TabOrder = 1
OnClick = Button2Click
end
object Button3: TButton
Left = 168
Top = 9
Width = 75
Height = 25
Caption = #21024#38500
TabOrder = 2
OnClick = Button3Click
end
object Button4: TButton
Left = 248
Top = 9
Width = 75
Height = 25
Caption = #36864#20986
TabOrder = 3
end
end
object Panel3: TPanel
Left = 0
Top = 0
Width = 337
Height = 209
Align = alClient
BevelInner = bvLowered
TabOrder = 1
object TreeView1: TTreeView
Left = 2
Top = 2
Width = 333
Height = 205
Align = alClient
HideSelection = False
Indent = 19
PopupMenu = PopupMenu1
TabOrder = 0
OnEdited = TreeView1Edited
Items.Data = {
010000001F0000000000000000000000FFFFFFFFFFFFFFFF0000000000000000
06D7DCB9ABCBBE}
end
end
object DataSource1: TDataSource
DataSet = tmp
Left = 168
Top = 16
end
object tmp: TADOTable
Connection = ADOConnection1
CursorType = ctStatic
TableName = 'DEPART2'
Left = 216
Top = 40
end
object PopupMenu1: TPopupMenu
Left = 168
Top = 80
object N1: TMenuItem
Caption = #21069#37096#23637#24320
OnClick = N1Click
end
object N2: TMenuItem
Caption = #38065#37096#25910#32553
OnClick = N2Click
end
object N3: TMenuItem
Caption = '-'
end
object N4: TMenuItem
Caption = #22686#21152#33410#28857
OnClick = N4Click
end
object N5: TMenuItem
Caption = #21024#38500#33410#28857
OnClick = N5Click
end
object N6: TMenuItem
Caption = '-'
end
object N7: TMenuItem
Caption = #36864#20986
end
end
object ADOConnection1: TADOConnection
Connected = True
ConnectionString =
'Provider=Microsoft.Jet.OLEDB.4.0;User ID=Admin;Data Source=E:\db' +
'1.mdb;Mode=Share Deny None;Extended Properties="";Persist Securi' +
'ty Info=False;Jet OLEDB:System database="";Jet OLEDB:Registry Pa' +
'th="";Jet OLEDB:Database Password="";Jet OLEDB:Engine Type=5;Jet' +
' OLEDB:Database Locking Mode=1;Jet OLEDB:Global Partial Bulk Ops' +
'=2;Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database P' +
'assword="";Jet OLEDB:Create System Database=False;Jet OLEDB:Encr' +
'ypt Database=False;Jet OLEDB:Don'#39't Copy Locale on Compact=False;' +
'Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=Fal' +
'se'
LoginPrompt = False
Mode = cmShareDenyNone
Provider = 'Microsoft.Jet.OLEDB.4.0'
Left = 104
Top = 24
end
end
我自己尝试着作了一个,但在运行中出现错误,有谁能帮我改一下呀!
请留下E-Mail址,我把源代码发给你,谢谢。
字段为:DEPARTNAME,DEPARTNO,PREDEPART
你可以Access建立一个数据库然后用OLE 连接由于编码用的是树的节点的个数,所以最好别用删除,你可以自己定义一个编码方式然后编码
存到数据库中
我给发给你的源代码的数据库是用dbisam4.05作的,你现在是用Access的数据库,
我要的是用dbisam4.05作的,你可以帮我改一下我发给你的源代码里面的错误吗?
谢谢。
请在此下载源码吧
JnOnlie.meibu.com/TREEVIEW.rar改完的话,发E-Mail给我吧([email protected])
type
PData=^MyData;
MyData=Record
id:string;//integer;
name:string;
AlLoad:boolean;
end;
增加数据:
New(NData);
NData.id:=tqr.FieldByName('id').AsString;//.AsInteger;
Ndata.name:=tqr.FieldByName('Name').AsString;
Ndata.AlLoad:=false;
tmpNode:=Tree.Items.AddChildObject(root,tqr.FieldByName ('Name').AsString,Ndata);
tmpNode.Text:=tqr.FieldByName('Name').AsString;
使用:点击TreeView时的处理
procedure TFrmMain.TVDirClick(Sender: TObject);
var
tmpNode:TTreeNode;begin
tmpNode:=TVDir.Selected;
if tmpNode=nil then exit;
if PData(tmpNode.Data)^.AlLoad then exit;
// tqr.FieldByName('id').AsString LoadSubTreeCon(PData(tmpNode.Data)^.id,tmpNode);
end;提示出错!why??????
PMyRecord = ^MyRecord;
MyRecord = record
ID : integer;
Name:string;
ParentID : integer;
end;//end of recordprocedure pCreateTreeView(Node:TTreeNode;ParentID:integer;
AtvnViewNode:TTreeView;AadoConnection:TADOConnection;AstrSQL:String;
AImageIndex,ASelectedIndex:Integer;AstrFieldName:String);
var
tmpNode : TTreeNode;
ADOTree : TADOQuery;
p : PMyRecord;
begin
ADOTree := TADOQuery.Create(application);
ADOTree.Connection := AadoConnection;
ADOTree.close;
ADOTree.SQL.clear;
//SELECT lx_bh, lx_mc,lx_parentID FROM ESMDqxlx_1 ADOTree.SQL.Text := AstrSQL+' where '+AstrFieldName +' ='+inttostr(ParentID);
ADOTree.open;
if ADOTree.recordcount > 0 then
begin
ADOTree.First;
while not ADOTree.Eof do
begin
new(p);
p.ID := ADOTree.Fields[0].AsInteger;
p.name :=ADOTree.Fields[1].AsString;
p.ParentID := ADOTree.Fields[2].AsInteger;
tmpNode := AtvnViewNode.Items.AddChildObject(Node,p.name,p); if AtvnViewNode.Images<>nil then //有图标时设置图标
begin
tmpNode.SelectedIndex := ASelectedIndex; //选中时图标
tmpNode.ImageIndex := AImageIndex; //没选中时图标
end; {== End If ==} pCreateTreeView(tmpNode,ADOTree.Fields[0].AsInteger,AtvnViewNode,AadoConnection,AstrSQL,AImageIndex,ASelectedIndex,AstrFieldName);
ADOTree.next;
//dispose(p);//一定要去掉这条语句,不然的话,Treeview中的Data也被dispose掉了。
end;
end;
ADOTree.Free;
end;
http://expert.csdn.net/Expert/topic/2946/2946450.xml?temp=.8297998
我现用的是数据库是DBISAM,不是ADO的(如果是ADO的话早就没问题了)
能我看看源代码里的错误怎么改吗?
JnOnlie.meibu.com/TREEVIEW.rar
1.我在调试时,要我给出,一些BISAM 的部分*.pas文件,所以我在delphi的 project --> Options -->directories/conditionals引入了他们,你注意看看
2.是这个出错提示吗?
Access violation at address 0054DA9C in module 'Project1.exe'. Read of address 00000058.
这个出错提示是这个引起的
LSTDM.QryTmp.SQL.Add('select * from tb1'); //出错
原因在 LSTDM.QryTmp 没有初始化,虽然你在 LSBMTreeDMdata.pas单元中已经配置了,但是,还有个问题:在Project1.dpr中.
原来的
program Project1;uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
LSBMTreeDMdata in 'LSBMTreeDMdata.pas' {LSTDM: TDataModule};{$R *.res}begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TLSTDM, LSTDM);<<===问题在此,产生
Application.Run;
end.
修改办法:只需要调换初始化的位置:
begin
Application.Initialize;
Application.CreateForm(TLSTDM, LSTDM);<<===
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
在我这里调试通过.
回复人: fcjg(★飘来飘去!★(一天18小时在线))
你的这段代码看了,现在有一个问题:
如果这个treeview有几万(甚至十几万个)个node,那么
在每个节点都使用了data指针:
new(p);
p.ID := ADOTree.Fields[0].AsInteger;
p.name :=ADOTree.Fields[1].AsString;
p.ParentID := ADOTree.Fields[2].AsInteger;
tmpNode := AtvnViewNode.Items.AddChildObject(Node,p.name,p);
由于p的使用,计算机内存是否会溢出而崩溃?
我观察过,只要node增加,程序所需要的内存就不断增加~~~不知道其他各位是否注意了这个问题?还是这么做有问题?????