Pb从入坑到放弃(三)数据窗口

打印 上一主题 下一主题

主题 916|帖子 916|积分 2750

写在前面

数据窗口是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:是否显示网格。
-- 未选中-- 选中后③Show Ruler:显示标尺。
-- 未选中-- 选中④  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.2.2 翻页

-- 呼出菜单--呼出菜单

  • first page(翻到第一页)
  • prior page(前一页)
  • next page(下一页)
  • last page(最后一页)
1.2.3 增加、删除数据

在数据窗口中增加或者删除数据,得首先设置数据窗口相应的属性,
允许修改的字段Tab Order 值不能为 0
----1.3 Control List 视窗

Control List 是数据窗口中所有的部件构成的一个列表

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 数据源

快捷数据源,是经常使用的一种数据源,可以快速地创建数据窗口  。
使用这种数据源,只能从一个数据表或者视图中选取数据
需要从多个数据表中选取数据而且还想使用这种数据源时,只能创建对应的视图
----2.2  SQL Select 数据源

选择这种数据源时,SQL语句设计是图形化的,也可以手工输入SQL语句
-- ①选择数据源--②选择表--③ 选择字段-- SQL语法和图形化切换-- ④ 定义检索条件2.3  Query 数据源

PB可以将特定的 SQL 语句保存为 Query 对象, 不同的 Query 数据源的数据窗口都可以使用这些已经保存
Query对象来作为数据源,增强了 SQL 语句的重用性
--① 新建Query数据源对象--② 使用Query 数据源2.4 External 数据源

是一种比较特殊的数据源,可以弥补其他四种数据源的不足
当和不存在于数据库中的数据打交道或者要利用数据窗口的某些特性但不进行数据处理时,这两种情况下都可以使用 External 数据源的数据窗口
--① 指定数据源-- ② 设置数据类型及长度2.5 Stored Procedure(存储过程)

可以直接使用数据库中已经创建好的存储过程作为数据源
SQL 语句无需网上传送,可以减少网络通信量及网上传输 SQL 语句的时间, 所以执行效率比其他数据源的数据窗口要高
-- ① 选择数据源--② 选择数据库中创建好的存储过程2.6 Web Service 数据源

这是PB 11.5 以后新加的数据源
--① 选择Web Service 数据源--②输入WebService的WSDL文件的地址--③ 选择WebService接口--④ 选择WebService 接口方法三、数据窗口显示样式

3.1 Grid 显示样式

数据窗口布局整齐,但不能灵活地安排字段、标签、表头的布局
字段横向排列在 detail band 中,标签横向排列在 header band 中,和字段相对应,字段和字段之
间有网格线分隔,类似于电子表格  。
如下图所示

3.2 Tabular 显示样式

字段、标签的布局和 Grid 显示样式的数据窗口相同,都是横向排列的,但是字段之间没有网格线分隔。
字段和标签的布局可以随意调整,在 header band 中的标签可以随意拖放到 detail band 中,
detail band 中的字段也可以拖放到 header band 中

3.3 Group 显示样式

数据窗口可以指定按那个(或那些)字段进行分组,可以用指定的分组条件将数据分组显示,并且允许为每组指定一些计算。
例如:要显示各部门员工的薪资数据,可以按部门分组
-- ①按部门分组-- ②分组后数据3.4 Freedom 显示样式

这种显示样式的数据窗口布局也很灵活,可以随意安排字段和标签的位置
-- ① 选择Freeform-- ②录入表单信息3.5 Label 显示样式

如果用户想要生成邮件标签,可以使用 Label 显示样式的数据窗口来实现
在向导的指引下,可以设定标签的一些参数。
可以指定标签的大小,包括三方面的设定: Label 本身的大小、Label 之间的边框、 Label 的布局顺序。
在 Label 组框中,参数“ Across”指横向显示的标签数目, “ Down”表示一页中竖向显示的标签数目
----
3.6 N-up 显示样式

可以在同一页上显示多列相同字段的一种特殊的显示样式 .
可以设置每行重复显示字段的次数 ,默认是2
这里我们每行显示2列员工编号和员工姓名
-- ① 选择N-up样式-- ②设置每行显示列数
3.7 CrossTab 显示样式

通过CrossTab 显示样式我们可以制作出下图所示的交叉报表
--① 选择CrossTab 显示样式--② 设置行分类、列分类最终显示效果

