用POWERBUILDER编写一个通用代码维护程序

来源:互联网 发布:npc什么意思网络语言 编辑:程序博客网 时间:2024/06/07 02:34

用POWERBUILDER编写一个通用代码维护程序

邓振兴

  笔者用开发工具Powerbuilder结合数据库Oracle编写一个通用万能代码维护程序。该程序具有如下特点:只要数据操纵语言为SQL(若是其它,可稍作修改),该程序都可不做任何修改直接运行。在笔者开发的一些应用系统中,所有代码维护都直接调用该通用代码维护程序,只要修改相关数据表中数据,无需修改程序,既减少了工作量,又形成了一定规范。

  程序基本思想

  先用一例解释一下相关名称,如现对全国所有单位编码,那么该编码为多级合成,可用四级合成(省、地(县)、单位类别、单位序号〕,其中前三级又分别对应三个编码表,第四级在现有前三级编码相同者总数上增一,需对应编码表的级称固定名级;还有一类简单编码,例某单位所有部门电话号码编码,这类编码为固定的对应。

  首先需创建三个辅助表d_tab_columns,d_tab_comments,d_tab_codenote。前两个表可根据Oracle数据字典中的表user_tab_columns,user_tab_comments来创建。其中表d_tab_columns比表user_tab_columns多一列column_chinesename,其它所有列相同;表d_tab_comments比表user_tab_comments多一列table_
chinesename,其它所有列相同;表d_tab_codenote是辅助需多级合成代码表的,说明如下:imjf001代码表名,imjf002合成代码总级数,imjf003合成代码固定名总级数,imjf004合成代码各级总说明(用*号隔开各级说明〕,imjf005代码列名。另外,每级合成代码的代码表需若干辅助代码表(个数为合成代码固定名总级数,每个表内容为合成代码各级编码,表名为:主表名+“CODE”+级数序号,其中级数序号为两位,例01、02....10...)

  利用Powerbuilder数据窗口的动态特性,程序基本流程如下:

  用户对象:dropdownlistboxd_ddlb,statictextd_st

  主窗口w_code_maintenance有一数据窗口dw_1,_Listboxlb_1,若干图形命令按钮。

  主窗口open事件触发:

  d_1b_table(1b_1)/*把所有代码表名填入listbox1b_1中

  1b_1.selectitem(1)/*取1b_1第1项为初始值

  d_1b_itemchanged(dw_1,1b_1)/*数据窗口dw_1显示在

  1b_1中选定的代码表的内容

  主窗口中对象1b_1的事件selectionchanged:

  d_1b_itemchanged(dw_1,1b_1)/*数据窗口dw_1显示在

  1b_1中选定的代码表的内容

  主窗口中对象pb_1事件clicked:/*实现代码插入功能*/

  该事件script见附录,功能:若选定的表为一合成代码表,则

  打开窗口w_code_attr否则直接在数据窗口dw_1中插入一空行,以待输入数据。

  窗口w_code_attr事件open中script:功能:根据合成代码级数,

  动态打开相应个数的用户对象d_dd1b,d_st,并把相关辅助代

  码表中的数据分别填入每个d_dd1b,窗口w_code_attr中对象

  cb_1事件clicked中script见附录,功能:根据每dd1b所选项,合成代码。

  程序script(所有次要,易实现的功能略去,为节约篇幅,几条语句放在一行时,用分号隔开)

  全局变量:stringcode_table,vcode,codelnote

  intlft,len_codecol

  窗口w_code_maintenance中共享变量:codevΚ0

  窗口w_code_attr中共享变量:d_ddlbd[10]

  d_sts[10]

  int p[10]

  //函数d_lb_table(v1listbox),功能:把应用系统所有代码表名加入到listbox中,以供选择

  stringt_name,t_name_chinese,fΚ″0%″,vt

  intiΚ0

  declarec1cursorforselecttable_name,table_chinesenamefromd_tab_comments

  wherecommentslike:f;/*代码表对应的comments为0%

  openc1;

  label:fetchc1into:t_name;

  ifsqlca.sqlcodeΚ0then

  i++;vtΚt_name_chinese+space(40-len(t_name))+t_name;insertitem(v1,vt,i)

  gotolabel

  endif;closec1;

  //函数my_table_datawindow(v1string,v2datawindow),数据窗口风格部分script已略去

  //功能:把参数v1所代表的代码表的所有数据在数据窗口v2中显示出来

  stringsel_str,dwsyntax_str,errors,dt_str,t_name,mo1,c_name,c_type,c_length,colup datestrΚ″″

  string,c_nullable,modstr,modhead,col_chinese

  longrc,iΚ0

  t_nameΚupper(v1);mo1Κ″″;modheadΚ″″;sel_strΚ″select″;

  declarecolcursorforselectcolumn_name,data_type,data_length,nullable

  fromd_tab_columnswheretable_nameΚ:t_name;

  opencol;

  label1:fetchcolinto:c_name,:c_type,:c_length,:c_nullable;

  ifsqlca.sqlcodeΚ0then

  i++;sel_strΚsel_str+c_name+″,″;mo1Κmo1+c_name+″.tabsequenceΚ″+string(i)
+″″

  colupdatestrΚcolupdatestr+c_name+″.updateΚyes″+″″

  selectcolumn_chinesenameinto:col_chinese

  fromd_tab_columnswheretable_nameΚ:t_nameandcolumn_nameΚ:c_name;

  modheadΚmodhead+c_name+″_t.textΚ'″+col_chinese+″'″

  gotolabel1

  endif

  closecol;sel_strΚmid(sel_str,1,len(sel_str)-1)+″from″+t_name

  dt_strΚ″style(typeΚgrid)″;dwsyntax_strΚsqlca.SyntaxFromSQL(sel_str,dt_str,errors)

  Create(v2,dwsyntax_str,errors);settransobject(v2,sqlca)

  dt_strΚ″datawindow.table.updatetableΚ'″+t_name+″'″

  modify(v2,dt_str);modify(v2,mo1);modify(v2,colupdatestr)

  modify(v2,″datawindow.table.updatewhere=1";modify(v2,modhead)

  rc=retrieve(v2); setrow(v2,rc)

  //对象pb_1(实现代码插入功能,其它诸如删除、查找已略去事件clicked中script:

  long row;
  string t_name,im001,im002,im003,im004,im005

  codev=0;t_name=upper(trim(right(trim(selecteditem(lb_1)),40)))

  select imjf0012imjf002,imjf003,imjf004,imjf005

  into:im001,:im002,:im003,:im004,:im005

  from d_tab_codenote where imjf001=::t_name;

  if dw_1.update()=1 then commit;end if

  if(upper(im001)=t_name)then

  code_table=t_name; codelnote=im004; lft=integer(im003); open(w_code_attr)

  codev=1; dw_1.setfocus(); row=dw_1.insertrow(0);dw_1.scrolltorow(row);

  dw_1.setrow(row);dw_1.setitem(row,im005,vcode); dw_1.setcolumn(1)

  else

  dw_1.setfocus(); row=dw_1.insertrow(0); dw_1.scrolltorow(row)

  dw_1.setrow(row); dw_1.setcolumn(1)

  end if

  //函数d_lb_itemchanged(v1 datawindow,v2 listbox)功能:获得、、listbox中所选定项、即代码表名,并把它作为参数传递给函数my_table_datawindow(v1 string,v2 datawindow)

  string sel_str,dwsyntax_str,errors,dt_str,t_name,mo1

  string c_name,c_type,c_length,c_nullable,modstr,colupdatestr=""long re,i

  t_name=upper(trim(right(trim(selecteditem(v2)),40)))

  my_table_datawindow(t_name,v1)

  //窗口w_code_attr事件open下script,功能:合成代码

  int i,len,j,pa0

  string obparm,para,tname,t1,sqlstr,im001,im002,str,pa1,pa2

  len=2100/lft;p[1]=1

  for i=1 to lft

  pa0=2; pa1=string(i-1);pa2=string(0)

  obparm=dfun001(pa0,pa1,pa2); obparm=code_table+"CODE"+obparm

  openuserobjectwithparm(d[i],(i-1)*len+30.100);

  openuserobjectwithparm(s[i],(i-1)*len+30,10);d[i].width=len; s[i].width=len

  if i=1 then p[i+1]=pos(codelnote,"*",i)

  else p[i+1]=pos(codelnote,"*",p[i]+1)

  end if

  s[i].text=mid(codelnote,p[i],p[i+1]);tname=obparm

  sqlstr="select imjf001,imjf002 from"+tname

  prepare sqlsa from:sqlstr; declare c1 dynamic cursor for sqlsa;

  open dynamic c1; j=0

  label: fetch c1 into :im001,:im002;

  if sqlca.sqlcode=0 then

  j++; str=im002+space(60-len(im002))+im001;d[i].insertitem(str,j)

  goto label

  end if;

  close c1;

  next

  //主窗口w_code_maintenance事件open中script

  d_lb_table(lb_1);lb_1.selectitem(1);d_lb_itemchanged(dw_1,lb_1);

  注:程序中sqlca事物决定程序所连接的数据库,在数据库中需有三个辅助表(如前言中所述)

  总结

  POWERBUILDER结合SQL语言,给应用开发人员提供了十分灵活的编程方法,可编制出一些通用的模块(代码维护、数据查找、报表等等),不仅可减少开发工作量,也可形成自己程序风格。
 

原创粉丝点击