PowerBuilder最吸引人的地方就是她那强大的数据窗口技术,它为展现数据的本质提供了丰富的手段,数据窗口能够从多种数据源提取数据,然后以多种风格展现在用户面前,对于一个PB程序员能否用好用活数据窗口是那么的重要,同时也反映出编程人员的一定技术水平。相信在看了本文之后一定会对你编写程序有所帮助,文中如有任何不妥之处还请同仁们多多指教。
在实际的应用中我们或许会碰到用户有这样的要求,在第一张报表上打印一个客户的购买商品的统计数据,以后的每页显示的是他购买商品的明晰清单。也就是相当于打印两份报表,一份是统计报表,另一份是明细表。单纯就这两份报表而言对于任何一个PB程序员来说都不是什么难事,很容易就可以搞定,我们完全可以分两张报表打印给用户,但这还总是让我们觉得似乎缺了点什么,毕竟用户是想让这两份报表作为一个整体出现,最起码的要求是它们的页号应该连续,并且同时也能告之用户总共有多少页。这就涉及到多个数据窗口连续打印的问题。 财软联盟 fs119.net
首先,统计和明细的结果是根据用户输入的条件来得到的,这是个不定的结果,我们无法预先得知会有多少条数据,更别说需要多少页了。即便是我们能够确定有多少条数据也会因为用户打印机的纸张设置不同而会出现不同的显示结果。其次,要在统计表和明细表里显示两张报表的总页数,这个有点难度,毕竟对于两张报表来说都是个未知数,即对于统计表来说,它可以知道自己的总页数,但不知道明细表的总页数。同样对于明细表也是这样,只知道自己的总页数,而不知道统计表的总页数。这样很难在两张报表里分别显示它们的页数之和。虽然如此可对于它们自己而言当前是第几页还是能够确定的,这个只要调用数据窗口的内嵌函数Page()就可以很容易的得到。
下边我们就通过一个简单的例子来探讨如何实现多个数据窗口连续打印技术。程序首先让用户输入客户号,然后系统根据用户输入的客户号统计出该客户各类商品的购买总数以及订购的每一种商品明细。整个程序的执行如下三副图所示: 财管家.园.fs119.net
财软 联盟 fs119.net
财管 家园 fs119.net 财软.联盟.fs119.net
在开始之前先让我们看一下例子中用到的三张表的结构以及它们之间的相互关系,见下图:
其中,表Customer和表Sales_Order通过cust_id(客户编号)相关联,表Sales_Order和表Sales_Order_Items通过id(销售定单号)相关联。这三张表取自于PB自带的演示数据库。
首先我们要做的第一件事就是制作两张带检索参数的数据窗口,这个很简单我就不细说了。其中,统计表命名为dw_1,明细表命名为dw_2。同时,为了在打印的时候显示给用户“第几页”“总共多少页”的信息,因此在两张报表每页的底端分别加上一个计算域用来显示当前页数和总页数信息。以统计表dw_1为例,在dw_1中增加两个计算域,取名为page_1和computer_2。见下图:
接下来要做的就是如何正确给这两个计算域赋值。对于当前页的显示,在前面已经说过了,可以直接在计算域的表达试中调用数据窗口的内嵌函数Page(),因此,在page_1的表达式中写上函数Page()。
财管家园 fs119.net
财管家园 fs119.net
财 管家园 fs119.net
财.管家园.fs119.net
现在来实现总页数赋值。我们知道在在数据窗口的内嵌函数中除了能得到当前页的Page()函数,还有一个函数叫PageCount(),它的功能是得到当前报表的总页数。如果说只有一张报表的话直接把它写上就行了,但问题是现在的总页数实际上是当前报表(统计表)总页数加上另一张报表(明细表)总页数之和。为了在统计表中得到明细表的总页数,我们不妨再增加一个计算域next_pagecount,该计算域保存有明细表的页数。见下图: 财软联.盟.fs119.net 财 软联盟 fs119.net
由于该计算域的放置是为了在程序中能够引用,相当于一个变量,目的也只是得到明细表的页数,这对于用户来说他并不需要知道,所以将它设为不可见,即Visible属性为FALSE。然后设置该计算域的表达式为:“0”。这只是个初始值,需要在程序中更新。
要在程序中动态得到一个数据窗口的页数需要用到两个函数Describe()和Evaluate(),函数的意义如下:
1、函数Describe()
定义:
dwcontrol.Describe(propertylist)
它的功能是返回数据窗口控件结构方面的指定信息,包括数据窗口对象以及数据窗口对象中其他对象的属性取值。你可以在这个函数中指定一个或者多个需要取得值的属性字符串,此外,该函数还能执行数据窗口内嵌函数组成的表达试。
其中,参数Dwcontrol表示连接数据窗口对象的数据窗口控件、子数据窗口控件或者数据存储。Propertylis表示String类型的变量,可以是属性列表或内嵌函数表达式。该函数返回String类型的变量。有关Describe()的具体含义和用法还请参阅用户手册。
2、函数Evaluate()
定义:
Evaluate('expression',rownumber)
它是Describe函数中的一个求值函数,它可以执行数据窗口画笔中定义的计算域中的表达式,并返回字符型结果。其中,Expression代表想要执行的包含内嵌函数的表达式;Rownumber表示要执行表达式的数据窗口内的数据行
3、举例说明:
stringls_return
ls_return=dw_1.Describe("Evaluate('if(sales_amount>2,0,sale_amount)',1")
以上代码表示,如果第一条数据的sales_amount值大于2,则函数返回“2”,否则ls_return的值为sales_amount。注意,函数Describe返回的是字符串类型的数据。
有了这两个函数之后我们就可以在程序中得到一个数据窗口的页数,实现代码如下
stringls_pagecount
ls_pagecount=dw_2.Describe("Evaluate('pagecount()',1)")//得到DW_2中总页数
dw_1.object.next_pagecount.expression=ls_pagecount//给计DW_1中的算域赋值
最后我们就可以在computer_2计算域的表达式中写上:pageCount()next_pagecount,从而得到两张报表的页数之和。
对于明细的表的做法也是如此,就不再浪费笔墨了。需要提醒大家注意的是,由于明细表是紧接着统计表打印出来的,所以它的当前页数理所当然应该接着统计表连续下去,因此在明细表的当前页数计算域中不能是简单的page(),因该加上统计表的总页数,即,page()previous_pagecount。其中previous_pagecount为计算域,是用来存放统计表的总页数,它相当于统计表中的next_pagecount。同样,也应该在代表总页数的计算域的表达式中加上统计表的总页数,即,pagecount()previous_pagecount。
当全部设置完之后我们可以来看看效果如何了。运行一下,两张报表的当前页数和总页数都很正确,而且第二份报表的页数也是正好承接于第一份报表。在目前看来至少是符合了程序的设计要求,现在我们来打印看看...奇怪,怎么报表的页号乱了?是不是程序写错了?...都不是!通过分析显示的报表和打印的报表我们发现,原来我们上面所取得的报表总页数都只是显示时候的,即它的结果是根据你的数据窗口控件的大小计算出来的。也就是说,假设这次在数据窗口里检索出10条符合条件的记录,如果数据窗口做的足够大的话,那么这10条记录是在一页中显示,但如果数据窗口做小了,数据就会分成几页显示(相对于数据窗口控件的大小),在这种情况下我们就会看见在数据窗口控件的右边出现一个垂直滚动条允许用户通过上下滚动查看全部的数据。无论你的数据窗口做的大还是小,这10条记录在一张标准的A4纸上是完全可以打印的下,这也就是为什么会出现上面的这种页号和总页数不相符的原因。
财,管家园,fs119.net
财 管家园 fs119.net
财软联盟.fs119.net 那么,是不是就没有办法解决了呢?当然不是,PB为我们提供了一个数据窗口对象的打印预览属性,在缺省的状态下是FALSE,即显示数据窗口的时候为非预览模式,你只要在程序将它改True,预览模式显示就可以了,注意别忘了两个数据窗口都要是预览模式。修改代码如下: 财软联,盟,fs119.net
dw_1.object.datawindow.print.preview=true
dw_2.object.datawindow.print.preview=true
好了,现在我们在来运行一下看看,打印一份,结果正确,完全符合要求。见图
至此,整个程序结束。下面是完整的程序代码:
*********************程序代码**********************
//设置两张报表的显示模式为预览模式
tab_1.tabpage_1.dw_1.object.datawindow.print.preview=true
tab_1.tabpage_2.dw_2.object.datawindow.print.preview=true
tab_1.tabpage_1.dw_1.Retrieve(integer(tab_1.tabpage_3.sle_1.text))
tab_1.tabpage_2.dw_2.Retrieve(integer(tab_1.tabpage_3.sle_1.text))
stringls_pagecount
//得到明细表中的页数
ls_pagecount=tab_1.tabpage_2.dw_2.describe("Evaluate('pagecount()',1)")
tab_1.tabpage_1.dw_1.object.next_pagecount.expression=ls_pagecount
//设置统计表中的存放明细表总页数的计算域next_pagecount
//得到统计表中的页数
ls_pagecount=tab_1.tabpage_1.dw_1.describe("Evaluate('pagecount()',1)")
//设置明细表中的存放统计表总页数的计算域previous_pagecount
tab_1.tabpage_2.dw_2.object.previous_pagecount.expression=ls_pagecount
*********************结束**********************
至此,有关多个数据窗口连续打印技术就全部讲述完毕,为了便于大家能够更好的理解,我提供了一个PB的源程序,它是在WIN98环境下,PB7.03调试通过。由于本文所用的数据库是PB自带的例程数据库所以没有被打包。 财管家 园 fs119.net
Google.cn搜索相关文章:
谷歌中搜索全球网 在PB7.0中实现多数据窗口的连续打印
百度中搜索 在PB7.0中实现多数据窗口的连续打印
谷歌中搜索www.fs119.net 在PB7.0中实现多数据窗口的连续打印
下一篇:PB中数据窗口的精确页面打印技术