tangdh
PB and .net 乐园

2010年6月1日

一、处理SQL语句
1、缓冲SQL语句
应用程序中有时需要反复调用同一组SQL语句,在这种情况下,可以通过在应用中为这些SQL建立缓冲

区来提高执行性能。
在缺省情况下,SQL语句的缓冲区是关闭的,可以通过如下语句打开:
SQLCACHE=n  n表示装入缓冲区SQL语句数量(缺省为0)

  例如:
     dw_1.SetTransObject(sqlca)
     SQLCA.dbParm = "SQLCache = 0"
     dw_1.retrieve()

    如果将上例的 "SQLCache = 0" 改为 "SQLCache = 25", 此句的执行效率将提高五分之一左右。

但应注意缓冲区的大小,否则也将影响程序执行的性能。注:此方法对用 ODBC 和 ORACLE 连接的数据

库非常有效。

2、捆绑变量
    请看下例:
     SQLCA.DBPARM = "DISABLEBIND=1"
     INSERT INTO DA_DH valueS("1","河南0")
     INSERT INTO DA_DH valueS("2","河南1")
     INSERT INTO DA_DH valueS("3","河南2")
     INSERT INTO DA_DH valueS("4","河南3")
     INSERT INTO DA_DH valueS("5","河南4")
     INSERT INTO DA_DH valueS("6","河南5")

    这里未使用捆绑变量,在插入是 PB 将重新处理每个带有    新值的SQL语句。如果将上例改为:

     SQLCA.DBPARM = "DISABLEBIND=0"

     INSERT INTO DA_DH valueS("1","河南0")
     INSERT INTO DA_DH valueS("2","河南1")
     INSERT INTO DA_DH valueS("3","河南2")
     INSERT INTO DA_DH valueS("4","河南3")
     INSERT INTO DA_DH valueS("5","河南4")
     INSERT INTO DA_DH valueS("6","河南5")

    则系统将把 INSERT 语句按如下格式进行处理:
     INSERT INTO DA_DH valueS(?,?)
    其中 "?" 称为占位符。系统性能将有所增强。

3、用数据窗口代替 SQL 语句

    通常,为了获得某些数据,采用数据窗口和 SQL 语句都是可行的,但是PB 对数据窗口和 SQL 语

句采用不同的处理机制,因此,具有不同的效率。例:为里检索电话档案中的用户名,可以利用 SQL

语句,将所有的数据检索到一个多行编辑中,也可以检索到一个数据窗口中。如果使用第一种方法:

    首先定义一个游标:

     DECLARE CUR CURSOR FOR
     SELECT "DA_DH"."HM"
     FROM "DA_DH";

    然后可以:

     STRING stxt[],st
     int li
     open cur
     do li = li + 1
        fetch cur
        into :stxt[li] ;
        st=st+stxt[li] + "~r~n"
     loop while stxt[li]<>""
     close cur;
     mle_1.txt = st

    也可以使用第二种方法:

     dw_1.settransobject(sqlca)
     dw_1.retrieve()

    利用 POWERBUILDER PROFILER 工具进行检查,对比两种方法所需时间如下
    方法                     所需时间 (百分之一秒)
     SQL 语句      100.9857
    数据窗口               49.0133

    由于数据窗口或DATASTORE 使用了标准的内嵌的代码,而不是有开发人员进行全部编码,同时编

译执行的速度比解释执行的速度快的多,因此在开发过程中应尽量使用数据窗口和DATASTORE..    即

使是必须用 SQL 语句的时候,也应该尽量将它们定义为存储过程(特别是在多用户的环境中),以

提高应用程序的性能.

 

二、数据窗口的编程和执行
    数据窗口是PB最值得被称道的, 其具有如下特点:
     1、多种显示方式.
     2、多种编辑方式.
     3、使用方法简单.
     4、具有多种报表形式.
     5、可实现屏幕滚动.
     6、可实现数据的有效性校验.
     7、执行性能显著提高.
     8、编程工作变少.
     9、可以在数据窗口内部实现数据哭的更新.

    下面, 我将介绍一些用于提高数据窗口性能的技术.

