论PB的itemchange事件

     最近在维护公司的银行结算系统.有客户反应在输入利率直接保存时,利息没有保存进去。经认真排查,是itemchange事件没有被触发,PB帮助里说的很清楚,当直接从数据窗口某个编辑域离开,跳到数据窗口之外某个控件时itemchange事件不会被触发。另外,以前同事写的代码也存在一些问题。
 原itemchange事件代码如下:
Choose Case dwo.name
 Case "contract_amt","interest_rate","contract_value","deposit_maturity"
       Post Event ue_setinterest()
 Case "contract_curr"
      If data = "HKD" or data = "GBP" Then
         object.interest_mark[row] = "E"
     Else
        object.interest_mark[row] = "B"
     End If
End Choose 

这事件的post Event是不安全的用法。建议在itemchange事件中尽量不用,而采用triggerevent的方式。如果直接点保存,即使你在后面的保存按钮里写了accepttext事件,也有可能造成保存完毕后,才执行 ue_setinterest()自定义事件,以致数据不对。

修正如下:

Choose Case dwo.name
 Case "contract_amt","interest_rate","contract_value","deposit_maturity"
       Event ue_setinterest()
 Case "contract_curr"
      If data = "HKD" or data = "GBP" Then
         object.interest_mark[row] = "E"
     Else
        object.interest_mark[row] = "B"
     End If
End Choose 

再来看原来ue_setinterest()事件代码:
Dec{2} lr_amt,lr_interest
Dec{8} lr_rate
Date   ldt_contract,ldt_maturity
Integer li_days

li_days = idw_mm.Object.rate_days[1]
ldt_contract = Date(idw_mm.GetItemDateTime(1,"contract_value"))
ldt_maturity = Date(idw_mm.GetItemDateTime(1,"deposit_maturity"))
If idw_mm.GetColumnName() = "interest_rate" Then
 lr_rate = Dec(idw_mm.GetText())
Else
 lr_rate = Dec(idw_mm.object.interest_rate[1])
End If
lr_amt = idw_mm.GetItemDecimal(1,"contract_amt")

If Not isnull(lr_amt) And lr_amt <> 0 And Not isnull(ldt_contract) And &
 Not isnull(ldt_maturity) Then
 lr_interest = Round((lr_rate * lr_amt * DaysAfter(ldt_contract, ldt_maturity) ) / (li_days * 100),&
      Gnv_app.Inv_services.of_getfraction(idw_mm.Object.contract_curr[1]))
 idw_mm.SetItem(1,"interest_amt",lr_interest)
End If

Return
这个算利息的函数也存在一些问题。参与计算的值也有可能是旧的数据。修正如下:

Dec{2} lr_amt,lr_interest
Dec{8} lr_rate
Date   ldt_contract,ldt_maturity
Integer li_days


li_days = idw_mm.Object.rate_days[1]
If idw_mm.GetColumnName() = "contract_value" Then
 ldt_contract = Date(BLOB(idw_mm.gettext()))
else
 ldt_contract = Date(idw_mm.GetItemDateTime(1,"contract_value"))
end if
If idw_mm.GetColumnName() = "deposit_maturity" Then
 ldt_maturity = Date(BLOB(idw_mm.gettext()))
Else
 ldt_maturity = Date(idw_mm.GetItemDateTime(1,"deposit_maturity"))
end if

If idw_mm.GetColumnName() = "interest_rate" Then
 lr_rate = Dec(idw_mm.GetText())
Else
 lr_rate = Dec(idw_mm.object.interest_rate[1])
End If
If idw_mm.GetColumnName() = "contract_amt" Then
 lr_amt = dec(idw_mm.GetText())
Else
 lr_amt = idw_mm.GetItemDecimal(1,"contract_amt")
end if

If Not isnull(lr_amt) And lr_amt <> 0 And Not isnull(ldt_contract) And &
 Not isnull(ldt_maturity) Then
 lr_interest = Round((lr_rate * lr_amt * DaysAfter(ldt_contract, ldt_maturity) ) / (li_days * 100),&
      Gnv_app.Inv_services.of_getfraction(idw_mm.Object.contract_curr[1]))
 idw_mm.SetItem(1,"interest_amt",lr_interest)

End If

Return

注意上面的日期转换Date(BLOB(idw_mm.gettext())),用的是blob函数,挺有意思的。

最后一步,数据在保存时一定要先accepttext()。这样即使直接离开数据窗口,也能先执行一遍itemchange事件,而不会造成利息字段没计算为空。accepttext()事件可以写在datawindow的losefocuse事件中。

展开阅读全文

没有更多推荐了,返回首页