3.8 Graph 显示样式

Graph 显示样式  可以显示饼图、柱状图、折线图等
Graph 显示样式的数据窗口时,三个主要参数是

  • Category  显示在横向坐标轴上的字段
  • Values    显示在纵向坐标轴上的字段
  • Series   横向坐标轴上同组比较时的分组标准
-- ① 选择Graph 样式-- ② 选择横向、纵向坐标--③ 选择图表样式及设置标题我们这里选择柱状图显示,一共又17种样式可以选择,感兴趣的小伙伴可以都试试

3.9  Composite 显示样式

这种样式的数据窗口可以将多种类型的、多个逻辑上毫不相关的数据窗口放置到一起,是一种比较灵活的
我们把前面制作好的柱状图和表格放到一起
-- ① 选择Composite 显示样式-- ② 选择要展示的报表最终显示效果

3.10  RichText 显示样式

这种样式的数据窗口使数据库中的数据和文字可以在一起排版,可以方便地将数据库中的数据和文字内容一起形成文
档、报告 。
-- ① 选择RichText 显示样式-- ② 选择文字处理工具最终显示效果

3.11 OLE 2.0 显示样式

OLE  对象链接和嵌入 。使用它可以将其他软件的功能引入到 PB开发的应用程序中
使用这种显示样式的数据窗口,可以借鉴其他软件的强大功能,弥补 PB在某些专业性较强领域中的不足或空白
-- ① 选择OLE 样式-- ② 设置分组
3.12 TreeView 显示样式

该样式可以按照树形结构显示数据,我们以emp和dept表为例,以dept_name 字段进行分组
-- ① 选择TreeView 样式-- ② 选择dept_name分组最终效果

四、数据窗口对象介绍

数据窗口用带( Band)将其分隔成四部分 ,一个标准的报表一般由题头、数据、页脚、总计四部分构成,分别对应数据窗口的 Header, Detail,
Summary 和 Footer 四部分

带描述Header出现在每页的顶端,用于显示标题和列的题头。
放置表头、报表日期等一些能够方便查阅的内容, 即使这部分字段的 Tab Order 值不为 0、 DisplayOnly 属性为 False 也不允许用户编辑,并且也只能显示多条记录中的一条Detail包含了数据窗口对象的主体,显示了各行的数据和相关的标签。
放置数据、表格,程序运行时,数据窗口自动处理该区域,根据数据库中的数据显示一条或者多条数据Summary出现在每页的底端,用来显示文本和页号
放置页内小计、页号等页脚方面的内容Footer出现在 DataWindow 对象的最后一页,用来为整个数据窗口对象显示总计和总和
放置总计、制表人等需要在表格最后放置的内容五、数据窗口常用函数

函数参数说明dw_1.insertrow(row)row 设置插入位置
成功时返回插入成功的行号,失败返回-1
insertrow(0) 表示在最后一行插入一行插入空行dw_1.deleterow(row)row 要删除的行号
成功时返回1,失败时返回-1
deleterow(0) 代表删除当前行删除行dw_1.retrieve()dw_1.retrieve(参数1,参数2,参数3...)检索数据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 将编辑的数据放到主缓冲区
  1. dw_1.accepttext()
复制代码
6.1.2 增加一行数据
  1. dw_1.insertrow(0)
复制代码
6.1.3 删除一行数据
  1. dw_1.deleterow(row)
复制代码
6.1.4 更新数据
  1. dw_1.update()
复制代码

  • 在使用update() 函数将修改的数据保存到数据库中时,必须要设置数据窗口的修改属性。
  • 数据窗口只能修改一个数据表
  • 当增加、删除或者重新选择了字段时, PB将数据窗口的修改属性置为不允许,这时也应该进行手工设置
单项 Rows→Update Properties  进行修改属性的设置


  • Allow Updates : 选中该选项,才允许继续进行其他属性的设定
  • Table to Update  :要被更新的表
  • Where Clause for Update/Delete
选项说明Key Columns单用户应用程序或者用户都以加锁方式访问数据库时可以选中该选项  
只使用在“ Unique Key Column(s)”列表框中指定的惟一列进行数据更新Key and Updateable Columns  默认的修改方式  
用主键列和可以修改的列来创建 where 子句Key and Modified
Columns  上面两种方法的折中  
用主键和数据发生了变化的列来产生 where 子句

  • Key Modification