1、减少连接数据库的次数

    连库操作是非常影响执行速度的操作. 因此在程序中,一旦与数据库连接后就应当尽量保持与数据

库的连接, 减少连接数据库的次数.PowerBuilder 提供里两个函数来建立数据窗口与事务对象的连接:
         SetTrans()
         SetTransObject()
    在程序中应当尽量使用 SetTransObject(), 因为SetTrans() 函数在每次调用 Retrieve(),

Update() 等函数之后, 都要执行数据库的连接和断开操作.

2、下拉数据窗口与表的连接

    对于数据库服务器来说, 表的连接操作是一项非常大的开销, 而 PowerBuilder 提供的下拉数据

窗口在某些情况下可以代替表的连接操作.

    例如, 为了在数据窗口上显示用户的电话号码和姓名:如果用表的连接的方法, 数据窗口对应的

SQL 语句应是这样的:
     SELECT "DA_DH"."DHHM","DA_HTH"."DWM"
     FROM "DA_HTH", "DA_DH"
     WHERE ("DA_HTH"."DHHM"="DA_DH"."DHHM")
    同样的程序可用下拉数据窗口来完成, 这里不再具体介绍.但是, 应当注意, 以上两种方法究竟哪

一种数据更快, 与表的结构, 表的数量, 连接的方法等均有关系, 应当具体分析.


3、共享数据

    在一个应用程序中, 某些数据需要频繁的使用, 如果在每次使用时都从数据库中进行检索, 则需

占用大量的服务器资源和网络资源. 为了减少开销, 可以在客户端对这些数据只进行一次检索, 然后

允许其它任务共享这些数据.

    例如, 如果有两个数据窗口, 都需要从第三方表中检索出用户的电话号码, 且此列用下拉数据窗

口给出. 如果每次都对电话号码进行检索, 则性能较低. 因此, 可以单独建立一个关于电话号码的数

据窗口. 在每次打开窗口时, 首先将电话号码检索到此数据窗口中, 然后另外两个数据窗口中关于电

话号码的下拉数据窗口可以共享此数据窗口中的数据.

    在窗口的 Open 事件中编写如下程序:

     dw_1.settransobject(sqlca)
     dw_2.settransobject(sqlca)
     dw_3.settransobject(sqlca)
     // 检索 dw_1
     dw_1.retrieve()

     // 使 DW_2 的下拉数据窗口共享 DW_1
     datawindowchild child1
     dw_2.getchild('dhhm',child1)
     child1.settransobject(sqlca)
     dw_1.sharedata(child1)

     // 使 DW_2 的下拉数据窗口共享 DW_1
     datawindowchild child2
     dw_3.getchild('dhhm',child2)
     child2.settransobject(sqlca)
     dw_1.sharedata(child1)
    使用这种方法, 避免了各个数据窗口间物理的拷贝数据, 因此减少了空间上的开销,提高了应用程

序的综合性能.

4、数据窗口间数据的拷贝

    如果需要在数据窗口间共享数据, 应当尽量使用 ShareData() 函数, 但是,ShareData() 函数并

不是物理地在数据窗口间拷贝数据, 如果在显示数据的同时, 还要对数据进行操作, 则需要进行数据

的拷贝.

    例如, 要求将 DW_1 中选定的行拷贝到 DW_2 中:

    在窗口的 OPEN 事件中编程:
     dw_1.settransobject(sqlca)
     dw_2.settransobject(sqlca)
     dw_1.retrieve()

    在数据窗口 DW_1 的 rowfocuschanged 事件中编写下列程序:
     long lr
     lr = dw_1.selectrow(0,false)
     lr = dw_1.getrow()
     lr = dw_1.selectrow(lr,true)

    要完成从 DW_1 到 DW_2 的拷贝工作, 有两种方法:

    第一种:在按钮 "拷贝" 的 CLICKED 事件中编程
     long lr
     lr = dw_1.getselectedrow(0)
     dw_1.rowscopy(lr,lr,primary!,dw_2,100,primary!)
    执行程序, 利用 POWERBUILDER PROFILER 得出所需时间为 1.7034(百分之一秒)

    第二种:在按钮 "拷贝" 的 CLICKED 事件中编程
     dw_2.object.data = da_1.object.data.selected
    执行程序, 利用 POWERBUILDER PROFILER 得出所需时间为 0.8062(百分之一秒)

