您的位置:首页 > 其它

PB中动态加载数据窗的实现

2015-07-31 17:14 225 查看

介绍

大家好,在这里我将通过一个PB的demo来实现,动态加载数据窗功能的实现。

在工程中有dw_test这个数据窗口(图1,编译时),我需要在运行时,把数据窗替换成新的数据窗展示效果(图2,运行时)。





代码与功能实现

工程连接数据库(oracle)

/*工程入口代码*/
SQLCA.DBMS = "O10 Oracle10g (10.1.0)"
SQLCA.LogPass = "123456"
SQLCA.ServerName = "test_service"
SQLCA.LogId = "user"
SQLCA.AutoCommit = False
SQLCA.DBParm = "PBCatalogOwner='user'"

connect using sqlca;

open(w_main)


用于保存动态加载数据窗语法的表(bill_set)

NameTypeComments
BILL_NOVARCHAR2(10)数据窗号
BILL_NAMEVARCHAR2(60)数据窗名称(用于显示)
DW_NAMEVARCHAR2(60)数据窗名称(在工程对象中的名字)
ENABLEDCHAR(1)有效性
OPERATORVARCHAR2(27)操作人
OPERATE_TIMEDATE操作时间
SYNTAXLONG RAW数据窗语法
动态加载方法f_dynamic_dw(datawindow adw_x)

AccessReturn TypeFunction Name
publicintegerf_dynamic_dw
Pass ByArgument TypeArgument Name
valuedatawindowadw_x
/*
auther:sxh
time:2015-03-06
function:仿照his的动态加载对象(n_bill_set),重写,动态加载数据窗的对象
*/

/* 判断空对象处理 */
if not isvalid(adw_x) then return -1

/* 只有数据窗对象可以使用动态加载功能 */
string ls_dw_name_old
if (TypeOf(adw_x) = datawindow!) then
ls_dw_name_old = adw_x.dataobject
else
return 0
end if

string ls_bill_no           //票据号<pk>
string ls_dw_name   //数据窗名称
string ls_syntax            //数据窗语法
string ls_lock          //锁表语句
string ls_error_create  //动态构造数据窗错误信息
blob lbl_syntax         //数据窗语法,blob

//查询这个数据窗有没有可用的构造语法,从表中获取
select trim(a.bill_no),trim(a.dw_name)
into   :ls_bill_no,:ls_dw_name
from   comm.bill_set a
where  enabled = '1'
and    a.dw_name = :ls_dw_name_old;
if sqlca.sqlcode < 0 then return messagebox("提示","动态加载功能查询数据窗构造语法出错。")

//如果为空,就要自动注册
if (isnull(ls_bill_no) or ls_bill_no = '') then
//锁表,并发的可能性不大,锁全表也没关系的,之后会commit
ls_lock = 'LOCK TABLE comm.bill_set IN EXCLUSIVE MODE'
EXECUTE IMMEDIATE :ls_lock;
if  sqlca.sqlcode  < 0 then return messagebox("提示","comm.bill_set表锁表语句执行出错。")

//生成新票据号
SELECT NVL(MAX(to_number(bill_no))+1,1)
INTO     :ls_bill_no
FROM     comm.bill_set;
if  sqlca.sqlcode  < 0 then return messagebox("提示","生成票据号语法出错。")
//如果没有数据
IF sqlca.sqlcode =100 THEN ls_bill_no = '1'

INSERT INTO comm.bill_set
( BILL_NO,
BILL_NAME,
DW_NAME,
ENABLED,
operate_time)
VALUES (:ls_bill_no,
:ls_dw_name_old,
:ls_dw_name_old,
'1',
sysdate)  ;
if sqlca.sqlcode < 0 then return messagebox("提示","动态加载自动注册sql语法出错。")

//获取程序"编译时"的数据窗语法
ls_syntax = adw_x.dynamic describe("DataWindow.Syntax")
//转码
//ls_syntax = trim(string(ls_syntax, EncodingANSI!))

if not(isnull(ls_syntax) or ls_syntax="") then
//bolb的变量用insert进不去,需要使用updateblob语句才能更新进去
lbl_syntax = blob(ls_syntax,EncodingANSI!)
updateblob comm.bill_set
set syntax = :lbl_syntax
where BILL_NO = :ls_bill_no;
if sqlca.sqlcode < 0 then return messagebox("提示","更新动态加载syntax语法出错。")
end if

//提交,使用sqlca事务
commit using sqlca;

else    //如果不为空,那么就用这个语法重新构造数据窗
selectblob syntax
into       :lbl_syntax
from       comm.bill_set
where      bill_no = :ls_bill_no;
if sqlca.sqlcode < 0 then return messagebox("提示","更新动态加载syntax语法出错(票据号不为空)。")

//pb12.5 转换增加字符集
ls_syntax = trim(string(lbl_syntax, EncodingANSI!))

if Len(ls_syntax) > 0 then
if isvalid(adw_x) then
adw_x.dynamic Create(ls_syntax, ls_error_create)

IF Len(ls_error_create) > 0 THEN
MessageBox('提示','构造数据窗语法出错:'+ls_error_create+'。~r~n可能会影响程序的运行。请通知系统管理员。')
END IF

adw_x.dynamic reset()
adw_x.dynamic settransobject(sqlca)
end if
end if
end if

return 0


w_main窗口中的open事件



dw_1.settransobject(sqlca)

f_dynamic_dw(dw_1)

dw_1.retrieve( )


替换数据窗edit source

完成以上代码后,第一次打开会再表(bill_set)中保存一条记录,在syntax中保存的就是数据窗口的构造语法



替换原有的代码

在PB中新建一个数据窗,dw_test_dynamic,用edit source方式打开,



用数据库中的语法覆盖,然后对数据窗进行编辑,使其有如下的展示效果,



接着用edit source方式打开,复制构造语法到数据库中syntax字段里。

下次打开时,就会动态加载新数据窗啦

完成。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: