数据窗口是
Pb
的一个特色控件,有了数据窗口对于
pb
来说可谓如虎添翼。
对数据库中的数据操作,几乎都可以在数据窗口中完成。
使用数据窗口可以简单检索数据、以图形化的方式显示数据、绘制功能强大的数据统计报表。
一、 数据窗口画板
数据窗口画板由Design, Preview, Control List, Data, Properties和 Column Specification 6个试窗构成
1.1 Design 视窗
Design 是一个非常重要的视窗 ,使用菜单 Design→Options 来改变 Design 窗口的外观
1.1.1 General tab页设置
①
Snap to Grid
:选中该属性时,在数据窗口中的部件自动和网格对齐, 建议都选中
②
Show Grid
:是否显示网格。
-- 未选中
-- 选中后
④
X, Y
:网格之间的间距,单位是数据窗口属性中设置的单位
⑤
Show Edges
:是否显示边框。主要针对字段、标签、文本等而言
⑥
Retrieve on Preview
:是否在预览时检索
1.1.2 Generation tab页设置
①
Presentation Style
:在该下拉列表框中可以选择要设置哪种类型的数据窗口。下面的
其他操作都是针对选中的那种类型的数据窗口而言的。
②
Background Color
:设置数据窗口的背景颜色。
③
Text 组框
: border 可以设置 text 部件的边框类型, color 可以设置文本的颜色。
④
Columns 组框
: border 可以设置字段的边框类型, color 可以设置字段中文字的颜
1.1.3 Prefixes tab页设置
设置数据窗口中放置部件时命名的默认前缀
1.2 Preview 视窗
可以预览数据窗口的外观,并显示相应表中对应的数据
在该窗口中可以进行各种数据操作,包括数据过滤、数据排序、增加数据、删除数据、检索数据、查找数据以及翻页等
这些操作都可以在鼠标右键弹出菜单中完成
1.2.1 查找数据
--呼出菜单
-- 查找内容
1.4 Data 视窗
显示的是数据窗口对象中的数据,很多操作和 Preview 视窗中的都相同 .
该视窗侧重于对应表中各个字段的取值,而 Preview 视窗侧重于数据窗口对象的显示效果
1.5 Properties 视窗
属性视窗显示的是当前选中对象的属性,可以对这些属性进行修改
1.6 Column Specification 视窗
是一个比较重要的视窗,在该视窗中可以增加、删除、修改列的初始值、检验表达式或者校验信息
举个栗子:
假设
empno
的位数是 10,如果位数不正确,则应该提醒用户。
在
Validation Expression
列为字段
empno
输入校验表达式:
len(empno) = 10
在
Validation message
中输入:'员工编号必须为 10 位! '
当程序运行时,会自动校验用户输入的内容是否位数为 10 位,否则显示输入的信息
二、数据窗口的数据源
Pb
提供的
Quick Select
(快速选择类型)、
SQL Select
( SQL 选择类型)、
Query
(查询类型)、
External
(外部类型) 和
Stored Procedure
(存储过程类型) 5种数据源
2.1 Quick Select 数据源
快捷数据源,是经常使用的一种数据源,可以快速地创建数据窗口 。
使用这种数据源,只能从一个数据表或者视图中选取数据
需要从多个数据表中选取数据而且还想使用这种数据源时,只能创建对应的视图
3.1 Grid 显示样式
数据窗口布局整齐,但不能灵活地安排字段、标签、表头的布局
字段横向排列在 detail band 中,标签横向排列在 header band 中,和字段相对应,字段和字段之
间有网格线分隔,类似于电子表格 。
如下图所示
3.2 Tabular 显示样式
字段、标签的布局和 Grid 显示样式的数据窗口相同,都是横向排列的,但是字段之间没有网格线分隔。
字段和标签的布局可以随意调整,在 header band 中的标签可以随意拖放到 detail band 中,
detail band 中的字段也可以拖放到 header band 中
3.3 Group 显示样式
数据窗口可以指定按那个(或那些)字段进行分组,可以用指定的分组条件将数据分组显示,并且允许为每组指定一些计算。
例如:要显示各部门员工的薪资数据,可以按部门分组
-- ①按部门分组
-- ②分组后数据
如果用户想要生成邮件标签,可以使用 Label 显示样式的数据窗口来实现
在向导的指引下,可以设定标签的一些参数。
可以指定标签的大小,包括三方面的设定: Label 本身的大小、Label 之间的边框、 Label 的布局顺序。
在 Label 组框中,参数“ Across”指横向显示的标签数目, “ Down”表示一页中竖向显示的标签数目
Header
出现在每页的顶端,用于显示标题和列的题头。
放置表头、报表日期等一些能够方便查阅的内容, 即使这部分字段的 Tab Order 值不为 0、 DisplayOnly 属性为 False 也不允许用户编辑,并且也只能显示多条记录中的一条
Detail
包含了数据窗口对象的主体,显示了各行的数据和相关的标签。
放置数据、表格,程序运行时,数据窗口自动处理该区域,根据数据库中的数据显示一条或者多条数据
Summary
出现在每页的底端,用来显示文本和页号
放置页内小计、页号等页脚方面的内容
Footer
出现在 DataWindow 对象的最后一页,用来为整个数据窗口对象显示总计和总和
放置总计、制表人等需要在表格最后放置的内容
五、数据窗口常用函数
dw_1.update(accept,resetflag)
accept
:默认为true,执行之前调用
resetflag
:默认为true,数据窗口自动重置更新标志
成功返回1,失败返回-1
修改或更新操作
dw_1.setsort(format)
format
: A 升序,D降序
成功时返回1,失败时返回-1
dw_1.sort()
成功是返回1,失败时返回-1
按照当前数据窗口 的排序规则进行排 序
dw_1.setfilter(format)
format
:是字符串,可以使用字段名或字段号定义
成功时返回1,失败时返回-1
例1:
dw_1.setfilter("sal> 5000 and age < 10000")
例2:
dw_1.setfilter(#3>5000)
例3:
dw_1.setfilter("")
设置数据窗口的过 滤条件
dw_1.filter()
对数据窗口进行过 滤
dw_1.reset()
成功返回1,失败返回-1
清除数据窗口的所 有数据
dw_1.scroll(number)
number
:滚动的行数
参数为正数的时候向下滚动,为负数时向上滚动
成功返回控件第一行显示的数据行号,失败时返回-1
设置滚动的行数
dw_1.scrolltorow(row)
row
指定的行号
成功返回1,失败返回-1
滚动到指定行
dw_1.scrollpriorpage()
滚动到上一页
dw_1.ScrollNextPage()
滚动到下一页
dw_1.scrollpriorrow()
滚动到上一行
dw_1.scrollnextrow()
滚动到下一行
dw_1.getrow()
没有当前行时返回0,失败返回-1,成功返回当前行号
获得当前行的行号
dw_1.getcolumn()
没有当前列时返回0,失败返回-1,成功返回当前列的 列号
获取当前列的列号
dw_1.setrow(row)
row
指定的行号
成功返回1,失败返回-1
设置当前行
dw_1.setcolumn(column)
coumn
列号或列名
成功返回1,失败返回-1
例:设置当前列为第5列
dw_1.setcolumn(5)
例:设置当前列为age列
dw_1.setcolumn("age")
设置当前列
dw_1.setrowfocusindicator(f,x,y)
f
用于指示当前行的可视化图标
x
x坐标
y
y坐标
成功返回1,失败返回-1
例:设置手形图标
dw_1.setrowfocusindicator(Hand!)
例2:设置图片控件p_arrow为指示图标
dw_1.setrowfocusindicator(p_arrow)
设置用于指示当前 行的可视化图标
dw_1.rowcount()
无数据时返回0,失败返回-1
获得数据窗口总行 数
dw_1.modifiedcount()
返回被修改但未更新的数据行数
无数据时返回0,失 败返回-1
获得数据窗口中被 修改,但未更新的 数据行数。(不包 括新插入的行)
dw_1.deletedcount()
无数据时返回0,失败返回-1
获得数据窗口中做 了删除标记,未做 update操作的数 据行数
dw_1.filteredcount()
无数据时返回0,失败返回-1
获得被过滤掉的数 据行数
dw_1.accepttext()
将还在编辑中的数 据,传送到数据窗 口控件
dw_1.gettext()
获得编辑控件中的 文本
dw_1.settext(text)
成功返回1,失败返回-1
设置编辑控件中的 文本
dw_1.GetItemDate (row,column,dwbuffer,originalvalue)
row
指定数据行的行号
column
: 指定的数据列
dwbuffer
: 指定读取数据的缓冲区
originalvalue
为true时,返回原始缓冲区的值,为 false时返回当前值
例:取数据窗口
dw_1
第3行
first_day
字段的日期型变量
dw_1.getitemdate(3,"first_day")
获取指定字段的日 期型变量
dw_1.GetItemDateTime(row,column,dwbuffer,originalvalue)
row
: 指定数据行的行号
column
: 指定的数据列
dwbuffer
指定读取数据的缓冲区
originalvalue
为true时,返回原始缓冲区的值,为 false时返回当前值
获取指定字段的日 期时间型变量
dw_1.GetItemTime(row,column,dwbuffer,originalvalue)
row
指定数据行的行号
column
: 指定的数据列
dwbuffer
指定读取数据的缓冲区
originalvalue
为true时,返回原始缓冲区的值,为 false时返回当前值
获取指定字段的时 间型变量
dw_1.GetItemString(row,column,dwbuffer,originalvalue)
row
指定数据行的行号
column
: 指定的数据列
dwbuffer
指定读取数据的缓冲区
originalvalue
为true时,返回原始缓冲区的值,为 false时返回当前值
获得指定字段的字 符串变量
dw_1.GetItemNumber(row,column,dwbuffer,originalvalue)
row
指定数据行的行号
column
: 指定的数据列
dwbuffer
: 指定读取数据的缓冲区
originalvalue
为true时,返回原始缓冲区的值,为 false时返回当前值
获得指定字段的数 值型变量
dw_1.GetItemDecimal(row,column,dwbuffer,originalvalue)
row
指定数据行的行号
column
: 指定的数据列
dwbuffer
指定读取数据的缓冲区
originalvalue
为true时,返回原始缓冲区的值,为 false时返回当前值
获得指定字段的小 数型变量
dw_1.sharedata(dwsecondary)
成功返回1,失败返回-1
数据窗口控件数据 共享,保持同步更 新
dw_1.sharedataoff()
成功返回1,失败返回-1
关闭数据窗口之间 的共享关系
dw_1.print()
成 功返回1,失败返回-1
打印数据窗口
dw_1.printcancel()
成功返回1,失败返回-1
取消数据窗口的打 印
dw_1.getitemstatus (row,colum,dwbuffer)
row
: 指定数据的行号
column
: 指定的数据列
dwbuffer
: 指定读取数据的缓冲区,默认为主缓冲区, 返回一个
dwitemstatus
枚举变量
例:取数据窗口
dw_1
第5行work字段在filter缓冲区的 状态
l_status l_status = dw_1.getitemstatus(5,'work',filter!)
获取指定字段的状 态
dw_1.setitemstatus (row,colum,dwbuffer,status)
row
: 指定数据的行号
column
: 指定的数据列
dwbuffer
:指定读取数据的缓冲区,默认为主缓冲区, 返回一个
dwitemstatus
枚举变量 status 枚举变量
例:设置数据窗口
dw_1
第5行party字段在主缓冲区的 状态为
notmodified
l_status l_status = dw_1.setitemstatus(5,'salary',primary!,notmodified!)
设置指定字段的状 态
dw_1.setitem(row,column,value)
row
: 指定的行
column
:指定的列
value
: 赋值的内容
为指定字段赋值
dw_1.getvalidate(column)
column 定义检验规则的字段(序号或字段名)。返回 指定字段的有效性检验规则
获取当前某些字段 的有效性检验规则
dw_1.setvalidate(column,rule)
column 定义检验规则的字段(序号或字段名) rule 新的有效性检验规则
成功返回1,失败返回-1
设置当前某些字段 的有效性检验规则
六、数据窗口使用技巧
6.1 数据窗口的增删改查
6.1.1 将编辑的数据放到主缓冲区
dw_1.accepttext()
6.1.2 增加一行数据
dw_1.insertrow(0)
6.1.3 删除一行数据
dw_1.deleterow(row)
6.1.4 更新数据
dw_1.update()
在使用update()
函数将修改的数据保存到数据库中时,必须要设置数据窗口的修改属性。
数据窗口只能修改一个数据表
当增加、删除或者重新选择了字段时, PB
将数据窗口的修改属性置为不允许,这时也应该进行手工设置
单项 Rows→Update Properties 进行修改属性的设置
Allow Updates : 选中该选项,才允许继续进行其他属性的设定
Table to Update :要被更新的表
Where Clause for Update/Delete
思路: 动态修改数据窗口的Update属性
举个栗子: dw_1数据窗口中包含两张表的字段,emp(员工信息表),dept(部门表)
select dept.deptno,dept.dname,
emp.empno,emp.ename
from emp,dept
where emp.deptno = dept.deptno
在创建数据窗口时设置为 dept 表可修改
Int li_update
li_update = dw_1.Update(True,False) //接受最后一个字段内容,并且不清除行修改标志
// 如果对 Department 表的修改成功,下一步就要修改另一个表 Employee
If li_update = 1 Then
//首先,关掉对 dept 表的修改
dw_1.ModIfy('dept_dname.Update = "No"')
dw_1.ModIfy('dept_deptno.Update = "No"')
dw_1.ModIfy('dept_deptno.Key = "No"')
//使 emp 表成为新的可修改表
dw_1.dwModIfy('DataWindow.Table.UpdateTable = ~'emp~' ')
dw_1.ModIfy('emp_empno.Update = "Yes"')
dw_1.ModIfy('emp_ename.Update = "Yes"')
dw_1.ModIfy('emp_empno.Key = 'Yes' ' )
//然后修改 Employee 表
li_update = dw_1.Update()
If li_update = 1 Then
Commit Using SQLCA;
MessageBox("修改错误! ", "数据修改错误,错误代码"&
+ String(SQLCA.SqlDBCode) + "~r~n 错误原因: "+ SQLCA.SqlErrText)
Rollback Using SQLCA;
End If
//恢复数据窗口开始时的属性,以便下一次用户单击“保存”按钮时
//程序能够正确执行
dw_1.ModIfy('dept_dname.Update = "Yes"')
dw_1.ModIfy('dept_deptno.Update = "Yes"')
dw_1.ModIfy('dept_deptno.Key = "Yes"')
dw_1.ModIfy('DataWindow.Table.UpdateTable = ~'dept~' ')
dw_1.ModIfy('emp_empno.Update = "No" ')
dw_1.ModIfy('emp_ename.Update = "No" ')
dw_1.ModIfy('emp_empno.Key = "No" ')
MessageBox('部门表更新失败,回滚更改为部门')
Rollback Using SQLCA;
End If
6.3 设置字段只读
① 方法一
将tab order 设置为0
② 方法二
dw_1.modify("cname.tabsequence = 0 ")
③ 方法三
dw_1.modify( "meno.edit.displayonly=yes")
④ 方法四
dw_1.modify("code_course.protect= 1")
6.4 切换数据窗口数据源
dw_1.dataobject = "数据窗口名"
6.5 隐藏数据窗口刷新过程
dw_1.setredraw(false) //不刷新
dw_1.setredraw(true) //刷新
6.6 数据窗口共享数据
dw_2.sharedata(dw_1)
6.7 数据窗口SQL中传递 in 的参数
select emp.empno,emp.ename,emp.job,emp.mgr,emp.hiredate,emp.sal,emp.comm from emp where emp.empno in (传入的参数)
//在传给数据窗口时,in中的内容必须是数组类型
string[] arr_in
arr_in[1]='7369'
arr_in[2]='7499'
arr_in[3]='7521'
dw_1.retrieve(ls_in)
6.8 获取当前数据窗口的sql
dw_1.getsqlselect()
6.9 设置当前数据窗口的sql
dw_1.setsqlselect(sql)
6.10 调用子数据窗口
integer rtncode
datawindowchild dwc_child
rtncode = dw_1.getchild("主窗口字段", dwc_child)
if rtncode = 1 then
messagebox('',dwc_child.getitemstring(1,'子窗口字段'))
messagebox('提示','未获取到子数据窗口!')
end if
6.11 判断数据窗口是否被修改
//判断数据窗口是否修改,建议写在closequery事件中
if dw_1.modifiedcount() + dw_1.deletedcount() > 0 then
messagebox('提示','数据窗口已经修改,是否保存?')
messagebox('提示','数据窗口没有修改,正常退出')
end if
6.12 数据窗口重置
dw_1.reset()
6.13 数据窗口重新分组
//重新分组,在我们处理过滤和排序后,如果是分组窗口可能会破坏分组规则
//所以我们要进行重新分组,重新分组一般都是在filter()或sort()后面
dw_1.groupcalc()
6.14 获得数据窗口的状态
//(可选状态:datamodified! new! newmodified! notmodified!)
//当第一次使用retrieve()函数从数据库中读取数据时,所有在数据窗口缓冲区的记录与字段都是属于
NotModified!状态。
//当时数据被修改过后,被修改过的记录状态标志与字段状态标志都会被改成DataModified!
//当增加一笔数据时,增加数据的字段状态标志为NotModified!,记录状态标志为New!.
//当我们在增加的字段中填上数据后,字段状态标志为DataModified!记录状态标志为NewModified!
if dw_1.getitemStatus(1,dw_1.deletedcount(),primary!) = datamodified! then
messagebox('1:已修改数据','datamodified!')
elseif dw_1.getitemStatus(1,dw_1.deletedcount(),primary!) = new! then
messagebox('2:已增加数据','new!')
elseif dw_1.getitemStatus(1,dw_1.deletedcount(),primary!) = newmodified! then
messagebox('3:已填写数据','newmodified!')
elseif dw_1.getitemStatus(1,dw_1.deletedcount(),primary!) = notmodified! then
messagebox('4:未修改数据','notmodified!')
end if
6.15 设置数据窗口状态
//(可选状态:datamodified! new! newmodified! notmodified!)
dw_1.setitemstatus(1,dw_1.deletedcount(),primary!,notmodified!)
6.16 查找数据窗口中第一个被选中的行
dw_1.getselectedrow(0)
6.17 数据窗口查找(find)
//dw_1.find(查找条件表达式,开始行, 结束行), 如果表达式成立,那么就返回符合条件的行号
dw_1.find('id=8',1,10)
6.18 数据窗口过滤
① 列名过滤
dw_1.setfilter("isnull(列名)")
dw_1.filter()
②条件过滤
dw_1.setfilter("列名='" + 列值 + "'")
dw_1.filter()
③ 清除过滤
//方法一
dw_1.setfilter('')
dw_1.filter()
//方法二
dw_1.setfilter('1=1')
④ sql语句过滤
sql = 'select * from 表名 where isnull(字段名 , ''空'') = ''空'' ' ;
6.19 数据窗口分页
Ⅰ 增加一个计算列
计算列必须放在detail段
expression中输入:ceiling(getrow()/20)
这里表示每页20条数据
这里20还可以用全局函数取代,这样可以允许用户任意设置每页多少行。
Ⅱ定义分组,选择菜单rows->create group...
按计算列字段分组,并一定将check box-->new page on group break选中
Ⅲ 将此计算列设为不可视
然后添加以下按钮,完成分页功能
dw_1.scrolltorow(0)
dw_1.setrow(0)
② 上一页
dw_1.scrollpriorpage()
③ 下一页
dw_1.scrollnextpage()
④ 最后一页
dw_1.scrolltorow(dw_1.rowcount())
dw_1.setrow(dw_1.rowcount())
6.20 数据窗口排序
① 正序排列
dw_1.setsort("列名 a")
dw_1.sort()
② 倒序排列
dw_1.setsort("列名 d")
dw_1.sort()
③ 双击排序
string ls_old_sort, ls_column
char lc_sort
if right(dwo.name,2) = '_t' then
ls_column = left(dwo.name, len(string(dwo.name)) - 2)
ls_old_sort = this.describe("datawindow.table.sort")
if ls_column = left(ls_old_sort, len(ls_old_sort) - 2) then
lc_sort = right(ls_old_sort, 1)
if lc_sort = 'a' then
lc_sort = 'd'
lc_sort = 'a'
end if
this.setsort(ls_column + " " + lc_sort)
this.setsort(ls_column + " a")
end if
this.sort()
end if
6.21 数据窗口获取焦点
dw_1.setfocus()
dw_1.setrow("数据行号")
dw_1.setcolumn("字段名")
6.22 数据窗口行相关
① 行处理
dw_1.rowcount() //获取总行
dw_1.getrow() //获取当前行
dw_1.setrow(1) //设置当前行
dw_1.scrolltorow() //滚动到目标行
dw_1.selectrow(1, true) //将第一行变成选中状态
dw_1.isselected(1) //检查第一行是否被选择
② 点击高亮显示
Ⅰ 在数据窗口的click事件中,写入以下代码
if row > 0 then
this.selectrow(0,false)
this.selectrow(row,true)
end if
Ⅱ在数据窗口rowfocuschanged事件中,写入以下代码
if currentrow > 0 then
selectRow(0, false)
selectRow(currentrow, true)
scrolltorow( currentrow )
end if
③ 隔行变色
Ⅰ 打开数据窗口
Ⅱ. 右键 detail
Ⅲ. 找到右侧 color 属性右侧的小图标
Ⅳ. 在表达式中输入以下代码
if ( mod( getrow() , 2) = 1 , rgb(255,255,255) , rgb(235,255,235) )
④ 自增行
Ⅰ. 添加计算列, page n of n
Ⅱ. 选择 getrow()
⑤ 设置每页打印行数
Ⅰ. 添加计算列 page n of n ,输入公式: ceiling(getrow()/20)
Ⅱ. 选择菜单 rows->create group ,创建分组,选择刚才创建的公式列page_1
Ⅲ. 创建完分组后,选择右侧属性, new page on group break 打上勾即可
Ⅳ. 如果需要最后一页不足补空行
long ll_pagerow = 6 //每页打印行数
long ll_count, ll_row
ll_count = dw_1.retrieve()
//取得现有报表的总行数
ll_count = ll_pagerow - mod(ll_count, ll_pagerow)
if ll_count < ll_pagerow then
for ll_row = 1 to ll_count
dw_print.insertrow(0) //补足空行
end if
⑥ 移动行
//移动行
//(primary!主缓冲区 delete!删除缓冲区 filter!过滤缓冲区)
//dw_name.rowsmove(开始行,结束行,缓冲区,要移动到的另一窗口名,在哪一行前面插入,插入哪个缓冲区)
//rowsmove还可以在同一数据窗口的不同缓冲区进行移动行
//如:从删除缓冲区移动行到主缓冲区实现恢复功能:
dw_1.deleterow(1) //删除第1行
dw_1.rowsmove(1,dw_1.deletedcount(),delete!,dw_1,1,primary!) //恢复第1行
⑦ 复制行
//复制行(primary!主缓冲区 delete!删除缓冲区 filter!过滤缓冲区)
//dw_name.rowscopy(开始行,结束行,缓冲区,要复制到的另一窗口名,在哪一行前面插入,插入哪个缓冲区)
//rowscopy( )--基本用法和移动行差不多
dw_1.deleterow(1) //删除第1行
dw_1.rowscopy(1,dw_1.deletedcount(),delete!,dw_1,1,primary!) //复制第1行
6.23 列处理
① 获得数据窗口所有的列名
integer li_index
for li_index = 1 to integer(dw_1.object.datawindow.column.count)
messagebox(string(li_index),dw_1.describe("#" + string(li_index) + ".name"))
② 获得字段对应的dbname
integer li_index
for li_index = 1 to integer(dw_1.object.datawindow.column.count)
messagebox(string(li_index),dw_1.describe("#" + string(li_index) +".dbname"))
③ 复制列
dw_1.object.字段名.primary = dw_1.object.字段名.primary
④ 获取显示列
describe('DataWindow.Table.GridColumns')
6.24 数据窗口中实现复选框
① 在数据窗口的sql中,添加多选框字段
'0' as checkbox
② 设置字段的 edit 属性为 checkbox
,并勾选3d look
③ 设置(data value for on = 1),设置(data value for off = 0)
④ 再dw_1数据窗口的click事件中写
if dwo.name = "checkbox" then
if dw_1.rowcount() = 0 then
if dw_1.object.checkbox[1] = "1" then
for row = 1 to dw_1.rowcount()
dw_1.object.checkbox[row] = "0"
for row = 1 to dw_1.rowcount()
dw_1.object.checkbox[row] = "1"
end if
end if
end if
⑤ 判断是否选中
long i
if dw_1.rowcount() = 0 then return 0
for i = 1 to dw_1.rowcount()
if dw_1.getitiemstring(i, "checkbox") = '1' then
messagebox('提示信息',‘第’+string(i)+'行被选中')
end if
6.25 数据窗口转datastore
datastore lds_data
lds_data = create datastore
//给实例化后的datastore变量关联数据窗口对象
lds_data.dataobject = 'd_data'
//给数据存储对象指定事务对象
lds_data.settransobject(sqlca)
//接下来就和操作普通数据窗口一样了
long ll_row
ll_row = lds_data.insertrow(0)
lds_data.object.name[ll_row] = '张三'
6.26 动态数据窗口
① 数据窗口赋值与取值
//1 赋值
dw.setitem(行, '列名称', 值)
dw.object.列名[行号] = 值
//2 取值
dw_1.object.字段名[行数] //直接取值
dw_1.object.字段名.text //文本框
dw_1.GetItemString(行数,列名) //字符串
dw_1.GetItemNumber(行数,列名) //数值
dw_1.GetItemDate(行数,列名) //日期
dw_1.GetItemDateTime(行数,列名) //日期时间
dw_1.GetItemDecimal(行数,列名) //小数
② 通过describe
获取数据窗口中的各种属性
dw_1.Describe("#1.name") //获取字段名称 title
dw_1.Describe("title.ColType") //获取字段类型 char(100)
dw_1.Describe("title.background.color") // 获取字段背景颜色 536870912
dw_1.Describe("title.background.mode") //获取字段背景模式 1
dw_1.Describe("title.edit.Autohscroll") //获取字段是否允许自动横向滚动 yes
dw_1.Describe("title.key") //获取字段是否为主键 no
dw_1.Describe("title.protect") //获取字段中的数据保护 0
dw_1.Describe("title.SlideLeft") //获取字段的滑动属性(当左面空白时是否向左滑动) no
dw_1.Describe("title.slideup") //获取字段的滑动属性(当上面出现空白时是否向上滑动) no
dw_1.Describe("title.tabsequence") // 获取字段的TabOrder值 15
dw_1.Describe("title.update") //获取字段是否可以修改 yes
dw_1.Describe("title.validation") // 获取字段的校验规则
dw_1.Describe("title.expression") // 获取字段的表达式
dw_1.Describe("Evaluate('LookupDisplay(sex)',1)") // 获取显示值的属性
③ 通过modify
修改数据窗口中的各种属性
dw_1.modify("title.background.mode='1'") // 修改字段背景模式
dw_1.modify("title.background.color = '0'") //修改字段背景颜色
dw_1.modify("title.criteria.dialog = yessex.criteria.override_edit =yes") //修改检索规则
dw_1.modify("title.edit.required = yes") //修改字段为必须输入
dw_1.modify("title.format = 'yyyy-mm-dd'") // 修改字段显示格式为日期格式
dw_1.modify("title.key = yes") // 修改字段为主键
dw_1.modify("title.protect ='1~tif(isrownew(),0,1)'") //修改字段的保护属性
④ 程序运行中动态创建数据窗口
string str_dwsyntax,str_lag
//获得数据窗口1的语法
str_dwsyntax=dw_1.object.datawindow.syntax
//根据数据窗口1的语法动态生成数据窗口2的语法
dw_2.create(str_dwsyntax)
//对数据窗口2的内容作局部修改
str_lag="stu_id_t.font.height='-12' stu_id_t.font.face='楷体_GB2312'"
//字体变12号字体,由宋体改为楷体
dw_2.modify(str_lag)
dw_2.settransobject(sqlca)
dw_2.retrieve()
在程序中使用系统函数LibraryExport()得到某个已经存在的数据窗口对象的源代码
在PB开发环境的库管理画笔(Library Painter)中使用移出功能(右键→Export)将某个数据窗口对象的语法保存到文本文件中
//连接默认事务sqlca
sqlca.dbms = "O84 Oracle8/8i (8.x.4+)"
SQLCA.LogPass = '数据库密码'
SQLCA.ServerName = ‘服务器IP’
SQLCA.LogId = '数据库用户名'
SQLCA.AutoCommit = False
SQLCA.DBParm = "PBCatalogOwner='hb_zh'"
sqlca.autocommit = false
sqlca.dbparm = ""
connect using sqlca;
string dw_sql,dw_style
string dw_syntax,dw_syntax_error,dw_create_error
//设置数据窗口sql
dw_sql = "select * from 表名"
//设置数据窗口风格
dw_style = "style(type=grid)"
//构造sql数据源
dw_syntax = sqlca.syntaxfromsql(dw_sql, dw_style, dw_syntax_error)
//判断sql数据源是否有错误
if len(dw_syntax_error) > 0 then
messagebox("提示", "构造sql数据源错误: " + dw_syntax_error)
return
end if
//通过sql数据源创建dw_1数据窗口
dw_1.create(dw_syntax,dw_create_error)
//判断dw_1数据窗口在创建中是否有错误
if len(dw_create_error) > 0 then
messagebox("提示", "创建数据窗口错误: " + dw_create_error)
return
end if
//检索数据
dw_1.settransobject(sqlca)
dw_1.retrieve()
以上用到的SyntaxFromSQL()
函数和Create()
函数具体说明如下
6.27 数据窗口导入导出
① 数据窗口导入
//dw_1.importfile(导入的文件类型, 文件名, 文件的开始行 , 文件的结束行, 文件的开始列, 文件的结束列, 数据窗口的开始列 )
//因为导出的数据窗口都有标题,所以我们这边从第2行开始导入
dw_1.importfile(text!,'1.txt',2,10,1,10,1) //导入txt文件
dw_1.importfile(excel!,'1.xls',2,10,1,10,1) //导入xls文件
dw_1.importfile(excel!,'1.xlsx',2,10,1,10,1)//导入xlsl文件
dw_1.importfile(csv!,'1.csv',2,10,1,10,1)//导入csv文件
② 数据窗口导出
//dw_name.saveas(名字可含路径,另存为的类型,是否显示列标题)
dw_1.saveas("1.txt",text!,true) //另存为txt文件
dw_1.saveas("1.xls",excel!,true) //另存为xls文件
dw_1.saveas("1.xlsx",excel!,true) //另存为xlsl文件
dw_1.saveas("1.csv",csv!,true) //另存为csv文件
6.28 数据窗口快捷键
//1、新建事件
//事件名 keydown
//event ID pbm_dwnkey(选择这个就可以了,其他参数它会自己设置)
//2、在此事件中,写入以下代码
if key = KeyEnter! then Send(Handle(this),256,9,0)
6.29 设置datawindow的当前行指示图标
//在datawindow中建立一个计算列,expression为'',并将该计算列移动为datawindow的第一个列,在
//datawindow控件的rowfocuschanged事件中写入代码:
SetRowFocusIndicator(hand!) //小手指样式
setrowfucsindicator(p_1) //自定义图片样式
6.30 打印datawindow的内容到文件中
//数据窗口打印出pdf
dw_1.object.datawindow.print.filename ="c:/temp.pdf"
dw_1.print()
6.31 将Grid风格改成自由格式
在DW的editsource中将processing=1的1改为0
6.32 数据窗口自动调整大小
在数据窗所在窗口的Resize事件下编写代码
Resize(dw_datamon,this.Workspacewidth()-50,this.Workspaceheight()-50)
6.33 一个报表中要有一个计算域,是几个NUM型列相加,加的时候几个列中有一为空就加不出来
设置此数据列的初使值为0.0。但必需在数据窗口对象中设,即选菜单Rows中的Column Specifications……选项,在Initial Value列中写上0.0即可
计算列公式采用如下:
// A + B + C
if(isnull(A), 0,A) + if(isnull(B), 0,B) + if(isnull(C), 0,C)
6.34 动态生成的报表中怎么修改各个带区的宽度、位置?
// 改变detail区的高度:
dw_1.Modify("DataWindow.detail.Height=200")
6.35 动态生成的报表中增加文本(标题),或对标题栏的文本进行修改
//对标题栏文本的更改(文本名为dept_name_t)
dw_1.modify("dept_name_t.text = '单位名称'")
6.36 动态生成的报表中动态增加计算列
string ls_modrow
dw_1.Modify("DataWindow.summary.Height=64")
ls_modrow = 'Create compute(band=summary font.charset="0" font.face="MS Sans Serif" font.family="2" font.height="-8" font.pitch="2" font.weight="400" background.mode="1" background.color="536870912" color="0" x="9" y="4" height="52" width="297" format="[general]" expression="count(dept_id for all)" alignment="1" border="0" crosstab.repeat=no )~r~n'
dw_1.modify( ls_modrow )
6.37 动态修改grid数据窗口中网格线是否可见,并在detail区增加加一条线
dw_1.Modify("DataWindow.Grid.Lines='1' ")
dw_1.Modify("DataWindow.detail.Height=332")
ls_line = 'Create line(band=detail background.mode="2" background.color="16777215" pen.style="0" pen.width="5" pen.color="0" x1="37" y1="320" x2="1458" y2="316" )~r~n'
dw_1.modify( ls_line )
6.38数据窗口中添加一计算域,统计一下性别为男的记录数
//添加一个计算列
sum( if( stu_sex ='男', 1, 0 ))
6.39 数据窗口中数据自动折行
在PowerBuilder应用程序的开发过程中, 使用DataWindow时, 经常会遇到某列的数据太长, 不能同时全部显示的情况. 若采用自动水平滚动, 操作起来又不够简便,那么我们将如何实现列数据多行显示, 即实现列数据的自动折行呢?
① 在DataWindow Painter中打开此DataWindow对象
②在需设定自动折行的列上双击鼠标, 弹开此列的属性窗口
③ 选择Position标签, 选中Autosize Height 多选框
④ 选择Edit标签, 不选中Auto Horz Scroll多选框
⑤ 单击OK按钮, 保存所做的修改
⑥ 点中Detail Band (即写有Detail的灰色长带), 单击鼠标右键, 选择Properties... 菜单项
⑦ 选中Autosize Height多选框
⑧ 单击OK按钮, 保存所做的修改
⑨ 保存此DataWindow
注意:连在一起的汉字(中间没有标点或空格分隔), 系统将认为是一个单词, 不会自动进行折行, 英文也是如此……DW窗口折行如果有汉字的话就必需中间加空格才会折行,否则怎样设置都不行。例如你如果想在第20位折行,就先判断第20位是否是个汉字,如不是就在第20位后加空格,如果是汉字就在第19位加空格。判断是否是汉字可以用它的ASCII码是否大于127来判断
6.40 连续页数打印多个数据窗
① 建立一个全局变量
integer g_int_page=0
② 建立一个全局函数f_setpage()
return g_int_page
③ 在数据窗口对象中加入一计算域gs_pagenum
//利用全局涵数来传递全局变量
page() + f_setpage()
④ 在每一个数据窗口控件的printend事件中改变全局变量的值,以使计算域的值发生变化
g_int_page=dw_1.getitemnumber(dw_1.rowcount(),"gs_pagenum")
⑤ 当所有窗口打印完毕后将全局变量恢复
g_int_page=0
6.41 动态实现打印不固定的数据列
做一个程序,其中的一个功能是:
例如:数据库。雇员(序号,姓名,年龄,性别,出生年月,学历,职务,工资,等等)。
客户要求在程序的运行中进行选择(对表的项任意选),然后打印出来。
如选择姓名,年龄,出生。则打印姓名,年龄,出生。
又如选择姓名,工资。则打印姓名,工资。我不知道如何去实现
建数据窗口对象时,选用Grid风格(Grid风格数据窗口的字段宽度可以随意拖动,如同Excel),不需要打印的字段可以随时将其宽度拖动为零
用列表框显示出所有的列,可以多选高亮列。通过Modify函数动态定义选中列的位置,宽度以及是否可见等属性
本文来自博客园,作者:程序员晓凡,转载请注明原文链接:https://www.cnblogs.com/xiezhr/p/17539440.html