5、数据窗口属性的访问和修改

     A、数据窗口属性的访问
    在程序中访问数据窗口的属性有下列几种方法:
     A1、采用点表达式访问
     A2、应用多个独立的 Describe() 函数访问
     A3、只使用一个 Describe() 函数, 采用复合参数访问多个属性
    上面三中方法, 通常第一种方法最慢, 第三种方法最快.

    例如:
    在窗口的 OPEN 事件中
     DW_1.Settransobject(SQLCA)
     DW_1.Retrieve()

    第一种方法:
    在检索按钮的 CLICKED 事件中编程.

     string dx, dy, dh, dw
     dx = dw_1.object.da_dh.x
     dy = dw_1.object.da_dh.y

     dx = dw_1.object.da_dh.height
     dy = dw_1.object.da_dh.width

     st_1.text =dx+","+dy+","+dh+","+dw

    第二种方法:
     string dx, dy, dh, dw
     dx=dw_1.describe("da_dh.x")
     dx=dw_1.describe("da_dh.y")
     dx=dw_1.describe("da_dh.height")
     dx=dw_1.describe("da_dh.width")

     st_1.text =dx+","+dy+","+dh+","+dw

    第三种方法:
     string dx, dy, dh, dw
     st_1.text=dw_1.describe("da_dh.x" + "a_dh.y" + "da_dh.height" + "da_dh.width")

    实验证明, 第三种方法的速度是最快的. 但是程序的可读性最差.

     B. 数据窗口属性的修改
    在程序中修改数据窗口的属性有下列几种方法:

     A1. 采用点表达式修改
     A2. 应用多个独立的 Modify() 函数访问
     A3. 只使用一个 Modify() 函数, 采用复合参数访问多个属性

    上面三中方法, 通常第一种方法最慢, 第三种方法最快.

    例如:
    在窗口的 OPEN 事件中
     DW_1.Settransobject(SQLCA)
     DW_1.Retrieve()

    第一种方法:
    在检索按钮的 CLICKED 事件中编程.

     DW_1.SETREDRAW(FALSE)
     dw_1.object.da_dh.x = 18
     dw_1.object.da_dh.y = 16
     dw_1.object.da_dh.height = 100
     dw_1.object.da_dh.width = 200
     DW_1.setredraw(true)
     st_1.text =dx+","+dy+","+dh+","+dw

    第二种方法:
     DW_1.SETREDRAW(FALSE)
     dw_1.modify("da_dh.x = 18")
     dw_1.modify("da_dh.y = 16")
     dw_1.modify("da_dh.height = 100")
     dw_1.modify("da_dh.width = 200")
     dw_1.setredraw(true)

    第三种方法:
     dw_1.modify("da_dh.x=18" + "da_dh.y=16" + "da_dh.height=100" + "da_dh.width=200")

    实验证明, 第三种方法的速度是最快的. 但是程序的可读性最差.
    注意, 在方法一和方法二中, 都使用的 setredraw() 函数以减少屏幕的重绘, 否则, 执行速度将

严重下降.


6、数据窗口中数据的访问

    在程序中, 经常会需要动态的修改数据窗口中的数据. 对此, PB提供了多种方法, 各种方法在性

能上会有一些差异.

A、数据窗口中数据的访问

    目的: 将数据窗口中的电话号码存放在一个数组中.
    请比较下面两中方法.
    方法一:
     string da_dh[]
     long ll,i
     ll = dw_1.rowcount()
     for i = ll to 1 stet -1
         da_dh[i] = dw_1.getitemstring(i,"dhhm")
     next
    方法二:
     string da_dh[]
     da_dh[] = dw_1.object.dhhm.current

    测试发现, 第二种方法比第一种方法快将近一倍. 数据量越大这种差异越明显.

B、数据窗口中数据的修改

    目的: 修改数据窗口中的电话号码列的值.
    请比较下面两中方法.
    方法一:
     dw_1.setitem(i,"dhhm",l_name)
    方法二:
     dw_1.object.name[i] = l_name
    测试发现, 第二种方法比第一种方法快将近一倍. 数据量越大这种差异越明显.