选项说明Use Delete then Insert   先删除原有主键值,然后再使用新的主键值插入一个完整的行Use Update  通过Update语句修改数据

  • Updatable Columns : 需要修改的列
  • Unique Key Column(s) : 唯一能够确定一行的列
6.1.5 查找数据
  1. dw_1.settransobject(sqlca)
  2. dw_1.retrieve()
复制代码
6.2 数据窗口更新多个表

思路: 动态修改数据窗口的Update属性
举个栗子: dw_1数据窗口中包含两张表的字段,emp(员工信息表),dept(部门表)
  1. select dept.deptno,dept.dname,
  2. emp.empno,emp.ename
  3. from emp,dept
  4. where emp.deptno = dept.deptno
复制代码
在创建数据窗口时设置为 dept 表可修改
  1. Int li_update
  2. li_update = dw_1.Update(True,False) //接受最后一个字段内容,并且不清除行修改标志
  3. // 如果对 Department 表的修改成功,下一步就要修改另一个表 Employee
  4. If li_update = 1 Then
  5.     //首先,关掉对 dept 表的修改
  6.     dw_1.ModIfy('dept_dname.Update = "No"')
  7.     dw_1.ModIfy('dept_deptno.Update = "No"')
  8.     dw_1.ModIfy('dept_deptno.Key = "No"')
  9.     //使 emp 表成为新的可修改表
  10.     dw_1.dwModIfy('DataWindow.Table.UpdateTable = ~'emp~' ')
  11.     dw_1.ModIfy('emp_empno.Update = "Yes"')
  12.     dw_1.ModIfy('emp_ename.Update = "Yes"')
  13.     dw_1.ModIfy('emp_empno.Key = 'Yes' ' )
  14.     //然后修改 Employee 表
  15.     li_update = dw_1.Update()
  16.     If li_update = 1 Then
  17.     Commit Using SQLCA;
  18. Else
  19.     MessageBox("修改错误! ", "数据修改错误,错误代码"&
  20.     + String(SQLCA.SqlDBCode) + "~r~n 错误原因: "+ SQLCA.SqlErrText)
  21.     Rollback Using SQLCA;
  22.     End If
  23.     //恢复数据窗口开始时的属性,以便下一次用户单击“保存”按钮时
  24.     //程序能够正确执行
  25.     dw_1.ModIfy('dept_dname.Update = "Yes"')
  26.     dw_1.ModIfy('dept_deptno.Update = "Yes"')
  27.     dw_1.ModIfy('dept_deptno.Key = "Yes"')
  28.     dw_1.ModIfy('DataWindow.Table.UpdateTable = ~'dept~' ')
  29.     dw_1.ModIfy('emp_empno.Update = "No" ')
  30.     dw_1.ModIfy('emp_ename.Update = "No" ')
  31.     dw_1.ModIfy('emp_empno.Key = "No" ')
  32. Else
  33.     MessageBox('部门表更新失败,回滚更改为部门')
  34.     Rollback Using SQLCA;
  35. End If
复制代码
6.3  设置字段只读

① 方法一
将tab order 设置为0
② 方法二
  1. dw_1.modify("cname.tabsequence = 0 ")  
复制代码
③ 方法三
  1. dw_1.modify( "meno.edit.displayonly=yes")
复制代码
④ 方法四
  1. dw_1.modify("code_course.protect= 1")
复制代码
6.4 切换数据窗口数据源
  1. dw_1.dataobject = "数据窗口名"
复制代码
6.5 隐藏数据窗口刷新过程
  1. dw_1.setredraw(false) //不刷新
  2. dw_1.setredraw(true) //刷新
复制代码
6.6 数据窗口共享数据
  1. dw_2.sharedata(dw_1)
复制代码
6.7 数据窗口SQL中传递 in 的参数
  1. select emp.empno,emp.ename,emp.job,emp.mgr,emp.hiredate,emp.sal,emp.comm  from emp where emp.empno in (传入的参数)
复制代码
  1. //在传给数据窗口时,in中的内容必须是数组类型
  2. string[] arr_in
  3. arr_in[1]='7369'
  4. arr_in[2]='7499'
  5. arr_in[3]='7521'
  6. dw_1.retrieve(ls_in)
