DataWindow的数据更新技术及应用

华铨平

摘要:

本文介绍DataWindow的数据缓冲技术,利用该技术探索一种对非数据源表数据即时更新操作的实现方法。

关键字:数据窗口、数据缓冲、即时更新。

正文:

PowerBuilder是一个强有力的数据库前端开发工具,其DataWindow(数据窗口)控件充分体现了PowerBuilder与数据库系统的紧密结合,是PowerBuilder中拥有专利技术最多、应用最为广泛的控件。它对数据的处理方法相当简洁,有关DataWindow的数据显示、编辑、有效性检验、报表打印技术方面的文章介绍的也很多。本文结合作者多年的开发经验,利用DataWindow的数据缓冲技术,探索一种对非数据源表数据即时更新操作的实现方法。

一、DataWindow的数据缓冲机制

PowerBuilder虚拟机在处理数据窗口时,为每一个DataWindow开辟了主记录缓冲区(Primary)、删除记录缓冲区(Deleted)、过滤记录缓冲区(Filter)。每个缓冲区又分两类,当前缓冲区(Current)存储当前编辑过的数据,原来缓冲区(Original)存储最初收到的数据。数据行有四种状态:NotModified、DataModified、New、NewModified,列有二种状态:NotModified、DataModified。每次对DataWindow调用Update函数时产生对应的SQL语句如下(假定在DataWindow的Update属性窗口中设置关键字修改用Update):

 

Primary

Deleted

Filter

NotModified

不产生

Delete语句

不产生

DataModified

Update语句

Delete语句

Update语句

New

不产生

不产生

不产生

NewModified

Insert语句

不产生

Insert语句

备注

用Current数据

用Original数据

用Current数据

DataWindow从数据库收到数据后,首先存储在主记录缓冲区,删除某个记录就将该记录移到删除记录缓冲区,将过滤的记录存储在过滤缓冲区。数据初始状态为NotModified,数据有更改后状态为DataModified,且原来缓冲区中仍然保留着原来的数据。新增记录状态为New,有数据输入后状态置为NewModified。

二、相关DataWindow函数

ModifiedCount()函数根据Primary缓冲区和Filter缓冲区判别DataWindow中已被修改的行数。DeletedCount()返回Deleted缓冲区中记录的行数,即已经删除记录的行数。这两个函数可以判断数据是否被更改。

要设置某缓冲区记录行或列的状态,可以用函数SetItemStatus ( row, column, dwbuffer, status ),其中:row是要设置状态的记录行号,column是要设置状态的记录列号,为零表示设置行状态。dwbuffer是要设置状态的数据缓冲区类型。status是要设置的状态值。同样通过函数GetItemStatus ( row, column, dwbuffer)可以获取某缓冲区记录行或列的状态。

函数GetNextModified ( row, dwbuffer )的功能是从row行开始查找下一个修

改过的记录行号。

对DataWindow单个数据项的访问,可以用这样的表达式: dwcontrol.Object.columnname{.buffer}{.datasource}[row]

默认访问的是主缓冲区的当前值,例如dw_detail.object.shuliang[2]访问dw_detail对象主缓冲区第2行shuliang列的当前值;dw_detail.object.shuliang.Delete.Original[2]访问删除缓冲区第2行shuliang的原来值。

三、应用实例

在数据库应用系统设计中,经常会碰到这样的问题,比如对客户销售单据编辑修改完成后,希望能及时更改客户库存、客户应收帐款表的本期销售的值。笔者和同事曾采用过对数据库相关表的定时或手动刷新,在数据库系统中也设计过UPDATE、INSERT触发器以达到即时更新客户库存、客户应收帐款的值。这里,笔者用DataWindow数据缓冲机制来解决这一问题。

1、问题涉及的数据库表结构

客户销售单头表,字段有单据号、日期、客户号等,是dw_master控件的主要数据源表。

客户销售单项表,字段有单据号、序号、产品号、售价、数量等,是dw_detail控件的主要数据源表。

客户收付存表,字段有月份号、客户号、产品号、期初库存数量、金额、本期收入数量、金额、本期付出数量、金额等。

客户应收帐款表,字段有月份号、客户号、期初应收、本期开票、本期收款等。

2、窗口对象的设计

销售单据编辑窗口对象主要有主从DataWIndow控件dw_master、dw_detail处理销售单头、项数据,窗口界面如图(一)。

图(一)

其中定义了在保存单据数据时调用的窗口函数wf_updatekucun,主要代码:

lu_update = CREATE u_updatekucun_xs//建立自定义的对象

