在实际开发应用程序中,常常会碰到数据行增加、插入、删除要求保持数据行的某一字段值的连续性。如在职工表中希望按职务高低赋予不同的连续的值,以便按职务高低进行显示;在制定工作任务或计划时能体现1、2、3、4 ... 连续的子项目。在此将此类要求连续的值称为序号。则要求程序能实现以下功能: 1)增加(追加)数据行时,能根据当前数据的总行数(n),追加新序号为(n+1) 2)插入数据行时,能根据当前所在行的序号(r),将序号大于和等于(r)的值都加上1。即序号(r)被赋予给新 插入的数据行,而原来序号r,r+1,...,n的数据行序号变为r+1,r+2,...,n+1 3)删除数据行时,能根据当前所在行的序号(r),将序号大于和等于(r)的值都减去1。即原来序号r,r+1, ...,n的数据行序号变为r-1,r,...,n-1 对于程序员来说,实现上述三个功能逻辑上来说比较简单,但对于具体开发语言实现起来却有一定的难度,特别是当序号是关键字组成之一时,更是较为困难。本人曾用Delphi开发一订货程序为实现订货明细录入具有以上功能,竟然为此编制了三个后台存储过程,才得与实现,虽可在前台实现但数据行大于几十行时,速度其慢无比,而当时一个订货明细数据行一般在千条以上。 而在Powerbuilder在保证较好的响应速度,可直接在前台实现上述功能,简直是小菜一碟。这主要是Powerbuilder与Delphi对数据控制的机制不同而造成的。 下面就在Powerbuilder中实现上述功能的方法举例予以说明。
1.创建一个employee表,如下: create table employee( serial number, //序号 name varchar2(30), //姓名 duty varchar2(20), //职务 primary key(serial) //设置字段serial为主键 )
2.假设表中将插入如下数据,要求按职位高低进行显示,在此例中序号即表示了职务的高低。 序号 姓名 职务 1 board chairman 董事长 2 general manager 总经理 3 manager 经理 . . . 3.创建一个性新的库,称作autoserial.PBl,以及一个应用程序对象,称作a_autoserial。 4.使用DataWindow画板创建一个数据窗口对象dw_employee。 Data Source选择Quick Select或SQL Select Presentation Style选择Grid Table 选择刚创建的employee Selection List 选择serial,name,duty (注意serial字段在Selection List中的位置)
5.使用Window画板创建一个窗口w_autoserial,并在窗体中放入以下控件。 控件名 属性 值 DataWindows Control Name dw_1 DataWindows Object Name "dw_employee" HScrollBar TRUE VScrollBar TRUE Command Button Name cb_insert Text "插入" Command Button Name cb_add Text "增加" Command Button Name cb_delete Text "删除" Command Button Name cb_save Text "保存" 6.在Application画板中,在应用对象的Open事件中输入如下代码 // Profile project SQLCA.DBMS = "OR8 Oracle 8.0" SQLCA.LogPass = "password" SQLCA.ServerName = "gxmis" SQLCA.LogId = "projectdba" SQLCA.AutoCommit = False SQLCA.DBParm = "" //以上为连接数据库的配置,由用户根据具体设置 connect using sqlca; open(w_autoserial) //打开w_autoserial窗口
7.窗口w_autoserial中的Open事件中输入如下代码 dw_1.settransobject(sqlca) dw_1.retrieve()
8.为窗口w_autoserial中的数据窗口dw_1声明一个用户事件ue_reassign_serial 用户事件ue_reassign_serial的说明 Event Name ue_reassign_serial Event ID Return (none) Argument serial_position long Value 其中参数serial_position接收数据窗口对象dw_employee中序号字段在Selection List的位置,本例中序号字段位置为1。 事件脚本如下 long i this.setredraw(false) for i=1 to this.rowcount() this.object.Data[i,serial_position]=i //重置序号 next this.setredraw(True)
9. 编写窗口w_autoserial中的Command Button控件脚本 9.1 cb_insert按钮的clicked事件代码 long ll_curr,ll_newcur ll_curr=dw_1.getrow() ll_newcur=dw_1.insertrow(ll_curr) //调用序号维护事件,1为序号字段在Selection List中的位置 dw_1.event trigger ue_reassign_serial(1) dw_1.setfocus() dw_1.setcolumn("name") dw_1.scrolltorow(ll_newcur)
9.2 cb_add按钮的clicked事件代码 long ll_curr,ll_newcur ll_newcur=dw_1.insertrow(0) dw_1.event trigger ue_reassign_serial(1) dw_1.setfocus() dw_1.setcolumn("name") dw_1.scrolltorow(ll_newcur)
9.3 cb_delete按钮的clicked事件代码 if messagebox(''删除请求'',''肯定要删除该人员?'',stopsign!,yesno!,2)=1 then dw_1.deleterow(0) dw_1.event trigger ue_reassign_serial(1) end if
9.4 cb_save按钮的clicked事件代码 if dw_1.update()=1 then commit; else rollback; end if
本例在Powerbuild 6.5 ,数据库oracle 8.0.5 上测试通过。对于序号上千的表,本方法也能应付自如。如果程序中序号不为关键字,或为一些简单表格可在DataWindow中增加计算字段来实现以上功能,计算字段表达式为getrow()。 (责任编辑:admin) |