复制代码
6.8 获取当前数据窗口的sql
  1. dw_1.getsqlselect()
复制代码
6.9 设置当前数据窗口的sql
  1. dw_1.setsqlselect(sql)
复制代码
6.10 调用子数据窗口
  1. integer rtncode
  2. datawindowchild dwc_child
  3. rtncode = dw_1.getchild("主窗口字段", dwc_child)
  4. if rtncode = 1 then
  5.         messagebox('',dwc_child.getitemstring(1,'子窗口字段'))
  6. else
  7.         messagebox('提示','未获取到子数据窗口!')
  8. end if
复制代码
6.11 判断数据窗口是否被修改
  1. //判断数据窗口是否修改,建议写在closequery事件中
  2. if dw_1.modifiedcount() + dw_1.deletedcount() > 0 then
  3.         messagebox('提示','数据窗口已经修改,是否保存?')
  4. else
  5.         messagebox('提示','数据窗口没有修改,正常退出')
  6. end if
复制代码
6.12 数据窗口重置
  1. dw_1.reset()
复制代码
6.13 数据窗口重新分组
  1. //重新分组,在我们处理过滤和排序后,如果是分组窗口可能会破坏分组规则
  2. //所以我们要进行重新分组,重新分组一般都是在filter()或sort()后面
  3. dw_1.groupcalc()
复制代码
6.14 获得数据窗口的状态
  1. //(可选状态:datamodified! new! newmodified! notmodified!)
  2. //当第一次使用retrieve()函数从数据库中读取数据时,所有在数据窗口缓冲区的记录与字段都是属于
  3. NotModified!状态。
  4. //当时数据被修改过后,被修改过的记录状态标志与字段状态标志都会被改成DataModified!
  5. //当增加一笔数据时,增加数据的字段状态标志为NotModified!,记录状态标志为New!.
  6. //当我们在增加的字段中填上数据后,字段状态标志为DataModified!记录状态标志为NewModified!
  7. if dw_1.getitemStatus(1,dw_1.deletedcount(),primary!) = datamodified! then
  8.         messagebox('1:已修改数据','datamodified!')
  9. elseif dw_1.getitemStatus(1,dw_1.deletedcount(),primary!) = new! then
  10.         messagebox('2:已增加数据','new!')
  11. elseif dw_1.getitemStatus(1,dw_1.deletedcount(),primary!) = newmodified! then
  12.         messagebox('3:已填写数据','newmodified!')
  13. elseif dw_1.getitemStatus(1,dw_1.deletedcount(),primary!) = notmodified! then
  14.         messagebox('4:未修改数据','notmodified!')
  15. end if
复制代码
6.15 设置数据窗口状态
  1. //(可选状态:datamodified! new! newmodified! notmodified!)
  2. dw_1.setitemstatus(1,dw_1.deletedcount(),primary!,notmodified!)
复制代码
6.16 查找数据窗口中第一个被选中的行
  1. dw_1.getselectedrow(0)
复制代码
6.17 数据窗口查找(find)
  1. //dw_1.find(查找条件表达式,开始行, 结束行), 如果表达式成立,那么就返回符合条件的行号
  2. dw_1.find('id=8',1,10)
复制代码
6.18  数据窗口过滤

① 列名过滤
  1. dw_1.setfilter("isnull(列名)")
  2. dw_1.filter()
复制代码
②条件过滤
  1. dw_1.setfilter("列名='" + 列值 + "'")
  2. dw_1.filter()
复制代码
③ 清除过滤
  1. //方法一
  2. dw_1.setfilter('')
  3. dw_1.filter()
  4. //方法二
  5. dw_1.setfilter('1=1')
复制代码
④ sql语句过滤
  1. sql = 'select * from 表名 where isnull(字段名 , ''空'') = ''空'' ' ;
复制代码
6.19 数据窗口分页

增加一个计算列
计算列必须放在detail段
expression中输入:ceiling(getrow()/20)  这里表示每页20条数据
这里20还可以用全局函数取代,这样可以允许用户任意设置每页多少行。
定义分组,选择菜单rows->create group...
按计算列字段分组,并一定将check box-->new page on group break选中
将此计算列设为不可视
然后添加以下按钮,完成分页功能
①首页
  1. dw_1.scrolltorow(0)
  2. dw_1.setrow(0)
