Database 版 (精华区)
发信人: lizhenguo (夸父·追日), 信区: Database
标 题: 6
发信站: 哈工大紫丁香 (2001年09月26日18:37:57 星期三), 站内信件
利用SetActionCode函数控制DataWindow
DataWindow控件的一些事件有一个动作码操纵这个事件之后的缺省动作。在Pow-erBuil
der 4.0中我们可以使用SetAction-Code函数,来设置这个动作码的值以控制在这些事件
发生后的处理过程。(在PowerBuilder 5.0中,由于事件可以有返回数值,所以采用返回一
个整型数值来取代SetActionCode函数,比如使用return 1取代SetActionCode(1),但基本
的使用规则两者是相同的。)DataWindow控件中下列事件使用动作码:
CLICKED
DBERROR
ITEMCHANGED
ITEMERROR
PRINTPAGE
RETRIEVEROW
RETRIEVESTART
UPDATESTART
有效的动作码值和应当的处理过程随事件的不同而不同。
Clicked Event
Clicked Event
无论何时,当用户在DataWindow控件上点击时,CLICKED事件被触发。如果点击在一个有效
的行上,那么DataWindow将自动把此行作为当前行。如果你不想换行,就可以使用SetAct
ionCode来停止。
0 进行换行和CLICKED事件。(缺省)
1 停止处理CLICKED事件。
例如:下面一段代码只允许用户点击在自己的用户号上。
//Clicked Event
//We'll assume there is an instance variable with the current user's
//User ID:string is_user_id
long ll_row
string ls_user_id
ll_row =GetClickedRow()
//No need to continue if the user didn't click on a valid row
if ll_row<1 then
return
end if
ls_user_id=GetItemString(11_row,"user_id")
//If the user_id is not the current user then disallow row change
if ls-user-id<>is-user-id then
beep(1)
SetActionCode(1)
return
return
end if
ItemChanged Event
DataWindow ITEMCHANGED事件可以有几种不同的操作:接受前一字段的新值,因有错误而
拒绝接受新值,拒绝新值但是继续其它的处理过程。这些值如下:
0 接受新的数据值。(缺省)
1 拒绝新的数据值。(启动ItemEr-ror事件)
2 拒绝新的数据值但是焦点改变。
在ITEMCHANGED事件中使用SetAction-Code函数可以进行多字段的交叉确认。例如,银行
系统中为确认Account Status是否可以转为Inactive,就需检验Balance字段是否为零:
//ItemChanged Event
Decimal (2) ld_balance //Customer Account Balance
Long ll_currow // Current Row Number
String ls_column_name //The name of the column that changed
String ls_status //Customer Account Status
ll_currow=this.GetRow()
ls_column_name=this.GetColumnName()
CHOOSE CASE ls_column_name
...
...
CASE "STATUS"
ls_status=this.GetText()
//If STATUS is Inactive
IF ls_status= "I" THEN
ld_balance=this.GetItemDecimal (ll_currow,"BALANCE")
IF ld_balance<>0 THEN
//SET AN ERROR
this.SetActionCode(1)
RETURN
ELSE
//ACCERT THE VALUE
this.SetActionCode(0) /* not required since 0 is default */
RETURN
END IF
END IF
END CHOOSE
在程序中,SetActionCode函数不一定要在最后一行,但是由于其他DataWindow函数可能会
重置动作码。为了避免这个问题,一般在SetActionCode后面立即执行Re-turn结束这个程
序段。
在ITEMCHANGED事件中使用SetAc-tionCode函数用途是可以给该字段一个新值,而不是用
户输入的那样。例如:用户将日期输入为星期日,但是我们希望将其改为在此之后的第一
个非休息日。实现这一功能并不像想象的那样简单:
//ItemChanged Event
date ldt_process //process date
long ll_currow // Current Row Number
string ls_column_name // The name of the column that changed
ll_currow=this.GetRow()
ls_column_name=this.GetColumnName()
CHOOSE CASE ls_column_name
...
...
CASE "process_date"
ldt_process=f_get_next_bus_date(date(this.GetText()))
错误 this.SetText(ldt_process)
this.AcceptText()
...
执行上述代码,系统将进入死循环。因为用AcceptText函数改变日期的同时,也触发ITEM
CHANGED事件,只是当前列仍在process-data列上,这样就导致堆栈溢出。因此在ITEMCHA
NGED事件中不能使用Ac-ceptText函数,应使用我们这里介绍的Se-tActionCode这一函数
来完成这一功能:
CASE "process_date"
ldt_process=f_get_next_bus_date(date(this.GetText()))
正确 this.SetItemText(ll_currow,"process_date",ldt_process)//set value in bu
ffer
this.SetActionCode(2) // reject edit control value
RETURN
在Primary!Buffer中将process_date的值置为ldt_process,SetActionCode(2)摒弃用户
在edit控件中输入的值(星期日),并允许改变焦点(没有错误发生)。
ItemError Event
在任何时候,当一个DateWindow列没有通过有效性检验或者这个值在ITEM-CHANGED事件中
被拒绝时,ITEMER-ROR事件启动。如同ITEMCHANGED事件一样,它的动作码也可以设置为接
受或拒绝这个字段的新输入值。它还可以在拒绝新值时,决定是否取消错误信息框的显示
。ITEMERROR事件的动作码可以是:
0 拒绝新的数据值并且显示错误信息;(缺省)
1 拒绝新的数据值而不显示错误信息;
2 接受新的数据值;
3 拒绝新的数据值但是允许改变焦点。
如果我们想要在一特定区域显示一个用户自定义的错误信息来代替Power-Builder本身错
误信息框,我们可以使用SetActionCode来取消标准的信息框。例如,在前面例子中,当收
支差额不是0是0时,我们就可以用这一方法显示一个错误信息:
//ItemError Event
Long 11_Currow /* Current Row Number */
String ls_column_name /* The name of the column that changed */
ll_currow=this.GetRow()
ls_column_name=this.GetColumnName
CHOOSE CASE s_column_name
CASE "status"
MessageBox("Error","Account cannot be changed to Inactive"+ "Balance is not
zero.")
zero.")
this.SetActionCode(1)
RETURN
...
END CHOOSE
在ITEMERROR事件中使用SetAc-tionCode,我们就可以有选择地忽略DataWindow对象的一
个列中输入的有效性规则。例如,在收支差额中,我们有下面这个有效性规则:
Real(GetText())<=10000
客户收支差额不应超过10,000元,如果我们允许使用公司帐户的客户可以超过10,000,我
们可以使用如下方式:
//ItemError Event
CHOOSE CASE ls_column_name
CASE "balance"
// Allow balance over $10,000 on Corportate accounts
IF ld_balance not <=10000 AND ls_type="C"
this.SetActionCode(2)
RETURN
END IF
...
我们也可以像前面ITEMCHANGED事件那样在Prinary!Buffer中拒绝新输入的值并填入新值
,只是在这里将动作码置为3。
DBError Event
在执行了dw.Retrieve,dw.Update()函数或嵌入式SQL语句并发生了一个数据库错误(SQL
Code等于-1)时,触发DBError事件。许多Power-Builder的开发商都在为这种情况设计了
标准的数据库错误信息显示。为了使PowerBuilder不显示缺省的数据库错误信息,我们可
以使用SetActioncode。DBError事件的动作码值如下:
0 显示错误信息。(缺省)
1 不显示错误信息。
例如:
//DBError event
MessageBox("数据库错误","错误值"+string(this.DBErrorCode)+&
"错误信息为:"+this.DBErrorMessage(),StopSign!)
//Supress PB generated DB Error Message.
this.Set ActionCode(1)
return
PrintPage
PRINTPAGE事件是在执行dw.Print()函数之后,数据传送给打印机之前触发。当打印一个
DataWindow时,你可在打印之前设置动作码来跳过一页。PRINT-PAGE事件的动作码如下:
0 不跳过一页;(缺省)
1 跳过一页。
如您打算打印时跳过一页,你可以在中PRINTPAGE编码如下:
//Printpage event
this.SetActionCode(1)
RetrieveRow
RetrieveRow
从数据库服务器中每次接受了一行记录均启动REIRIEVEROW事件。在这个事件中,你可以
设置一动作码来停止检索。下面是RE-TRIEVEROW事件的有效动作码:
0 继续。(缺省)
1 停止检索。
如果一个DataWindow将命中很多行,并且你希望在检索到一定量后停止。你可以在RETRI
EVEROW事件中使用SetActionCode:
//RetrieveRow event
//Instance variable Long il_count
...
IF il_count++> 100 THEN
// Maximum rows retrieved,stip retrieval
this.SetActionCode(1)
RETURN
END IF
当用来给被检索行计数的临时变量il_count的值超过100时,检索将停止。
注意:在RETRIEVEROW事件中存在代码,那么检索每一行都会触发事件,这将降低检索的速
度。
RetrieveStart
RETRIEVESTART事件在dw.Retrieve()函数之后,产生SQL传送给服务器之前触发。
在一些特定场合可能需要在开始一个检索之前停止它。在RetrieveStart事件中的动作码
:
0 继续。(缺省)
0 继续。(缺省)
1 不检索。
例如:我们让一个用户输入检索标准的窗口,在RETRIEVESTART中判断返回行数是否太多,
以决定停止检索并且让用户缩小检索范围。
//Retrieve Start event
Int li_count /*Expected Retrieve Count */
...
//Get count of Rows to be retrieved
...
IF li_count>1000 THEN
MessageBox("Stop","Please narrow your search",stop!)
This.SetActionCode(1)
RETURN
END IF
...
UpdateStart
这一在执行Update()函数之后,产生的修改SQL语句传送给服务器之前触发。
通过设置这一动作码,你可以阻止修改传送给服务器。UPDATESTART事件的动作码如下:
0 继续。(缺省)
1 不修改。
如果你要阻止执行修改语句,在UP-DATESTART事件中使用下列代码:
//UpdateStart event
...
this.SetActionCode(1)
RETURN
...
综 述
在很多情况下,设置动作码是非常有用的。这里的例子,让你对其中几种情况有一个了解
。当你对使用PowerScript编码有了更多的经验后,你会发现SetActionCode是非常有用的
。
--
《列子·汤问》:“夸父不量力,欲追日影,逐之于隅谷之际。渴欲 得饮,赴饮河渭
。河渭不足,将走北饮大泽。未至,道渴而死。”
※ 来源:·哈工大紫丁香 bbs.hit.edu.cn·[FROM: 202.118.229.154]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.272毫秒