7、数据窗口事件对性能的影响

   对于数据窗口控制中经常发生的事件, 应当尽量减少其中的程序代码.特别是如下事件:
     a、 itemchanged
     b、 editchanged
     c、 itemfocuschanged
     d、 pbm_dwnkey
     e、 rowfocuschanged
     f、 retrieverow
    在这些事件中的任何处理程序, 都会降低应用程序的处理速度. 所以应当尽量减少这些事件中的

处理程序, 必要时, 可以考虑只将重要的代码放在这些事件中, 而将剩余的代码放在一个传递的事件

中.

    例如,如果需要用到数据窗口的 Rowfocuschanged 事件,可以为数据窗口定义一用户事件

"UE_RE",       而在数据窗口的 ROWFOCUSCHANGED 事件中写如下代码:

     Parent.postevent("ue_re")
    在 UE_RE 事件中再编写相应的程序代码,如:
     string code
     dw_1.selectrow(0,false)
     dw_1.selectrow(rownum,true)
     code = getitemstring(dw_1,rownum,"dhhm")
     dw_2.retrieve(code)

    另外,为了获得当前行号,应尽量使用数据窗口的 Currentrow 变量,而少用 GETROW() 函数

8、数据窗口的列名称与列编号
    对数据窗口的某列进行访问, 可以采用该列的名称, 也可以使用该列的编号,
    例如:采用列编号:
    dw_1.object.data[ll_row,2]
    dw_1.getitemstring(3,2)
    采用列名称表示某列:
    dw_1.object.article_text[ll_row]
    dw_1.getitemstring(3,"dhhm")
    dw_1.setitem(3,"date",1999-03-31)
    对于以上两种方法, 如果只进行一次查询, 在速度上并没有太大的区别,如过需要循环访问数据窗口上的某一列, 则速度上的差异就表现的比较明显,才用第一种方法要快, 但是程序的可读性比较差。
但是, 在使用函数时(如 GETITEM() 和 setitem() ), 执行速度往往没有很大差别。
9、计算域
    数据窗口的计算域会对数据的操作性能产生影响。 如果数据窗口中包含许多复杂的计算域,将严重影响数据窗口的执行速度。

 

 

 

posted @ 2010-06-01 16:24 tangdh 阅读(201) 评论(0) 编辑
 
string ls_selected

ls_selected=dw_1.Object.DataWindow.Selected.Data

clipboard(ls_selected)
posted @ 2010-06-01 16:15 tangdh 阅读(97) 评论(0) 编辑
 