复制代码
② 上一页
  1. dw_1.scrollpriorpage()
复制代码
③ 下一页
  1. dw_1.scrollnextpage()
复制代码
④ 最后一页
  1. dw_1.scrolltorow(dw_1.rowcount())
  2. dw_1.setrow(dw_1.rowcount())
复制代码
6.20 数据窗口排序

① 正序排列
  1. dw_1.setsort("列名 a")
  2. dw_1.sort()
复制代码
② 倒序排列
  1. dw_1.setsort("列名 d")
  2. dw_1.sort()
复制代码
③ 双击排序
  1. string ls_old_sort, ls_column
  2. char lc_sort
  3. if right(dwo.name,2) = '_t' then
  4.     ls_column = left(dwo.name, len(string(dwo.name)) - 2)
  5.     ls_old_sort = this.describe("datawindow.table.sort")
  6.     if ls_column = left(ls_old_sort, len(ls_old_sort) - 2) then
  7.             lc_sort = right(ls_old_sort, 1)
  8.         if lc_sort = 'a' then
  9.             lc_sort = 'd'
  10.         else
  11.             lc_sort = 'a'
  12.         end if
  13.                 this.setsort(ls_column + " " + lc_sort)
  14.         else
  15.                 this.setsort(ls_column + " a")
  16.         end if
  17.         this.sort()
  18. end if
复制代码
6.21 数据窗口获取焦点
  1. dw_1.setfocus()
  2. dw_1.setrow("数据行号")
  3. dw_1.setcolumn("字段名")
复制代码
6.22 数据窗口行相关

① 行处理
  1. dw_1.rowcount() //获取总行
  2. dw_1.getrow() //获取当前行
  3. dw_1.setrow(1) //设置当前行
  4. dw_1.scrolltorow() //滚动到目标行
  5. dw_1.selectrow(1, true) //将第一行变成选中状态
  6. dw_1.isselected(1) //检查第一行是否被选择
复制代码
② 点击高亮显示
Ⅰ 在数据窗口的click事件中,写入以下代码
  1. if row > 0 then
  2.     this.selectrow(0,false)
  3.     this.selectrow(row,true)
  4. end if
复制代码
Ⅱ在数据窗口rowfocuschanged事件中,写入以下代码
  1. if currentrow > 0 then
  2.     selectRow(0, false)
  3.     selectRow(currentrow, true)
  4.     scrolltorow( currentrow )
  5. end if
复制代码
③ 隔行变色
Ⅰ 打开数据窗口
Ⅱ. 右键 detail
Ⅲ. 找到右侧 color 属性右侧的小图标
Ⅳ. 在表达式中输入以下代码
  1. 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 打上勾即可
Ⅳ. 如果需要最后一页不足补空行
  1. long ll_pagerow = 6 //每页打印行数
  2. long ll_count, ll_row
  3. ll_count = dw_1.retrieve()
  4. //取得现有报表的总行数
  5. ll_count = ll_pagerow - mod(ll_count, ll_pagerow)
  6. if ll_count < ll_pagerow then
  7.     for ll_row = 1 to ll_count
  8.         dw_print.insertrow(0) //补足空行
  9.     next
  10. end if
复制代码
⑥ 移动行
  1. //移动行
  2. //(primary!主缓冲区 delete!删除缓冲区 filter!过滤缓冲区)
  3. //dw_name.rowsmove(开始行,结束行,缓冲区,要移动到的另一窗口名,在哪一行前面插入,插入哪个缓冲区)
  4. //rowsmove还可以在同一数据窗口的不同缓冲区进行移动行
  5. //如:从删除缓冲区移动行到主缓冲区实现恢复功能:
  6. dw_1.deleterow(1) //删除第1行
  7. dw_1.rowsmove(1,dw_1.deletedcount(),delete!,dw_1,1,primary!) //恢复第1行
复制代码
⑦ 复制行
  1. //复制行(primary!主缓冲区 delete!删除缓冲区 filter!过滤缓冲区)
  2. //dw_name.rowscopy(开始行,结束行,缓冲区,要复制到的另一窗口名,在哪一行前面插入,插入哪个缓冲区)
  3. //rowscopy( )--基本用法和移动行差不多
  4. dw_1.deleterow(1) //删除第1行
  5. dw_1.rowscopy(1,dw_1.deletedcount(),delete!,dw_1,1,primary!) //复制第1行