IF lu_update.of_init_bqfc(dw_master) < 0 THEN RETURN 1//初始化调用

li_ret = lu_update.of_updatesfcdetail_bqfc(dw_detail)//更改客户收付存表

3、设计自定义不可视对象

窗口函数调用了一个PowerBuilder的自定义不可视对象u_updatekucun_xs 来处理库存、应收帐款的即时更新,该对象主要实例变量及函数说明如下:

1)主要实例变量及说明

datawindow dw_detail,dw_master //存放传递来的主从DataWindow控件对象

string ls_kh_cur,ls_kh_org //存放主dw_master中当前、原来客户号

Dec ld_je_cur,ld_je_org//存放从dw_detail中当前、原来销售金额

long ll_sl_cur,ll_sl_org//存放从dw_detail中当前、原来销售数量

string ls_cp_cur,ls_cp_org//存放从dw_detail中当前、原来产品号

Boolean ib_update = TRUE //初始操作后,是否要继续修改库存

2)主要函数及说明

函数of_init_bqfc是进行初始操作,传递销售单编辑窗口中的主DataWindow控件对象,获取该对象中当前、原来客户号。

integer of_init_bqfc (ref datawindow adw_master);

ls_yuefen = f_getbenqi_yuefen()//取本期帐册月份号

dw_master = adw_master//该DataWindow控件对象至多有1行记录。

IF dw_master.GetRow() = 0 THEN //记录已删除

IF dw_master.DeletedCount() = 0 THEN //删除行是新行

ib_update = FALSE

Return 1

END IF

//删除行是旧行,则

ls_kh_org = dw_master.object.kehu_id.Delete.Original[1]//取原来的客户号

ls_kh_cur = ls_kh_org//该行无实际意义,此时不会有dw_dettail主缓冲区记录

ELSE //主dw_master有记录,可能是新的,也可能是旧的

dwItemStatus Rowstatus

Rowstatus=dw_master.GetItemStatus(1,0, Primary!)//当前行状态

CHOOSE CASE Rowstatus //根据当前行状态作不同处理

CASE NewModified!, NotModified! //是新行且已更改或是旧行且没有更改

ls_kh_cur= dw_master.object.kehu_id[1]

ls_kh_org= ls_kh_cur

CASE DataModified! //是旧行且已更改

ls_kh_cur= dw_master.object.kehu_id[1]

ls_kh_org= dw_master.object.kehu_id.Original[1]

END CHOOSE

END IF

RETURN 1

函数of_updatesfcdetail_bqfc则根据销售项数据修改客户的相应值。

integer of_updatesfcdetail_bqfc (ref datawindow adw_detail);

dw_detail = adw_detail

IF ib_update = FALSE THEN RETURN 1

//处理主缓冲区记录

long Rows, row = 0, count = 0,i

dwItemStatus Rowstatus,status

Rows = dw_detail.RowCount( )

//如果改变客户,则每行dw_detail未修改的记录都认为已修改

IF ls_kh_cur <> ls_kh_org THEN

FOR i = 1 to dw_detail.RowCount()

Rowstatus=dw_detail.GetItemStatus(i,0, Primary!)

IF Rowstatus = NotModified! THEN

dw_detail.SetItemStatus(i,0, Primary!,DataModified!)

END IF

NEXT

END IF

DO WHILE row <= Rows

row = dw_detail.GetNextModified(row, Primary!)//取第一个修改过的记录行号

IF row <= 0 THEN EXIT

Rowstatus=dw_detail.GetItemStatus(row,0, Primary!)//当前行状态

CHOOSE CASE Rowstatus

CASE NewModified! //是新行且已更改,用当前值更改

of_GetRow_cur(row,"Primary") //取Primary缓冲区row行当前值

//当前客户库存的本期付出加上当前值

IF of_update_bqfc(ls_kh_cur,ls_cp_cur,ll_sl_cur,ld_je_cur) < 0 THEN

Return -1

END IF

CASE DataModified! //是旧行且已更改

//原来客户库存的本期付出减去原来值

of_GetRow_org(row,"Primary")

IF of_update_bqfc(ls_kh_org,ls_cp_org,- ll_sl_org, - ld_je_org) < 0 THEN

Return -1

END IF

//当前客户库存的本期付出加上当前值

of_GetRow_cur(row,"Primary")

IF of_update_bqfc(ls_kh_cur,ls_cp_cur,ll_sl_cur,ld_je_cur) < 0 THEN

Return -1

END IF

END CHOOSE

LOOP

//处理Delete缓冲区区记录

Rows = dw_detail.DeletedCount( )

FOR row = 1 to Rows //原来客户库存的本期付出减去原来值

of_GetRow_Org(row,"Delete")

IF of_update_bqfc(ls_kh_org,ls_cp_org, - ll_sl_org, - ld_je_org) < 0 THEN

Return -1

END IF

NEXT

RETURN 1

函数of_getrow_cur获取指定缓冲区数据行的当前值。

integer of_getrow_cur (integer row, string buffer);

Dec ld_shoujia

CHOOSE CASE buffer

CASE "Primary"

ls_cp_cur= dw_detail.object.chanpin_id[row]

ll_sl_cur = dw_detail.object.shuliang[row]

ld_je_cur = ll_sl_cur * dw_detail.object.shoujia[row]

CASE "Delete"

ls_cp_cur = dw_detail.object.chanpin_id.Delete[row]

ll_sl_cur = dw_detail.object.shuliang.Delete[row]

ld_je_cur = ll_sl_cur * dw_detail.object.shoujia .Delete[row]

CASE "Filter"

ls_cp_cur = dw_detail.object.chanpin_id.Filter[row]

ll_sl_cur = dw_detail.object.shuliang.Filter[row]

ld_je_cur = ll_sl_cur * dw_detail.object.shoujia.Filter[row]

END CHOOSE

RETURN 1

函数of_getrow_org获取指定缓冲区指定数据行原来的产品号、数量、金额赋值给实例变量ls_cp_org,ll_sl_org,ld_je_org,代码同函数of_getrow_cur类似,只是访问时在对应列对象后加”. Original”以表明访问的是缓冲区的原来值。如:

ls_cp_org = dw_detail.object.chanpin_id.Original[row]

函数of_update_bqfc的功能是修改客户库存收付存表的本期付出值、应收帐款表的本期销售值。

integer of_update_bqfc (string ls_id, string ls_cp_id, long ll_sl, decimal ld_je);

UPDATE bsc_sfcdetail

SET bqfc = bqfc + :ll_sl , bqfc_j = bqfc_j + :ld_je

WHERE chanpin_id = :ls_cp_id AND id = :ls_id;

IF NOT sqlca.SQLNRows > 0 THEN//是新记录,则

INSERT INTO bsc_sfcdetail (yuefen,id, chanpin_id,bqfc,bqfc_j)

VALUES (:ls_yuefen,:ls_id,:ls_cp_id,:ll_sl, :ld_je) ;

END IF

f_checkTransOk(SQLCA) //自定义函数,检查数据库事务对象执行状况

......

更改应收帐款表cw_sfcdetail本期销售值的方法与更改客户收付存表本期付出值的方法类似。

RETURN 1

四、结束语

在笔者参与开发的分销管理系统中对发货单、入库单、调拨单等数据编辑窗口也采用了DataWindow的数据更新技术即时更新相关数据表,使用户在这些单据的编辑过程中能及时看到最新库存、应收帐款等敏感信息。数据窗口控件是PowerBuilder中最令人激动的控件,深入了解数据窗口的处理机制,灵活运用数据窗口技术,一定会使程序员获益非浅。在笔者开发过程中对每个单据又分为”未处理”、”在处理”、”已处理”,根据不同状态间的变化确定不同的更新策略。在宁波维科销售有限公司、兴洋浙东毛毯有限公司等单位具体应用,取得较好的效果。

转载于:https://www.cnblogs.com/WangPB/archive/2010/06/30/1768726.html