string ls_msg
choose case error.number
case 1//by zero
ls_msg = "发生被 0 除错误"
case 2//2 Null object reference
ls_msg = "空对象引用"
case 3//3 Array boundary exceeded
ls_msg = "数组越界"
case 4//4 Enumerated value is out of range for function
ls_msg = "枚举值超出函数的范围"
case 5//5 Negative value encountered in function
ls_msg = "函数中遇到负数"
case 6//6 Invalid DataWindow row/column specified
ls_msg = "数据窗口的列或行非法"
case 7//7 Unresolvable external when linking reference
ls_msg = "链接调用时不能解决外部对象"
case 8//8 Reference of array with null subscript
ls_msg = "使用空下标引用数组"
case 9//9 DLL function not found in current application
ls_msg = "当前应用中没有找到动态链接库的函数"
case 10//10 Unsupported argument type in DLL function
ls_msg = "使用了动态链接库函数不支持的参数类型"
case 11//11 Object file is out of date and must be converted to current version
ls_msg = "对象文件已经过时并且必须使用当前的版本"
case 12//12 DataWindow column type does not match GetItem type
ls_msg = "数据窗口的列的数据类型与GetItem函数的类型不符"
case 13//13 Unresolved property reference
ls_msg = "属性引用尚未解决"
case 14//14 Error opening DLL library for external function
ls_msg = "为外部函数调用而打开动态链接库时发生错误"
case 15//15 Error calling external function name
ls_msg = "调用外部函数时发生错误"
case 16//16 Maximum string size exceeded
ls_msg = "字符串长度超越了最大**"
case 17//17 DataWindow referenced in DataWindow object does not exist
ls_msg = "数据窗口引用的数据窗口对象不存在"
case 18//18 Function doesn't return value
ls_msg = "函数没有返回值(应该有而没有)"
case 19//19 Cannot convert name in Any variable to name
ls_msg = "不能转换Any类型的变量到另一个类型"
case 20//20 Database command has not been successfully prepared
ls_msg = "数据库命令没有成功准备"
case 21//21 Bad runtime function reference
ls_msg = "引用了错误的运行时函数"
case 22//22 Unknown object type
ls_msg = "不知道的对象类型"
case 23//23 Cannot assign object of type name to variable of type name
ls_msg = "不能将对象赋给变量,两种类型不能赋值"
case 24//24 Function call doesn't match its definition
ls_msg = "函数调用格式与其定义不一致"
case 25//25 Double or Real expression has overflowed
ls_msg = "双精度型或实型表达式溢出"
case 26//26 Field name assignment not supported
ls_msg = "不支持这种字段赋值"
case 27//27 Cannot take a negative to a noninteger power
ls_msg = "不能计算一个负数的非整数次方"
case 28//28 VBX Error: name
ls_msg = "VBX 错误"
case 29//29 Nonarray expected in ANY variable
ls_msg = "ANY 类型变量期待非数组类型"
case 30//30 External object does not support data type name
ls_msg = "外部对象不支持这种变量类型"
case 31//31 External object data type name not supported
ls_msg = "外部对象的数据类型不支持"
case 32//32 Name not found calling external object function name
ls_msg = "调用外部对象函数时函数名称没有找到"
case 33//33 Invalid parameter type calling external object function name
ls_msg = "调用外部对象函数时使用了错误的参数类型"
case 34//34 Incorrect number of parameters calling external object function name
ls_msg = "调用外部对象函数时使用的参数个数不对"
case 35//35 Error calling external object function name
ls_msg = "调用外部对象的函数错误"
case 36//36 Name not found accessing external object property name
ls_msg = "访问外部对象属性时属性名称没有找到"
case 37//37 Type mismatch accessing external object property name
ls_msg = "访问外部对象属性时使用了不匹配的类型"
case 38//38 Incorrect number of subscripts accessing external object property name
ls_msg = "访问外部对象属性时使用了错误的下标"
case 39//39 Error accessing external object property name
ls_msg = "访问外部对象的属性错误"
case 40//40 Mismatched ANY data types in expression
ls_msg = "表达式中ANY数据类型不匹配"
case 41//41 Illegal ANY data type in expression
ls_msg = "表达式中使用了非法的ANY数据类型"
case 42//42 Specified argument type differs from required argument type at runtime in DLL function name
ls_msg = "指定的参数类型与动态链接库中的函数所需要的参数类型不一致"
case 43//43 Parent object doesn't exist
ls_msg = "父对象不存在"
case 44//44 Function has conflicting argument or return type in ancestor
ls_msg = "函数与祖先的参数或返回值冲突"
case 45//45 Internal table overflow; maximum number of objects exceeded
ls_msg = "内部表溢出;对象的最大数目已经超越"
case 46//46 Null object reference cannot be assigned or passed to a variable of this type
ls_msg = "空对象引用不能赋值或传递给一个这种类型的变量"
case 47//47 Array expected in ANY variable
ls_msg = "ANY类型期待数组"
case 48//48 Size mismatch in array to object conversion
ls_msg = "将数组转换成对象时数组的大小不匹配"
case 49//49 Type mismatch in array to object conversion
ls_msg = "将数组转换成对象不匹配"
case 50//50 Distributed Service Error
ls_msg = "分布式服务错误"
case 51//51 Bad argument list for function/event
ls_msg = "函数/事件的参数列表错误"
case 52//52 Distributed Communications Error
ls_msg = "分布式通讯错误"
case 53//53 Requested server not active
ls_msg = "被请求的服务器没有激活"
case 54//54 Server not accepting requests
ls_msg = "服务器不接受请求"
case 55//55 Request terminated abnormally
ls_msg = "请求意外中断"
case 56//56 Response to request incomplete
ls_msg = "响应请求不完整"
case 57//57 Not connected
ls_msg = "没有连接"
case 58//58 Object instance does not exist
ls_msg = "对象实例不存在"
case 59//59 Invalid column range
ls_msg = "无效的列的范围"
case 60//60 Invalid row range
ls_msg = "无效的行的范围"
case 61//61 Invalid conversion of number dimensional array to object
ls_msg = "转换**数组到一个对象无效"
case 62//62 Server busy
ls_msg = "服务器忙"
case 63//63 Function/event with no return value used in expression
ls_msg = "在表达式中函数/事件没有返回值"
case 64//64 Object array expected in left side of assignment
ls_msg = "赋值语句左边期待对象数组"
case 65//65 Dynamic function not found. Possible causes include: pass by value/reference mismatch
ls_msg = "动态函数没有找到,可能是因为:值传递/引用传递不匹配"
case 66//66 Invalid subscript for array index operation
ls_msg = "属组索引使用了非法的下标"
case 67//67 NULL object reference cannot be assigned or passed to an autoinstantiate
ls_msg = "空的对象引用不能赋值或传递给一个自动实例化对象"
case 68//68 NULL object reference cannot be passed to external DLL function name
ls_msg = "空的对象引用不能传递给外部动态链接库函数"
case 69//69 Function name cannot be called from a secured runtime session
ls_msg = "安全模式中不能调用该函数"
case 70//70 External DLL function name cannot be called from a secured runtime session
ls_msg = "安全模式中不能调用外部动态链接库函数"
case 71//71 General protection fault occurred
ls_msg = "发生一般的保护错误"
case 72//72 name failed with an operating system error code of number
ls_msg = "字段发生一个操作系统错误"
case 73//73 Reference parameters cannot be passed to an asynchronous shared/remote object method
ls_msg = "引用型参数不能传递给一个异步的共享/远程对象方法"
case 74//74 Reference parameters cannot be passed to a shared object method
ls_msg = "引用型参数不能传递给一个共享对象的方法"
case 75//75 The server has forced the client to disconnect
ls_msg = "服务器已经强制客户端断开连接"
case 76//76 Passing NULL as a parameter to external function name
ls_msg = "给外部函数传递了一个空值参数"
case 77//77 Object passed to shared/remote object method is not a nonvisual user object
ls_msg = "对象传递给共享/远程对象的方法不是一个不可视的用户对象"
case 78//78 Listen can only be done in Enterprise version of PowerBuilder
ls_msg = "本人只能在企业版的PowerBuilder中使用"
case 79//79 The argument to name must be an array
ls_msg = "参数必须是一个数组"
case 80//80 The server has timed out the client connection
ls_msg = "客户端尝试连接的时间已经超出服务器设置的**时间"
case 81//81 Function argument file creator must be a four character string
ls_msg = "函数参数文件创建者必须是一个四个字符的字符串"
case 82//82 Function argument file type must be a four character string
ls_msg = "函数参数文件类型必须是一个四个字符的字符串"
case 83//83 Attempt to invoke a function or event that is not accessible
ls_msg = "试图调用一个不可存取的函数或事件"
case 84//84 Wrong number of arguments passed to function/event call
ls_msg = "在函数/事件中传递的参数个数错误"
case 85//85 Error in reference argument passed in function/event call
ls_msg = "在函数/事件中传递的引用型参数错误"
case 86//86 Ambiguous function/event reference
ls_msg = "引用不明确的函数/事件"
case 87//87 The connection to the server has been lost
ls_msg = "与服务器的连接已经丢失"
case 88//88 Cannot ask for ClassDefinition Information on open painter: name
ls_msg = "不能在打开的画笔中查询类定义信息"
case 85//89 5.0 style proxy objects are not supported. Copy the new style proxy that was generated at migration time
ls_msg = "5.0中的类型代理对象不支持,拷贝移植时产生的新的类型代理"
case 90//90 Cannot assign array of type name to variable of type array of name
ls_msg = "这两种数据类型的数组不能赋值"
case 91//91 Cannot convert any in Any variable to string.Possible cause uninitialized value.
ls_msg = "不能将任意型变量转变成字符型变量"
case else
ls_msg = '未知错误, 请记录错误号并与管理员联系'
end choose
posted @ 2010-06-01 16:10 tangdh 阅读(566) 评论(0) 编辑
 
在PB中,ItemChanged事件具有数据效验功能。通过其返回值,可以告之PB数据是否通过用户效验,然后PB将根据此效验结果决定是接受新值还是拒绝修改。此描述的隐含的表达了:PB在ItemChanged执行完后设置单元格值。另外,程序员无法在ItemChanged修改data参数(即新值)。也就是说,在ItemChanged事件中,我们只能决定是否接受这次修改,若是,则单元格值为输入值(即Data参数值),否则,单元格将保持原值。我们无法为单元格指定两者外的一个值。
  这样就无法在ItemChanged中实现这样一种效果:根据用户输入,对其进行一些转换或格式化操作,再赋给单元格。因为在ItemChanged中设置的单元格值会在ItemChanged事件执行完后被冲掉,最终单元格值仍将根据ItemChanged返回值被置为Data值或原值。
  但借助Post关键字可以非常简洁的获得此效果,PB文档中对Post的描述大意是:Post将目标调用放入窗口的消息队列中,所调用代码何时执行取决于消息在消息队列中的位置。
此用Post的原理如下:
  Windows应用程序是事件驱动或消息驱动的,用户通过界面交互生成消息,程序捕获各种消息并针对各种消息调用不同的处理程序,这些处理程序中包装有用户逻辑。
  消息的处理是串行的,在一个消息处理完之前,下一个消息不会被开始处理。一个消息的生命周期从其被生成并加入消息队列开始,到其处理完毕时止。
  从ItemChanged事件被触发,到PB根据ItemChanged事件返回值设置单元值格,属于同一个消息处理过程。因此在此期间通过Post调用的操作,将在PB设置单元格之后执行。