复制代码
6.23 列处理

① 获得数据窗口所有的列名
  1. integer li_index
  2. for li_index = 1 to integer(dw_1.object.datawindow.column.count)
  3.         messagebox(string(li_index),dw_1.describe("#" + string(li_index) + ".name"))
  4. next
复制代码
② 获得字段对应的dbname
  1. integer li_index
  2. for li_index = 1 to integer(dw_1.object.datawindow.column.count)
  3.         messagebox(string(li_index),dw_1.describe("#" + string(li_index) +".dbname"))
  4. next
复制代码
③ 复制列
  1. dw_1.object.字段名.primary = dw_1.object.字段名.primary
复制代码
④ 获取显示列
  1. describe('DataWindow.Table.GridColumns')
复制代码
6.24 数据窗口中实现复选框

① 在数据窗口的sql中,添加多选框字段
  1. '0' as checkbox
复制代码
② 设置字段的 edit 属性为 checkbox ,并勾选3d look  
③ 设置(data value for on = 1),设置(data value for off = 0)
④ 再dw_1数据窗口的click事件中写
  1. if dwo.name = "checkbox" then
  2.         if dw_1.rowcount() = 0 then
  3.         else
  4.         if dw_1.object.checkbox[1] = "1" then
  5.             for row = 1 to dw_1.rowcount()
  6.                 dw_1.object.checkbox[row] = "0"
  7.             next
  8.         else
  9.             for row = 1 to dw_1.rowcount()
  10.                 dw_1.object.checkbox[row] = "1"
  11.             next
  12.                 end if
  13.         end if
  14. end if
复制代码
⑤ 判断是否选中
  1. long i
  2. if dw_1.rowcount() = 0 then return 0
  3. for i = 1 to dw_1.rowcount()
  4.     if dw_1.getitiemstring(i, "checkbox") = '1' then
  5.         messagebox('提示信息',‘第’+string(i)+'行被选中')
  6.     end if
  7. next
复制代码
6.25 数据窗口转datastore
  1. datastore lds_data
  2. lds_data = create datastore
  3. //给实例化后的datastore变量关联数据窗口对象
  4. lds_data.dataobject = 'd_data'
  5. //给数据存储对象指定事务对象
  6. lds_data.settransobject(sqlca)
  7.    
  8. //接下来就和操作普通数据窗口一样了
  9. long ll_row
  10. ll_row = lds_data.insertrow(0)
  11. lds_data.object.name[ll_row] = '张三'
复制代码
6.26 动态数据窗口

① 数据窗口赋值与取值
  1. //1 赋值
  2. dw.setitem(行, '列名称', 值)
  3. dw.object.列名[行号] = 值
  4.    
  5. //2 取值
  6. dw_1.object.字段名[行数] //直接取值
  7. dw_1.object.字段名.text //文本框
  8. dw_1.GetItemString(行数,列名) //字符串
  9. dw_1.GetItemNumber(行数,列名) //数值
  10. dw_1.GetItemDate(行数,列名) //日期
  11. dw_1.GetItemDateTime(行数,列名) //日期时间
  12. dw_1.GetItemDecimal(行数,列名) //小数
复制代码
② 通过describe  获取数据窗口中的各种属性
  1. dw_1.Describe("#1.name")  //获取字段名称  title
  2. dw_1.Describe("title.ColType")  //获取字段类型  char(100)
  3. dw_1.Describe("title.background.color") // 获取字段背景颜色 536870912
  4. dw_1.Describe("title.background.mode") //获取字段背景模式 1
  5. dw_1.Describe("title.edit.Autohscroll") //获取字段是否允许自动横向滚动 yes
  6. dw_1.Describe("title.key")  //获取字段是否为主键 no
  7. dw_1.Describe("title.protect") //获取字段中的数据保护 0
  8. dw_1.Describe("title.SlideLeft") //获取字段的滑动属性(当左面空白时是否向左滑动)  no
  9. dw_1.Describe("title.slideup") //获取字段的滑动属性(当上面出现空白时是否向上滑动) no
  10. dw_1.Describe("title.tabsequence") // 获取字段的TabOrder值    15
  11. dw_1.Describe("title.update")  //获取字段是否可以修改 yes
  12. dw_1.Describe("title.validation") // 获取字段的校验规则
  13. dw_1.Describe("title.expression") // 获取字段的表达式
  14. dw_1.Describe("Evaluate('LookupDisplay(sex)',1)")  // 获取显示值的属性
  15.    
