省份地区的编号:
1,2位表示省份,3,4位表示地区,5,6位表示县市区
3,4位为0表示省份,5,6位为0表示地区,7,8位0表示县市区
如:
山东编号为370000,四川380000,广东:390000
而济南:370100,青岛:370200,烟台:370300,东营:371200
依此类推:
请大家给出一个递归算法,地区一下还有县市等等。
编号长度为11位。
1,2位表示省份,3,4位表示地区,5,6位表示县市区
3,4位为0表示省份,5,6位为0表示地区,7,8位0表示县市区
如:
山东编号为370000,四川380000,广东:390000
而济南:370100,青岛:370200,烟台:370300,东营:371200
依此类推:
请大家给出一个递归算法,地区一下还有县市等等。
编号长度为11位。
山东的下一级包括济南青岛烟台等等,而这些同样包括他们自己的下
一级,以此类推。
将按照编号来区分的行政关系显示到treeview上,一直可以从上级到下一 级找下来。
不知道是否吻合你的意思!?
就是这个意思,当然还有个人员表,也要根据这个编号显示在他们所在的
机构里面,人员表就是在相应的机构编号后面加数字了
Windows, Messages, SysUtils, Classes, Graphics,
Controls, Forms, Dialogs,
Db, DBTables, ComCtrls, ImgList, StdCtrls;type
TForm1 = class(TForm)
tvwCode: TTreeView;
tblCode: TTable;
ImageList1: TImageList;
btnClose: TButton;
procedure FormCreate(Sender: TObject);
procedure btnCloseClick(Sender: TObject);
private
{ Private declarations }
function LoadCode(crTbl:TDBDataSet):Integer;
function GetLevel(sFormat,sCode:String):Integer;
public
{ Public declarations }
end;var
Form1: TForm1;const
SCodeFormat = '322222'; //科目代码结构
SFirstNodeTxt = '科目代码'; //首节点显示的文字implementation{$R *.DFM}
//以下函数是本文的重点部分,
其主要功能是用一循环将Code.db表中的
//科目代码和科目代码名称显示出来
function TForm1.LoadCode(crTbl:TDBDataSet):Integer;
var NowID,sName,ShowTxt:String;
i,Level:Integer;
MyNode:array[0..6]of TTreeNode;
//保存各级节点,最长支持6级(重点)
begin
Screen.Cursor:=crHourGlass;
Level:=0;
With crTbl do
begin
try
if not Active then Open;
First;
tvwCode.Items.Clear;
//以下是增加第一项
MyNode[Level]:=tvwCode.Items.Add
(tvwCode.TopItem,SFirstNodeTxt);
MyNode[Level].ImageIndex:=0;
MyNode[Level].SelectedIndex:=0;
//以上是增加第一项
While Not Eof do
begin
NowID:=Trim(FieldByName('aCode').AsString);
ShowTxt:=NowID+' '+FieldByName('aName').AsString;
Level:=GetLevel(SCodeFormat,NowID);
//返回代码的级数
//以下是增加子项
//以下用上一级节点为父节点添加子节点
if Level>0 then//确保代码符合标准
begin
MyNode[Level]:=tvwCode.Items.AddChild
(MyNode[Level-1],ShowTxt);
MyNode[Level].ImageIndex:=1;
MyNode[Level].SelectedIndex:=2;
end;
//以上是增加子项
Next;
end;
finally
Close;
end;
end;
MyNode[0].Expand(False);//将首节点展开
Screen.Cursor:=crDefault;
end;
//以上函数将Code.db表中的科目代码和科目代码名称显示出来//下面函数的功能是返回一代码的级数,
参数sFormat传递科目代码结构;
//参数sCode传递某一科目代码
function TForm1.GetLevel
(sFormat,sCode:String):Integer;
var i,Level,iLen:Integer;
begin
Level:=-1;//如果代码不符合标准,则返回-1
iLen:=0;
if (sFormat< >'')and(sCode< >'')then
for i:=1 to Length(sFormat) do
begin
iLen:=iLen+StrToInt(sFormat[i]);
if Length(sCode)=iLen then
begin
Level:=i;
Break;
end;
end;
Result:=Level;
end;
//上面函数的功能是返回一代码的级数procedure TForm1.FormCreate(Sender: TObject);
begin
with tblCode do
begin
DatabaseName:=ParamStr(1);
//使tblCode的DatabaseName指向应用程序所在的路径
TableName:='Code.DB'; //指向数据表Code.DB
Open;
IndexFieldNames:='aCode';
//按字段aCode排序(不要漏掉)
end;
LoadCode(tblCode);
end;procedure TForm1.btnCloseClick(Sender: TObject);
begin
Close;
end;end.
然后动态建子树,这样很快的
我有个项目和你遇到的问题一样,不过我用的是fctreeview
[email protected]
通过后新建一个贴子给分。
begin
while not 表.eof do
begin
新节点:= 树.items.addchildobject(节点,编码,附加指针);
if 级别<4 {编码长11位,除去前两位,被分成4级 XX XX XX XX XXX}
begin
保存当前过滤条件;
保存当前的book;
设置新的过滤条件;{取最后3+4-级别位个编码,要求为'0'}
表.first;
//开始递归调用;
创建树(树,新节点,表,级别+1);
还原表的过滤条件;
还原表的位置,利用book;
Free自定的book;
end;
表.movenext;
end;
end;
过程 初始化();
begin
设置表过滤;{只显示省份}
创建树(树,nil,表,1);
取消过滤;
end;注:你上面所说的不一致,说是11位,可列出的例子是6位的邮编.
具体自己写吧,应当可以解决.
Windows, Messages, SysUtils, Classes, Graphics, ComCtrls, DB, Forms, Dialogs;function TreeFindItem(Sender: TTreeView; NodeItem: TTreeNode; Name: String): TTreeNode;
function TreeAddItem(Sender: TTreeView; ItemList: TStrings; Book: TBook; Resort: Boolean): TTreeNode;
function TreeGetItem(Sender: TTreeView; ItemList: TStrings): TTreeNode;
procedure TreeDeleteItem(Sender: TTreeView; ItemList: TStrings; Level: Integer);implementation
function TreeAddItem(Sender: TTreeView; ItemList: TStrings; Book: TBook; Resort: Boolean): TTreeNode;
var
ThisNode, Node: TTreeNode;
I: Integer;
begin
Node := nil; //nil = level 0 has no parent node
//this is checked by TreeFindItem
for I := 0 to Itemlist.count -1 do
begin
ThisNode := TreeFindItem(Sender, node, Itemlist[i]);
if ThisNode <> nil then Node := ThisNode else
begin
if I < Itemlist.count -1 then
begin
if I = 0 then Node := Sender.items.Add(Node, Itemlist[i])
else Node := Sender.items.AddChild(Node, Itemlist[i]);
end else
begin
if I = 0 then Node := Sender.items.AddObject(Node, Itemlist[i], Book)
else Node := Sender.items.AddChildObject(Node, Itemlist[i], Book);
end;
Node.stateIndex := Node.level + 1;
if Resort and (Node.parent <> nil) then Node.parent.alphasort;
end;
end;
Result := Node;
end;function TreeFindItem(Sender: TTreeView; NodeItem: TTreeNode; Name: String): TTreeNode;
begin
if NodeItem = nil then NodeItem := Sender.items.getfirstnode
else NodeItem := NodeItem.getfirstchild;
//NodeItem is now the first item of the desired level
//if this level has no items, NodeItem is nil if (NodeItem <> nil) and (NodeItem.text <> Name) then
repeat
NodeItem := NodeItem.getnextsibling;
until (NodeItem = nil) or (NodeItem.text = Name);
Result := NodeItem;
end;function TreeGetItem(Sender: TTreeView; ItemList: TStrings): TTreeNode;
begin
Result := TreeAddItem(Sender, Itemlist, nil, false);
end;procedure TreeDeleteItem(Sender: TTreeView; ItemList: TStrings; Level: Integer);
var
Node, Parent: TTreeNode;
begin
Node := TreeGetItem(Sender, ItemList);
while Node.level >= Level do
begin
Parent := Node.parent;
Node.delete;
if (Parent = nil) or (Parent.hasChildren) then break;
Node := Parent;
end;
end;
end.
node:tfctreenode;
i,j,count:integer;
begin
if not fctreeview1.HandleAllocated then exit;
i:=0;
j:=0;
count:=fctreeview1.Items.Count;
setlength(a,count);
node:=fctreeview1.Items.GetFirstNode;
while node<>nil do
begin
a[i]:=node;
node:=node.GetNextSibling;
i:=i+1;
end;
j:=i-1;
i:=0;
while i<count do
begin
node:=a[i].GetFirstChild;
while node <> nil do
begin
j:=j+1;
a[j]:=node;
node:=node.GetNextSibling;
end;
i:=i+1;
end;