此方法的使用描述如下:在ItemChanged事件中,在设置单元格值的语句前加上关键字Post即可。eg:

String NewValue = "17951" + data;
Post SetValue(Col,Row,NewValue);

注:
1、PB中的事件与Windows中的事件含义并不相同。
2、PB如何将函数调用包装为一个消息,这是一个很值得探讨的东西。
posted @ 2010-06-01 16:05 tangdh 阅读(642) 评论(0) 编辑
 

多个DW进行update

//菜鸟代码
dw_1.Update()
dw_2.Update()
初级代码
IF dw_1.Update() = 1 And dw_2.Update() = 1 THEN
        COMMIT;
ELSE
        ROLLBACK;
END IF
中级代码
IF dw_1.Update() = 1 THEN
        IF dw_2.Update() = 1 THEN
                COMMIT;
        ELSE
                MessageBox("提示","喝多了!")
                ROLLBACK;
        END IF
ELSE
        MessageBox("提示","喝多了!")
        ROLLBACK;
END IF
高级代码
IF dw_1.Update() = 1 THEN
        IF dw_2.Update() = 1 THEN
                COMMIT;
        ELSE
                ROLLBACK;
                MessageBox("提示","少喝点!")
        END IF
ELSE
        ROLLBACK;
        MessageBox("提示","少喝点!")
END IF
专家级代码
IF dw_1.Update(True,False) = 1 THEN
        IF dw_2.Update(True,False) = 1 THEN
                dw_1.ResetUpdate()
                dw_2.ResetUpdate()
                COMMIT;
        ELSE
                ROLLBACK;
                MessageBox("提示","没喝高啊!")
        END IF
ELSE
        ROLLBACK;
        MessageBox("提示","没喝高啊!")
END IF

 

 

多个DW进行update,有时会不能全部成功update 用事务处理时,多个DW进行update后,再COMMIT.偶然会发现前面几个DW update成功,但后面的表失败时,好像执行了COMMIT,不会rollback.

正确的写法如下:
if dw_1.update(true, false)= 1 and dw_2.update(true, false)=1 ...then
  commit;
  dw_1.resetUpdate();
  dw_2.resetUpdate();

else
  rollback;
end if

posted @ 2010-06-01 15:46 tangdh 阅读(401) 评论(0) 编辑