复制代码
③ 通过modify 修改数据窗口中的各种属性
  1. dw_1.modify("title.background.mode='1'")  // 修改字段背景模式
  2. dw_1.modify("title.background.color = '0'") //修改字段背景颜色
  3. dw_1.modify("title.criteria.dialog = yessex.criteria.override_edit =yes")  //修改检索规则
  4. dw_1.modify("title.edit.required = yes") //修改字段为必须输入
  5. dw_1.modify("title.format = 'yyyy-mm-dd'")  // 修改字段显示格式为日期格式
  6. dw_1.modify("title.key = yes") // 修改字段为主键
  7. dw_1.modify("title.protect ='1~tif(isrownew(),0,1)'")  //修改字段的保护属性
复制代码
④ 程序运行中动态创建数据窗口
方法Ⅰ
  1. string str_dwsyntax,str_lag
  2. //获得数据窗口1的语法
  3. str_dwsyntax=dw_1.object.datawindow.syntax
  4. //根据数据窗口1的语法动态生成数据窗口2的语法
  5. dw_2.create(str_dwsyntax)
  6. //对数据窗口2的内容作局部修改
  7. str_lag="stu_id_t.font.height='-12' stu_id_t.font.face='楷体_GB2312'"
  8. //字体变12号字体,由宋体改为楷体
  9. dw_2.modify(str_lag)
  10. dw_2.settransobject(sqlca)
  11. dw_2.retrieve()
复制代码
方法Ⅱ
在程序中使用系统函数LibraryExport()得到某个已经存在的数据窗口对象的源代码
方法Ⅲ
在PB开发环境的库管理画笔(Library Painter)中使用移出功能(右键→Export)将某个数据窗口对象的语法保存到文本文件中
方法Ⅳ
  1. //连接默认事务sqlcasqlca.dbms = "O84 Oracle8/8i (8.x.4+)"SQLCA.LogPass = '数据库密码'SQLCA.ServerName = ‘服务器IP’SQLCA.LogId = '数据库用户名'SQLCA.AutoCommit = FalseSQLCA.DBParm = "PBCatalogOwner='hb_zh'"sqlca.autocommit = falsesqlca.dbparm = ""connect using sqlca;string dw_sql,dw_stylestring dw_syntax,dw_syntax_error,dw_create_error//设置数据窗口sqldw_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)        returnend 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)        returnend if//检索数据dw_1.settransobject(sqlca)
  2. dw_1.retrieve()
复制代码
以上用到的SyntaxFromSQL()函数和Create() 函数具体说明如下


6.27 数据窗口导入导出

① 数据窗口导入
  1. //dw_1.importfile(导入的文件类型, 文件名, 文件的开始行 , 文件的结束行, 文件的开始列, 文件的结束列, 数据窗口的开始列 )
  2. //因为导出的数据窗口都有标题,所以我们这边从第2行开始导入
  3. dw_1.importfile(text!,'1.txt',2,10,1,10,1) //导入txt文件
  4. dw_1.importfile(excel!,'1.xls',2,10,1,10,1) //导入xls文件
  5. dw_1.importfile(excel!,'1.xlsx',2,10,1,10,1)//导入xlsl文件
  6. dw_1.importfile(csv!,'1.csv',2,10,1,10,1)//导入csv文件
复制代码
② 数据窗口导出
  1. //dw_name.saveas(名字可含路径,另存为的类型,是否显示列标题)
  2. dw_1.saveas("1.txt",text!,true) //另存为txt文件
  3. dw_1.saveas("1.xls",excel!,true) //另存为xls文件
  4. dw_1.saveas("1.xlsx",excel!,true) //另存为xlsl文件
  5. dw_1.saveas("1.csv",csv!,true) //另存为csv文件
复制代码
6.28 数据窗口快捷键
  1. //1、新建事件
  2. //事件名 keydown
  3. //event ID pbm_dwnkey(选择这个就可以了,其他参数它会自己设置)
  4. //2、在此事件中,写入以下代码
  5. if key = KeyEnter! then Send(Handle(this),256,9,0)
