关于超想
本站导航
邮件列表
  首页 | 本站产品 | Delphi资料 | 免费资源 | 程序人生 | 软件工程 | 网站设计 | 推荐网站
你所在的位置 -> 主页 -> 超想软件 -> 编程资料 -> delphi -> 开发技巧 -> 构件使用 ->详细
相关内容  
 
 
在Delphi程序中应用IE浏览器控件
 
【新品推荐】

  详细内容
 

用树型结构表示科目代码的一种高效算法
作者: 松本电工实业有限公司电脑部 舒嵩嵩 评价: 上站日期: 2001-09-04
内容说明:
来源:




---- 在很多常见的财务软件中,科目代码一般都用树型结构来显示。要实现这一点,通常的做法是用多个(嵌套)循环,甚至递归等算法,将科目表中的代码"织"成树,但这样不但算法复杂,而且执行效率低。本人在实际的开发应用中,摸索出一种简单高效的算法,在此和盆托出,只在抛砖引玉,找出最佳解决方案。下面介绍在delphi中的实现方法。 

一.表结构 
---- 首先建立如下结构的数据表code.db,并输入一些测试数据: 
字段名    类型    长度    说明
acode    字符型    20    科目代码
aname    字符型    30    科目代码名称
......    ......    ......    ......
表(一)  

---- 其中,科目代码acode的数据类型一定要字符型(一定),长度按具体要求而定,假如要支持六级编码,且代码结构是"3-2-2-2-2-2",则该字段的长度不小于18,而其他字段则不作要求 。另外,要为字段acode建一索引(切记),因为要用它来排序。 
二.编写程序 
---- 1.新建一project:codetree.drp,主窗体命名为frmmain,单元存为main.pas。在frmmain上添加一ttreeview控件,命名为tvecode,一个timagelist,命名为imgicon,并装入三个icon和bmp,最后添加一ttable控件,命名tblcode。 
frmmain和各控件的属性按表(二)设置:
组件          属性           设置
frmmain        caption          '科目代码'
        font        宋体 9号
        borderstyle    bsdialog
tvwcode        images          imgicon
        readonly    true
imgicon        imagelist    装入三个图标
btnclose    caption        关闭(c)
表(二)

---- 2. 单元main.pas的完整源代码如下: 
unit main;

interface

uses
  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.

---- 其中,常量scodeformat是科目代码的代码结构,其定义的规则一定要和数据表code..db中的字段acode的值相符。所以在实际应用中,让用户新增科目代码时,必须严格检查其规范性,只有完全符合事先定义的代码结构,才能添加入库。 
---- 函数getlevel是求某一科目代码的级数,例如,有一科目代码"10102",在代码结构是"322222"的情况下,调用函数getlevel('322222','10102')将返回整数2 。 

---- 当然,本文的核心是loadcode函数,该函数用了一个循环来遍历数据表code.db的所有记录,将字段acode和aname的内容按层次显示出来。而在该函数中定义的二维数组mynode[0..6],则显得优为重要,在这里,它作用类似于递归中的栈。因为在ttreeview添加子节点的方法addchild(node: ttreenode; const s: string)中,要为其指定一父节点作为参数,而父节点的代码级数一定是要添加节点的代码级数减1,所以只要用一数组来动态保存和指定父节点就成功了。 

三.运行结果 
---- 好了,现在把code.db复制到和可执行文件相同的目录下,按下f9键编译运行,本人运行的效果如图(一)。只要在以上的基础上加以完善,如增加维护功能,就可搬到实际应用中了。当然,本算法不单能用在科目代码上,其他类似的树型结构都能奏效。本人就已将此算法应用于[科目代码]、[物料清单(bom)]、[库房管理]和[物料主文件]等多个模块中,取得令人满意的效果。 
---- 以上程序在中文windows 9x、delphi 4 c/s环境下编译通过。 

 
你所在的位置 -> 主页 -> 超想软件 -> 编程资料 -> delphi -> 开发技巧 -> 构件使用 ->详细
  首页 | 本站产品 | Delphi资料 | 免费资源 | 程序人生 | 软件工程 | 网站设计 | 推荐网站
声明:本站内容除注明原创以外均从网上摘抄,如有侵权请指明。
  如果您对我们的网站有什么意见或者建议,请与我们联系
powered by 建站易上手- V2.0