DataWindow的数据更新技术及应用相关推荐

  1. 大数据时代,如何构建国家地质基础数据更新体系

    大数据是当今世界经济.社会和科技发展的大趋势,已成为信息时代大国竞争的新领域.美国政府将大数据看作是"未来的新石油",并将对大数据的研究上升为国家意志.我国也要求充分运用大数据.云 ...

  2. 大数据时代到来如何构建国家地质基础数据更新体系

    原文地址 大数据是当今世界经济.社会和科技发展的大趋势,已成为信息时代大国竞争的新领域.美国政府将大数据看作是"未来的新石油",并将对大数据的研究上升为国家意志.我国也要求充分运用 ...

  3. 大数据时代_如何构建国家地质基础数据更新体系

    阅读原文请点击 摘要: 大数据是当今世界经济.社会和科技发展的大趋势,已成为信息时代大国竞争的新领域.美国政府将大数据看作是"未来的新石油",并将对大数据的研究上升为国家意志.我国 ...

  4. 嵌入式linux gif 缩放_嵌入式环境动力监控主机

    点击上方蓝字关注我们! 嵌入式环境动力监控主机 基于嵌入式LINUX平台,针对机房.变电站.博物馆等环动监控场合设计,主机集成通信端口.采集模块和WEB监控软件,具有联网功能,可独立完成区域监控任务, ...

  5. (附源码)springboot家庭财务分析系统 毕业设计 641323

    基于SpringBoot家庭财务分析系统 摘 要 大数据时代下,数据呈爆炸式地增长.为了迎合信息化时代的潮流和信息化安全的要求,利用互联网服务于其他行业,促进生产,已经是成为一种势不可挡的趋势.在家庭 ...

  6. (附源码)springboot家庭财务分析系统 毕业设计641323

    基于SpringBoot家庭财务分析系统 摘 要 大数据时代下,数据呈爆炸式地增长.为了迎合信息化时代的潮流和信息化安全的要求,利用互联网服务于其他行业,促进生产,已经是成为一种势不可挡的趋势.在家庭 ...

  7. spring boot清远旅游推荐网站的开发毕业设计-附源码211551

    摘 要 清远自然生态环境特别优越,以水域风光.园林景观.地文景观﹑气候景观﹑生物景观.建筑景观.遗址遗迹.人文活动,旅游特产为主.旅游冬有温泉﹐夏有漂流﹐并拥有喀斯特地貌特有的地下溶洞及景观,形成了清 ...

  8. springboot+清远旅游推荐网站 毕业设计-附源码211551

    清远旅游推荐网站的开发 摘 要 清远自然生态环境特别优越,以水域风光.园林景观.地文景观﹑气候景观﹑生物景观.建筑景观.遗址遗迹.人文活动,旅游特产为主.旅游冬有温泉﹐夏有漂流﹐并拥有喀斯特地貌特有的 ...

  9. (附源码)基于SSM框架的图片分享及评价网站设计与实现 毕业设计201524

    ssm图片分享及评价网站 摘 要 大数据时代下,数据呈爆炸式地增长.为了迎合信息化时代的潮流和信息化安全的要求,利用互联网服务于其他行业,促进生产,已经是成为一种势不可挡的趋势.在图片分享及评价的要求 ...

  10. (附源码)ssm+mysql+基于SSM框架的图片分享及评价网站设计与实现 毕业设计201524

    ssm图片分享及评价网站 摘 要 大数据时代下,数据呈爆炸式地增长.为了迎合信息化时代的潮流和信息化安全的要求,利用互联网服务于其他行业,促进生产,已经是成为一种势不可挡的趋势.在图片分享及评价的要求 ...

最新文章

  1. 百度开源业内首个口罩人脸检测及分类模型,携手开发者共同抗疫
  2. Tools - 一些代码阅读的方法
  3. 世界第一台电脑_再述东芝的传奇霸业:当年造出世界上首台笔记本,现在却为何放弃...
  4. c语言常量结构体的成员,c语言之结构体
  5. nginx简单代理配置
  6. Java日常错误及需要注意细节,持续更新......
  7. 5.10 Ext JS Grid中 WidgetColumn(组件列)的使用
  8. hadoop MapReduce 输出结果中文乱码解决
  9. 1038. Recover the Smallest Number
  10. html中居中的三种方式
  11. 视频教程-JQuery全套视频-jQuery
  12. 原创|批处理|批处理安卓log抓取工具
  13. android能卸载干净,安卓系统清理卸载残留的方法
  14. 不知道如何写好作文?写好作文的十大技巧赶紧收好
  15. html入门、结构、标签、列表、表格
  16. android微信7,微信7.0安卓版之初体验
  17. 仿照余额宝余额动态变动
  18. 文本框导入图片并显示到页面上
  19. 现代前端技术解析读书笔记
  20. Mercury mw150us(8188eu) debian wireless driver

热门文章

  1. matlab画三维图如何更改颜色,MATLAB画三维图像
  2. html canvas 绘制转盘,Canvas绘制转盘
  3. 【python】if __name__==‘__mian__‘ 如何理解,原理及作用
  4. 学生用计算机中括号怎么打,大括号怎么打,教您word大括号怎么输入
  5. 语音识别(Speech Recognition)
  6. 青岛大学的计算机专业考研分数线,青岛大学考研分数线
  7. 大学生计算机应用基础赵山林高媛,我院学生获“第四届全国大学生计算机应用能力与信息素养大赛(IC3)”全国一等奖...
  8. linux魔兽世界黑屏怎么办,魔兽世界8.1登陆界面黑屏怎么办 魔兽世界8.1登陆界面黑屏解决方法...
  9. 教你如何使用u盘安装Linux系统,手把手教你如何使用u盘安装Linux系统
  10. 如何写好一个打动投资人的计划书