复制代码
6.29 设置datawindow的当前行指示图标
  1. //在datawindow中建立一个计算列,expression为'',并将该计算列移动为datawindow的第一个列,在
  2. //datawindow控件的rowfocuschanged事件中写入代码:
  3. SetRowFocusIndicator(hand!) //小手指样式
  4. setrowfucsindicator(p_1) //自定义图片样式
复制代码
6.30 打印datawindow的内容到文件中
  1. //数据窗口打印出pdf
  2. dw_1.object.datawindow.print.filename ="c:/temp.pdf"
  3. dw_1.print()
复制代码
6.31 将Grid风格改成自由格式
  1. 在DW的editsource中将processing=1的1改为0
复制代码
6.32 数据窗口自动调整大小

在数据窗所在窗口的Resize事件下编写代码
  1. Resize(dw_datamon,this.Workspacewidth()-50,this.Workspaceheight()-50)
复制代码
6.33 一个报表中要有一个计算域,是几个NUM型列相加,加的时候几个列中有一为空就加不出来

方法Ⅰ
设置此数据列的初使值为0.0。但必需在数据窗口对象中设,即选菜单Rows中的Column Specifications……选项,在Initial  Value列中写上0.0即可
方法Ⅱ
计算列公式采用如下:
  1. // A + B + C
  2. if(isnull(A), 0,A) + if(isnull(B), 0,B) + if(isnull(C), 0,C)  
复制代码
6.34 动态生成的报表中怎么修改各个带区的宽度、位置?
  1. // 改变detail区的高度:
  2. dw_1.Modify("DataWindow.detail.Height=200")
复制代码
6.35 动态生成的报表中增加文本(标题),或对标题栏的文本进行修改
  1. //对标题栏文本的更改(文本名为dept_name_t)
  2. dw_1.modify("dept_name_t.text = '单位名称'")
复制代码
6.36   动态生成的报表中动态增加计算列
  1. string ls_modrow
  2. dw_1.Modify("DataWindow.summary.Height=64")
  3. 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'
  4. dw_1.modify( ls_modrow )
复制代码
6.37 动态修改grid数据窗口中网格线是否可见,并在detail区增加加一条线
  1. dw_1.Modify("DataWindow.Grid.Lines='1' ")
  2. dw_1.Modify("DataWindow.detail.Height=332")
  3. ls_line = 'Create line(band=detail background.mode="2" background.color="16777215" pen. pen.width="5" pen.color="0" x1="37" y1="320" x2="1458" y2="316" )~r~n'
  4. dw_1.modify( ls_line )
复制代码
6.38数据窗口中添加一计算域,统计一下性别为男的记录数
  1. //添加一个计算列
  2. 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 连续页数打印多个数据窗

① 建立一个全局变量
  1. integer g_int_page=0
复制代码
② 建立一个全局函数f_setpage()
  1. return g_int_page
复制代码
③ 在数据窗口对象中加入一计算域gs_pagenum
  1. //利用全局涵数来传递全局变量
  2. page() + f_setpage()
复制代码
④ 在每一个数据窗口控件的printend事件中改变全局变量的值,以使计算域的值发生变化
  1. g_int_page=dw_1.getitemnumber(dw_1.rowcount(),"gs_pagenum")
复制代码
⑤ 当所有窗口打印完毕后将全局变量恢复
  1. g_int_page=0
复制代码
6.41 动态实现打印不固定的数据列

做一个程序,其中的一个功能是:
例如:数据库。雇员(序号,姓名,年龄,性别,出生年月,学历,职务,工资,等等)。
客户要求在程序的运行中进行选择(对表的项任意选),然后打印出来。
如选择姓名,年龄,出生。则打印姓名,年龄,出生。
又如选择姓名,工资。则打印姓名,工资。我不知道如何去实现
方法Ⅰ
建数据窗口对象时,选用Grid风格(Grid风格数据窗口的字段宽度可以随意拖动,如同Excel),不需要打印的字段可以随时将其宽度拖动为零
方法Ⅱ
用列表框显示出所有的列,可以多选高亮列。通过Modify函数动态定义选中列的位置,宽度以及是否可见等属性

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

南七星之家

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表