首页 PB编程技巧实例

PB编程技巧实例

举报
开通vip

PB编程技巧实例 顶 热 荐 PB编程技巧实例 [ 作者:佚名    转贴自:本站原创    点击数:13009    文章录入:lqk101 ] 随着数据库技术在各行各业的广泛应用,作为企业级数据库前端开发工具的Power Builder日益成为开发人员的得力助手。PowerBuilder以其开放的体系结构,友好的用户界面和简洁高效的开发环境赢得了众多程序员的喜爱,连续多年被评为美国计算机界的年度风云产品,在数据库开发工具领域占据了高达44%的市场份额。PowerBuilder进入我国的时间不长,许...

PB编程技巧实例
顶 热 荐 PB编程技巧实例 [ 作者:佚名    转贴自:本站原创    点击数:13009    文章录入:lqk101 ] 随着数据库技术在各行各业的广泛应用,作为企业级数据库前端开发工具的Power Builder日益成为开发人员的得力助手。PowerBuilder以其开放的体系结构,友好的用户界面和简洁高效的开发环境赢得了众多程序员的喜爱,连续多年被评为美国计算机界的年度风云产品,在数据库开发工具领域占据了高达44%的市场份额。PowerBuilder进入我国的时间不长,许多编程人员希望了解并掌握这一先进工具。在这里,笔者将自己平日用PowerBuilder作开发的一些体会整理出来,奉献给大家。 PowerBuilder是由多个功能模块组成的可视化集成开发环境,是面向对象的开发工具,用它可以方便地建立起基于Windows的分布式数据库应用。其功能模块分别完成应用管理、窗口对象设计、菜单对象设计、数据窗对象设计和数据库查询等工作,这些功能模块由于PowerBuilder提供的色彩丰富的工具条而被称作"Painter"(画板)。下文便依据各模块作大的分类介绍相应的编程技巧。  一、有关应用的编程技巧仅让应用程序运行一次的技巧:  有时需要限制一个PowerBuilder应用同时运行的实例(Instance)个数或仅让应用运行一次,我们可以通过调用WindowsSDK函数或使用PowerBuilder的Handle()函数来实现。    先谈调用SDK函数的 方法 快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载 。为了调用SDK函数,需要在ApplicationPainter的菜单项Declare\GlobalExternalFunctions中定义:    FunctionuintGetModuleHandle(stringModuleName)Library"Kernel.exe" FunctionuintGetModuleUsage(uintModuleHandle)Library"Kernel.exe"  下面这段程序写在Application的Open事件中。它先通过调用SDK函数GetModuleHandle()获得指定应用程序的句柄,然后调用GetModuleUsage()函数确定应用程序同时运行的实例个数。 uint IApplHandle  int App_num  IApplHandle=GetModuleHandle("ocmis.exe")  if IApplHandle>0 then    App_num=GetModuleUsage(IApplHandle)    if App_num>1 then        Messagebox("注意","本程序已经运行!",Stopsign!)       return    endif endif Open(w_main)   若需要限制应用同时运行的实例个数,比如仅允许同时运行N个实例,那么将上述程序中的语句 “if App_num>1 then”改为“if App_num>N then”即可。   采用Handle()函数的方法更简洁一些,代码如下:  int hand  hand=Handle(this,TRUE)  If hand>0 then    Messagebox("注意","本程序已经运行!",Stopsign!)    Halt  else  Open(w_main)  endif  二、有关窗口的编程技巧  1、提供实时帮助条 中文之星2.0版的链形菜单管理器提供了实时帮助条,增强了系统的易用性,在PowerBuilder中也可以实现类似的功能。当鼠标移动到窗口中的某些控制(Control),如编辑器、图片等时,会在鼠标附近自动产生帮助条,实时地提示操作要领。 首先在窗口w_main中任意位置定义一个黄底黑字的静态文本st_help,设定st_help.visible=false,st_help.text=&Help;然后在该窗口模块的Declare\WindowFunctions...下定义函数show_help(),其参数只有一个,参数名为text,类型为string,通过传值方式接收参数;无返值。show_help()代码如下:  if st_help.visible then     return endif  st_help.text=text   st_help.width=Len(st_help.text)*38   st_help.x=w_main.PointerX()  st_help.y=w_main.PointerY()+50  if st_help.x+st_help.width>w_main.Workspacewidth() then      st_help.x=w_main.Workspacewidth()-st_help.width  endif  if st_help.y+st_help.height>w_main.Workspaceheight()     then st_help.y=w_main.Workspaceheight()-st_help.height  endif  st_help.visible=true  接下来,我们就可以调用show_help()函数了。但PowerBuilder提供的所有控制均缺乏当鼠标移至其上就触发的事件,显然,需要定义相应的用户事件。先选中准备定义用户事件的控制,如某个单行编辑器,然后在窗口模块的菜单Declare\UserEvents...下,双击PasteEventID:中的pbm_mousemove条目,将其拷贝至EventID下,取EventName为Mouseon,这样,我们就定义好了相应控制的用户事件Mouseon。我们可以在该控制的用户事件Mouseon下,写下调用函数show_help()的语句:    if st_help.visible then       Hide(st_help)       show_help("瞧!这便是实时帮助条!")    endif  2、“跑马灯”的实现技巧 有时需要用一矩形条显示少量用户特别关心的信息,这条信息串首尾相连,向一个方向循环滚动,我们通常将其称作“跑马灯”。证券业中常用“跑马灯”来显示不断变化的股票行情;实际应用中也常通过“跑马灯”来监视是否死机。我们可以写一个简单的函数running_horse()来实现“跑马灯”的显示。    running_horse有两个参数,       第一个参数的参数名为textline,类型为string,传值;       第二个参数的参数名为num,类型为int,传值;函数返值类型为string。    该函数的代码仅一句:      returnMid(textline,(num+1))+Left(textline,num)  下面就可以调用running_horse()函数了。先在一个窗口里定义好单行编辑器sle_running_horse,在该窗口的Open事件下写上:   sle_running_horse.text="Iamtestingrunning_horse!"   Timer(0.2)  然后在该窗口的Timer事件下调running_horse(),代码如下: sle_running_horse.text=running_horse(sle_running_horse.text,1) 这样,当你打开这个窗口时,“跑马灯”便会运转起来。可以在程序中加些语句,适时地增减sle_running_horse.text中的内容,你便会在“跑马灯”中看到相应变化的信息。 三、有关菜单的编程技巧右键菜单的实现技巧:  当你在相应的窗口或控制上按鼠标右键时,就会在鼠标所指位置弹出菜单,这就是右键菜单。程序中支持右键菜单会为用户的操作带来许多方便,同时鼠标右键可以分担部分左键的功能。右键菜单在证券期货业中的许多大型行情分析软件中得到了广泛的应用。在PowerBuilder中实现右键菜单非常简单,仅两个步骤:1.设计相应菜单;2.在窗口或控制的Rbuttondown事件下写上调用语句。 先在MenuPainter中创建菜单rbuttonpop,rbuttonpop有一个菜单条目(Menuitem)m_choice。然后在需要调用该菜单的窗口或控制的Rbuttondown事件下写上:  m_rbutton popNewMenu NewMenu=Createm_rbuttonpop  NewMenu.m_choice.PopMenu(PointerX(),PointerY()) 至此,右键菜单制作完毕。上述语句中的NewMenu的数据类型为m_rbuttonpop,当你在相应位置按鼠标右键时,弹出的菜单NewMenu是菜单m_rbuttonpop的一个实例(Instance)。  四、有关数据窗口的编程技巧 数据窗对象是PowerBuilder中最重要的概念之一,它是PowerBuilder应用区别于其它Windows应用的重要特征,同时也是PowerBuilder的价值所在。PowerBuilder应用通常通过数据窗对象从数据库或其它数据源取得数据并加以显示,其数据的输入、添加、修改和删除也大都通过数据窗对象来实现。故理解并掌握数据窗概念对于用好PowerBuilder具有重要意义。下面给出了有关数据窗的几个编程技巧。  1、自动调整大小的数据窗 在PowerBuilder应用运行过程中,常常会用鼠标拖动窗口角以改变窗口大小,尤其是在多文档窗口(MDI)中,通常有多个sheet存在的情况下,有时为了察看后面窗口中的数据而将前面窗口缩小,但窗口缩小了,其中的数据窗并没有缩小,由此而不能方便地使用数据窗的卷滚条,那么怎样使前面窗口中的数据窗大小随窗口的大小自动调整呢? 很简单,我们只需要在数据窗所在窗口的Resize事件下写上一句话:       Resize(dw_datamon,this.Workspacewidth()-50,this.Workspaceheight()-50)    其中dw_datamon是数据窗的名字,数字50可以调整。这样,你就拥有了一个会随窗口大小变化而自动调整大小的数据窗了。卷滚条用起来很方便,不信试试。  2、Retrieve后不回卷的数据窗 我们经常面对一大堆数据,其具体体现就是数据窗很长,需要拉动垂直卷滚条才能看到后面的数据,当你在包含长数据窗的窗口的Timer事件中写下Retrieve()语句后,令人气恼的事情就会发生:Timer事件一执行,数据窗就翻回第一页;如果Timer事件执行的时间间歇很短,那我们就永远没有足够的时间来察看后面的数据了。下面我们着手解决这个问题。可能你已经注意到了,每个数据窗都拥有两个与Retrieve有关的事件:Retrievestart和Retrieveend,它们分别允许我们在Retrieve的前后干一些事,这正是我们所需要的。实际上,就这两个事件,我们已经能够提出两个解决 方案 气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载 了。 其一,在Retrievestart事件中,保存当前数据窗中可见的数据行;然后Retrieve;接着在Retrieveend事件中,恢复先前保存的数据行。 其二,在Retrievestart事件中,保存当前垂直卷滚块的位置;Retrieve后再恢复其位置。后者使用了动态数据窗函数,实现起来更简洁一些,下面详细探讨。假设你已设计好了一个在窗口w_datamon中的数据窗dw_datamon,现在可以先定义一个保存垂直卷滚块位置的类型为string的Globle变量old_vspos,然后在该数据窗的Retrievestart事件下输入以下语句以保存其位置: old_vspos=this.Describe("DataWindow.VerticalScrollPosition")  dw_datamon.SetRedraw(false)  在相应的Retrieveend事件下输入恢复垂直卷滚块位置的语句:  this.Modify("DataWindow.VerticalScrollPosition="+old_vspos)  dw_datamon.SetRedraw(true)  这样,数据窗上的工作已做完。下面是相应窗口上的工作。该窗口的Open事件下: dw_datamon.Settrans(sqlca)  dw_datamon.Retrieve()  timer(6)  该窗口的Timer事件下:  Setfocus(w_datamon)  Retrieve(dw_datamon)  至此,Retrieve后不会回卷的数据窗dw_datamon已经可以工作了。值得注意的是,数据窗的排序分类等操作应在Retrieve前就在数据库表中完成,否则Retrievestart事件保存的卷滚块位置很可能并不是你所期待的,换句话说,Retrievestart事件应发生在所有数据窗操作之后;另外,在每次Retrieve后,应将处于该数据窗上的Focus移开,以免具有焦点的数据窗的第一行第一列总要显示,故在窗口w_datamon的Timer事件中设置了Setfocus(w_datamon)这条语句。  3、依据条件改变数据颜色  依据条件改变数据颜色是许多场合都要用到的重要功能,数据颜色的改变不仅引人注目,而且能起到暗示作用,清楚地告诉用户价位的涨跌或状态的改变等。大多数证券期货实时行情显示软件都提供了这种功能。在当前价位比其前一价位高时,当前价位数据颜色变红,表示价位上涨;反之,颜色变绿,表示价位下跌;若当前价位与其前一价位相等,则数据颜色不变。PowerBuilder没有提供解决这一问题的捷径,但我们仍可利用动态数据窗来实现。先考虑一下实现的步骤,在Retrieve前需要把有关列的数据先保存起来;Retrieve后我们获得了相应列的新数据;我们需要将上述二者作一比较,以确定颜色的变化。值得指出的是,由于动态数据窗函数dwModify()只能用描述数据窗的模式串作参数,不能接收变量作参数,故我们得想法把比较的结果传递给数据窗。为解决这个问题,可以在定义数据窗时多定义几个空列,这几列不与数据库表中的列相对应,它们作为存放比较结果的缓冲区。原则上若需要N列实时地变色,则需要N列缓冲区,就应该多定义N个空列。下面给出了一个例子具体说明。 这段程序写在某窗口的Timer事件中,该窗口内有数据窗dw_infor,其"buy"、"sell"列分别表示买价和卖价,需要实时地变颜色。为此,我们在数据窗dw_infor中多定义了"buybuf"和"sellbuf"两列,分别存放"buy"列和"sell"列Retrieve前后数据比较的结果。  //Red=255;Green=65280  int i,infor_rownum decimalbuy_old[],sell_old[],buy_new[],sell_new[]  dw_infor.SetRedraw(false)  infor_rownum=dw_infor.RowCount() FOR i=1 To infor_rownum    buy_old[i]=dw_infor.GetitemNumber(i,"buy")    sell_old[i]=dw_infor.GetitemNumber(i,"sell") NEXT  dw_infor.retrieve()  FOR i=1 TO infor_rownum    buy_new[i]=dw_infor.GetitemNumber(i,"buy")    sell_new[i]=dw_infor.GetitemNumber(i,"sell") NEXT  FOR i=1 TO infor_rownum    dw_infor.Setitem(i,"buybuf",buy_new[i]-buy_old[i])   dw_infor.Setitem(i,"sellbuf",sell_new[i]-sell_old[i]) NEXT dw_infor.dwModify("buy.color='0~tif(buybuf>0,255,if(buybuf<0,65280,0))'")  dw_infor.dwmodify("sell.color="0~tif(sellbuf>0,255,if(sellbuf<0,65280,0))'")  dw_infor.setredraw(true)  我们看到,程序在Retrieve前后分别将"buy"和"sell";列的数据写进与其类型匹配的数组中,然后将比较的结果分别写入"buybuf"和"sellbuf"列,最后用函数dwModify()改变有关列的颜色。记住在该窗口的Open事件中设置事务对象并激活Timer事件。此外,还有一些方法可以改变颜色,比如先在某些需要变颜色的行或列设置带颜色的长方形,同时将其上面的数据窗中的数据设置成透明的,当条件改变时,可以通过改变数据窗后的长方形的颜色来实现。  4、用Enter键替代Tab键切换栏目的数据窗  许多情况下,PowerBuilder应用的数据是通过数据窗输入的,而且输入的数据是单纯的数字数据,也就是说,输入内容完全可以通过敲击键盘右面的数字小键盘来完成。但在实际使用中,数据窗栏目间的切换却要通过按键盘最左边的Tab键来实现,既不方便又影响录入速度。如果能用Enter键替代Tab键切换栏目就好了。由于按Enter键是Windows直接支持的消息,故我们可以使用用户事件来解决问题。在用户事件中,PowerBuilder提供的一条pbm_事件对应Windows的一条或几条消息。我们在数据窗dw_datamon的用户事件中选择pbm_dwnProcessEnter并命名为Enterkeydown。在该事件下写代码:    Send(Handle(this),256,9,Long(0,0))    This.SetActionCode(1)  这将把消息传递给Tab键,同时忽略Enter键的处理。下面是一段用数据窗接收数据的完整的程序段,其中采用了用Enter键替代Tab键的代码。当光标在每行最后一列时按Enter键,光标会移至下一行第一列;当光标在最后一行的最后一列时按Enter键,会自动产生新行并将光标置于该行的第一列;在其它情况下按Enter键,光标会移至当前行的下一列。这段程序仍然写在与pbm_dwn ProcessEnter相对应的用户事件Enterkeydown下:  IF This.AcceptText()<0 then  this.setactioncode(1) return  endif  if this.getcolumn()=Long(This.DwDescribe("datawindow.column.count")) then  if this.getrow()=This.RowCount() then  this.insertrow(0)  this.scrolltorow(this.getrow()+1)  this.setcolumn(1)  this.setactioncode(1)  return  endif  endif  send(handle(this),256,9,long(0,0))  this.setactioncode(1)  5、数据从文本文件写入数据库表的捷径 许多情况下,文本文件中的数据排列顺序与数据库表中列的顺序一致,并且其数据类型与数据库表中对应列的一致,要做的就是将该文件中的内容存入对应数据库表中。例如在点对点通讯的情况下,一方把数据库表中的数据以文本文件格式存储并传送给另一方,另一方要做的工作就是将收到的数据存入相同的数据库表中。PowerBuilder有多种方式与文本文件打交道,比如使用ODBC的文本文件驱动器、采用DDE(动态数据交换)方式、采用OLE方式或使用Cursor将文本文件逐行逐列读取并写入数据库表等。但在这种情况下,还有一种更快捷的方法:使用ImportFile()函数将文本文件内容直接倒入数据库表中。该函数用法为: datawindowname.ImportFile(filename{,startrow{,endrow& {,startcolumn{,endcolumn{,dwstartcolumn}}}}}) ImportFile()函数要求数据窗列的数据类型和列的排列顺序必须与文本文件中的数据相匹配。在存储文本文件时要注意接收数据库对表的格式要求,比如在SYBASE中,表格的列与列间是采用Tab键区分的,所以如果要用ImportFile()函数将文件内容写入SYBASE表中,就要将相应文本文件的列与列间加入Tab键——这在文件形成时即可加入。下面的代码将文件infor.txt写入数据窗dw_infor,并将与dw_infor对应的数据库表更新:  int impt  if (FileLength("c:\data\infor.txt")>0) then  impt=dw_infor.ImportFile("c:\data\infor.txt")  if impt>0 then  dw_infor.settrans(sqlca) update(dw_infor) commit; If sqlca.sqlcode=-1 then  messagebox("SQLERROR",sqlca.sqlerrtext)  endif  else  messagebox("注意","文件infor.txt写入失败!")  endif  endif  此外,ImportFile()函数还支持从文本文件的指定开始行列到结束行列读取并写入数据;并且支持.dbf(dBase)文件的读写,这给原有台式数据库数据文件向新的分布式数据库表中转换带来了极大的方便。  五、有关文件输出的编程技巧  1、打印前的模拟显示的编程技巧 在制作完一段文档或表格后,我们在正式打印输出前总希望看一下模拟显示的效果,看看是否需要调整打印参数等。笔者在调试一个标签打印程序时就遇到了这个问题,标签文档的输出格式正确与否、标签间的横竖间距恰当与否等均可通过模拟显示直观地看到。总之,我们需要打印前的模拟显示。单纯写一段模拟显示程序并不难,但多思考一下往往能找到好方法。在文件读写时需要有文件号、在用Socket编程时涉及到Socket号,同样,多任务的操作系统管理进程时也采用了进程号——显然,整个软件系统都是采用一些数据类型为整型的变量来管理它要处理的逻辑对象的。一台打印机有它的逻辑文件名,在操作系统看来,它和磁盘上的一个文本文件没有两样。这样,向打印机输出与向磁盘文件输出就统一起来了,我们就依据这个想法来写模拟显示程序。大家知道,打印机的逻辑名是"PRN",我们可以对此作与磁盘文件相同的处理。下面的程序可写于按钮cb_print的Click事件下:  int retn,fileno  string filename,write_string  retn=Messagebox("提示","输出至打印机选,~r~n模拟显示(c:\simulate.txt)选,~r~n取消选! " ,Information!,YesNoCancel!,1) Choose Case retn  Case 1    sle_help.text="请准备好打印机!" filename="PRN"  Case 2    filename="c:\simulate.txt"  Case else   Return  End Choose  fileno=FileOpen(filename,linemode!,write!,lockwrite!,replace!)  if fileno=-1 then    Messagebox("警告","设备文件<打印机>打开失败!",information!,ok!)    Return  endif  write_string="打印前的模拟显示!"  FileWrite(fileno,write_string)  FileClose(fileno)  if Upper(filename)="PRN" then  sle_help.text="文件打印完毕!"  else  Run("Notepad.exec:\simulate.txt",maximized!)  sle_help.text="模拟显示文件输出完毕!"  endif  这样,当需要模拟显示时,write_string被送往磁盘文件c:\simulate.txt,并调用Notepad将其显示出来;当需要打印时,write_string被送往打印机。 六、结语写作本文不仅想与读者交流编程技巧,还希望向读者提供一些有用的思路。PowerBuilder不仅支持ODBC,而且支持MAPI,是企业级信息管理系统和Intranet应用开发的强大工具。笔者深信,PowerBuilder的应用范围将更加广泛,随着应用的深化,必定会涌现出更多优秀的PowerBuilder应用,并将在各行各业充分发挥作用。 TreeView控件能够清晰地表示层次关系,因而赢得了众多程序员的喜爱。在TreeView编程中,常见的一个问题是同步选择(即选择一个节点时,同时选择该节点的所有子节点;不选一个节点,同时去除该节点的祖先节点选择标志)。 要实现这种效果,本来不难,只需要在检测到节点选择状态变化时,遍历节点的祖先或者后代节点进行同步即可。但是PB并没有提供检测节点选择状态变化的事件。怎么办呢? 让我们来看看PB中TreeView节点选择状态的表示。当TreeView的CheckBoxes属性为True时,每个节点包含一个复选框。选中复选框时,StatePictureIndex属性为2,未选中则为1。当选择某个节点时,首先触发TreeView的Clicked事件,处理完Clicked事件后再对StatePictureIndex进行设置。显然,如果我们能够将Clicked事件前后节点的StatePictureIndex属性值进行比较,我们就可以判断节点的选择状态是否发生了变化。按照这个思路,疏理PB的事件模型,发现采用Post的调用事件方法,可以实现将一个事件加入控件消息序列,在处理完当前事件后再对新加入的事件进行处理。至此,我们得到了如下的解决方案: 1.       为TreeView控件添加一个用户事件ue_synchronizechildren(long handle, integer state),代码如下: long childitem treeviewitem tvitem getitem(handle, tvitem) tvitem.statepictureindex=state setitem(handle, tvitem) childitem=this.finditem(ChildTreeItem!, handle) do while(childitem<>-1)     this.Event ue_synchronizechildren(childitem, state) //递归遍历后代结点     childitem=this.finditem(NextTreeItem!, childitem) loop 添加一个用户事件ue_synchronizeparent(long handle, integer state),如下: long parentitem treeviewitem tvitem getitem(handle, tvitem) tvitem.statepictureindex=state setitem(handle, tvitem) parentitem=this.finditem(ParentTreeItem!, handle) if parentitem<>-1 then this.Event ue_synchronizeparent(parentitem, state)       end if 2.       添加一个用户事件ue_statechanged(long handle, integer prevstate)检测节点的选择状态, 如果发生了变化则调用ue_synchronizechildren同步后代节点,并根据需要通过ue_synchronizeparent同步祖先节点。代码如下: treeviewitem tvitem getitem(handle, tvitem) if tvitem.statepictureindex=prevstate then   return else   this.Event ue_synchronizechildren(handle, tvitem.statepictureindex)     if tvitem.statepictureindex=1 then //如需实现文末提及的功能,可在此处添加代码。            this.Event ue_synchronizeparent(handle, tvitem.statepictureindex)     end if end if 3.       在Clicked事件中,添加如下调用: treeviewitem tvitem getitem(handle, tvitem) post event ue_statechanged(handle, tvitem.statepictureindex)        为了简单起见,上面的代码并没有考虑当选上一个结点时,它的所有兄弟已被选择,因此父结点也应该被选择的情况,如有需要,请读者自己完成。 本 PowerBuilder数据窗口编程技巧十则 PowerBuilder取得巨大成就的原因就是有Datawindow对象,DataWindow是具有功能强大和灵活多变的特点,本人用PowerBuilder开发过一段时间后,,总结出一些技巧,以供广大的PB开发者借鉴使用。   一.如何创建一个报表,如下形式 Quantity Running Total 5,000 5,000 2,500 7,500 3,000 10,500 12,000 22,500   对于Running Total列,我们可使用计算列:CumulativeSum(Quantity for all),即可达到逐渐递增求和的功能。   二.数据窗口的数据送缓冲区之前确认的四个步骤 判断数据类型是否正确。如不正确则触发ItemError事件。判断数据是否符合有效性规则。如不符合有效性规则,同样触发ItemError事件。 判断是否有数据被改动。判断数据是否通过ItemChanged事件,如果数据和ItemChanged相斥,将触发ItemError事件。   三.如何在DataWindow中用数据类型为Datetime的列为条件进行查找   1.当要查找的日期条件是一常数时使用如下表达式:    ls_Find = "datetime_col     = DateTime ('1/1/1999')"   2.当要查找的日期条件是一个变量时使用如下的表达式:    ls_Find = "datetime_col = DateTime ('" + ls_Date + "')"   3.当要查找的日期条件是一个DateTime数据类型时使用如下表达式:    ls_Find = "datetime_col = DateTime ('" + String (ldt_DateTime) + "')"   四.设置数据窗口Boolean型属性的三种方法   PowerBuilder提供了三种方法设置数据窗口的布尔型属性,分别是True/False, 1/0, 'Yes'/'No'。例如: dw_1.Object.address.Visible = 0 dw_1.Object.address.Visible = False dw_1.Object.address.Visible = 'No'   PowerBuilder在处理上以字符串的形式保存属性,而不考虑属性值是布尔型、长整型或是字符型。 为了进一步理解,可以导出一个数据窗口并查看它的原码,可以发现即使是列的颜色属性它也是使用带双引 号的数字来表达。   五.如何在DataWindow中快速删除多行   在开发过程中可能经常有要进行多行删除的操作,一般都使用循环语句进行操作: FOR ll_RowOn = 1 TO dw_1.RowCount() dw_1.DeleteRow(ll_RowOn) NEXT   一个快速的删除方法是把要删除的行从主缓冲区中移到删除缓冲区中。例如,删除缓冲区中所有的行: dw_1.RowsMove(dw_1, 1, dw_1.RowCount, Primary!, dw_1, 1, Delete!)   不过不要忘了过滤的行在不同的缓冲区中。   六.如何在DataWindow的SQL语法中不使用SELECT DISTINCT实现删除重复的行   起先对你要显示唯一值的列进行排序:"city A",然后增加如下过滤字符串:" city < > city [-1] or GetRow () = 1"   七.如何在分组形式的DataWindow中分别显示各组的行号   当我们为Datawindow的每一行显示行号时,可以简单的放一个表达式为GetRow()计算列。但是对于分组的Datawindow,要分别显示各组的行号,则应使用表达式为 GetRow() - First(GetRow() for Group 1) + 1的计算列。   八.如何改变列的字体颜色,提醒用户此列已做修改   在列的Color属性中,输入如下表达式 IF (column_name < >column_name.Original, RGB(255, 0, 0), RGB(0, 0, 0))。   在这个条件中,如果此列已改变,则显示红色字体,否则显示黑色字体。这个表达式主要用column_name < > column_name.Original比较当前列的值和原始列的值是否相同来达到判断的目的。   九.在数据窗口中移走行,但不是去做过滤或删除操作   RowsDiscard()函数可做到这一点,它在数据窗口中执行移除工作,但被移走的行它不可被删除或做任何修改性的保存。   十.如何在多行显示的DataWindow 中的Footer Band中显示当前数据的首行和最后行的行号   我们先看两个计算列的表达式: IF (GetRow() = First(GetRow() FOR Page), 1, 0) // 1 为当前页的第一行 IF (GetRow() < > 1 AND GetRow() = Last(GetRow() FOR Page), 1, 0) // 1 为当前页的最后一行   由上面可知,在Footer Band中设置如下计算列表达式: 'Rows ' + String(First(GetRow() FOR Page)) + ' to ' + String(Last(GetRow() FOR Page)) + ' are displayed'。 浅析PowerBuilder下动态SQL语句  作者:张继荣 王举国 谭琦 谢元呈 发文时间:2004.12.22   PowerBuilder是目前最流行的数据库开发工具之一。PowerBuilder提供了在程序代码中加入嵌入式SQL语句的功能来支持对数据库的访问。但这种嵌入式SQL语句只能支持一些固定的 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 的SQL语句,即在进行程序代码编译处理时这些SQL语句必须是确定的,例如:对哪张表哪几个字段进行操作在程序代码中是固定写明的,另外这种方式也不能执行像Creat Table,Creat Database等这些数据库定义的语句(DDL)。 因此这种嵌入式SQL语句在实际应用中有一定的局限性。为克服这种方式的局限性,可以使用PowerBuilder提供的动态SQL语句,这种对数据库访问的方式可以完成嵌入式SQL语句无法实现的功能。如建库、建表这一类的数据库定义语句(DDL);其次,由于动态SQL语句允许在执行时才确定到底要执行怎样的SQL语句,因此使用动态SQL语句可以使程序实现参数化设计,具有很大的灵活性和通用性。 一、动态SQL语句的应用分析 PowerBuilder提供了四种格式的动态SQL语句,每种格式都有自己不同的特点和作用。下面我们对各种格式的具体使用方法分别加以说明。   (一)第一种格式   当执行没有输入参数并且没有返回结果集的SQL语句时可以使用这种格式,这种格式使用比较简单,其实现的操作也比较少。   1语法   EXECUTE IMMEDIATE SQLStatement{USING TransactionObject};   其中SQLStatement是要执行的SQL语句,可以直接用引号将要执行的SQL引起来用,或者用字符串变量的形式提供SQL语句。通过使用字符串变量可以在具体执行的时候才指定要执行什么样的SQL语句。TransactionObject是用户所使用的事务对象,缺省为SQLCA。   2应用实例   ①建立一张数据库表(base),SQL语句的表述用引号引起来直接使用。   EXECUTE IMMEDIATE‘CREATE TABLE base(code char(6),name char(30))’USING SQLCA;   ②执行对数据库记录的操作,在表base中插入一条记录,SQL语句通过字符串变量传递执行语句。   STRING lsSQL   LsSQL=”INSERT INTO TABLE base VALUES(’320201’,’市中区支行’)”   EXECUTE IMMEDIATE:lsSQL;   (二)第二种格式   当执行带输入参数但没有返回结果集时的SQL语句可以采用第二种格式。该格式不仅可以动态 PowerBuilder中的TreeView 控件为树状游览,类似于WINDOWS的资源管理器,其特点是信息项呈树状层次结构,能更清晰地表现主、细目关系 ,操作非常方便。在应用中可将其与DataWindow 配合使用, 一个提供信息的分类体系,一个提供具体信息,达到珠连碧合的奇妙效果。它特别适用于多级信息的分类检索, 是多级菜单所无法比似的,它的表现形式深受程序设计人员和广大用户的喜爱,在许多应用软件中都能看到她的英姿。   在PowerBuilder下,TreeView 控件的应用较其它控件要复杂得多,刚接触它时往往有些不知所措。但如果将它的机理搞清楚,掌握它也不是很难的事。下面我结合长白公司图书分类检索的实例,把TreeView 控 件的使用方法和大家探讨一下。   一、应用TreeView 控件的一般步骤   1、 建立一个应用,并设好与数据库的接口,这是操作数据库的前提。   2、 在应用中建一应用窗口W_1,在其上加入二个名为dw_3和dw_4的datawindow控制对象和一个名为TV_1的TreeView对象。   3、 修改DW_3属性   General:把Datawindow object name填写一个已存在的名为DW_date的datawindow(注意:它与datawindow控制对象是不同的),用于生成树视图项,将其Visible项设为不可见。   4、 修改DW_4属性   General:把Datawindow object name填写一个已存在的名为DW_TS的datawindow对象,用于显示查询出的具体内容。   5、 编辑TV_1的属性   TreeView的树视图项不能直接编辑,必须在Script中编写程序。   Picture:在Picture Name中加入四个不同的图标,用于代表树视图中的两个层次(一、二级)、两种状态(未选、选中)。   General:可根据具体应用设定是否选中,其中:   Delete Items:运行中是否允许删除表项。   Disable PragDrog: 运行中是否允许拖放表项。   Edit Labels: 运行中是否允许单击表项来改变表项的标题。   Show Buttons:是否在表项放显示+-按钮,有示相对的扩展和收缩。   Hide Selection:当该控件失去焦点时,选中项是否以高亮度显示。   Show Line:表项间是否加一竖线。   Lines At Root:所有根层表项是否用竖线连接。   Indentation:子表项相对于父表项的向右缩进度。   6、 编写TV_1的Script   这里是TreeView控件的关键,也是难点。   二、TreeView 控件的信息构成及创建   树视图项TreeViewItem是TreeView 控件的基本信息单位,树视图项的生成一般有二种方法,一种是先生成根层视图项,再在应用中动态生成下级视图项,另一种是把全部树视图项一次和成。两种方法各有优点,请根据具体情况选用,本例中采用后一种方法。   1、 树视图项TreeViewItem的主要属性   Label:String 型,树视图项的显示信息。   Data:Any型,树视图项的内部值。   Level:Integer型,树视图项在树视图中级别。   Children:Boolean 型,它决定该项是否有下一层(如图中书名)。   PictureIndex:Integer 型,该项非选中时所用的图标在图标队列中的编号。   SelectedPictureIndex:Integer型,该项选中时所用的图标在图标队列中的编号。   2、 生成TreeViewItem项用到的函数   InsertItemFirst():将加入项作为第一项   InsertItemLast():将加入项作为最后一项   InsertItem():将加入项插入到指定项的后面   InsertItemSort():按顺序放置。   3、 TreeView的常用事件   Constructor: 该事件在控件创建时触发,可在这里构造TreeViewItem。   Click:单击TreeViewItem项时,执行查询程序。   Double Click: 双击TreeViewItem项时,执行查询程序。   ItemPopulate 事件: 该事件在某TreeViewItem项首次展开时触发, 触发的同时系统会将 该TreeViewItem项的句柄通过参数handle 传递过来。它主要用来生成对应项的下层信息项。主要用于第一种方法。   三、 事件代码   1、树视图控件TV_1的constructor事件代码 wanqi 1999.6.28 integer li_rowcount,li_row string li_current_dn,li_last_dn,li_current_ei,li_last_ei //声明二个树视图的实例变量 treeviewitem itvi_level_one,itvi_level_two //long ii_h_l_one //long ii_h_l_two dw_3.settransobject(sqlca)//dw_3 为隐含的数据窗口,存有生成树的数据 li_rowcount=dw_3.retrieve()//行数 dw_3.setsort("lb,pm") dw_3.sort() //生成树视图的各级树视图项 for li_row=1 to li_rowcount li_current_dn=dw_3.object.lb[li_row] //DW_3对象中"LB类别" li_current_ei=dw_3.object.pm[li_row] //DW_3对象中"PM品名" if isnull (li_current_ei) then li_current_ei="" end if if li_current_dn< >li_last_dn then //IF LB不与一级视图项重复 //设置一级树视图项 itvi_level_one.label=dw_3.object.LB[li_row] //视图项的显示信息 itvi_level_one.level=1 //级别 itvi_level_one.data=li_current_dn //视图项的内部信息 itvi_level_one.pictureindex=1 //没选中时所用的图标序号 itvi_level_one.selectedpictureindex=3 //选中时使用的图标序号 itvi_level_one.children=(li_current_ei< >' ') //树视图是否有下一级 ii_h_l_one=this.insertitemlast(0,itvi_level_one) //将项加入到一级树的最后一项 end if //设置二级树视图项 if li_current_dn< >li_last_ei then if li_current_ei<>' ' then itvi_level_two.label=dw_3.object.pm[li_row] itvi_level_two.level=2 itvi_level_two.data=li_current_dn itvi_level_two.pictureindex=2 itvi_level_two.selectedpictureindex=4 itvi_level_two.data=li_current_ei itvi_level_two.children=false ii_h_l_two=this.insertitemlast (ii_h_l_one,itvi_level_two) //将项加入到二级树的最后一项 end if end if li_last_dn=li_current_dn//设比较项 li_last_ei=li_current_ei next   2、tv_1控件的clicked事件代码 string s1 treeviewitem ii this.getitem(handle,ii) s1=string(ii.label) choose case ii.level case 1 //过滤类别 dw_4.setfilter("lb='"+s1+"'") dw_4.filter() case 2 dw_4.setfilter("pm='"+s1+"'") dw_4.filter() //过滤书名 end choose 如何制作PSR文件浏览器 作者:unknown 更新时间: 2005-03-13 PB(PowerBuilder)有一种以PSR结尾的特殊的保存报表的文件格式(本文简称作PSR文件)。当报表以PSR格式另存出来后,我们常常会不知道用什么方法再次打开它。 其实很简单,下面将介绍打开的办法: 先新建一空的库文件(PBL文件),这里命名为psropen,在库文件中的应用也命名为psropen。 再创建一窗口w_psropen,稍微调一下它的属性,如width,height,title等。 在窗口中添加按钮cb_1,cb_2,cb_3,cb_4,分别命名“另存为”,“打印”,“选择文件”,“返回”。 在窗口中添加一数据窗口dw_1。 另存为按钮clicked的代码: St
本文档为【PB编程技巧实例】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_396354
暂无简介~
格式:doc
大小:122KB
软件:Word
页数:36
分类:工学
上传时间:2012-01-04
浏览量:68