自动计算字段引起死循环的问题
记录集有三个字段 price单价、amout数量、charge金额,记录集的locktype属性为ltBatchOptimistic
单价或数量改变时,自动计算金额 charge:=amount*price;
金额改变时,自动计算单价 price:=charge/amount;
问题:单价或数量改变时,计算出金额,给金额赋值,这时候,金额发生改变,触发金额自段的onchange事件,在onchange事件中开始计算单价,然后给单价赋值,又触发单价的onchange事件(虽然这时赋给单价的值跟上次输入的值一致,但确实引发了单价的onchange事件),这样就导致了死循环。
大家有什么好的解决方法呢?
- Delphi(Pascal) code
procedure TForm1.qry1priceChange(Sender: TField);var price,amount,charger:Real;begin price:=Sender.DataSet.FieldByName('price').AsFloat; amount:=Sender.DataSet.FieldByName('amount').AsFloat; charge:=price*amount; if charge<>0 then Sender.DataSet.FieldByName('charge').AsFloat:=charge;end;procedure TForm1.qry1amountChange(Sender: TField);var price,amount,charger:Real;begin price:=Sender.DataSet.FieldByName('price').AsFloat; amount:=Sender.DataSet.FieldByName('amount').AsFloat; charge:=price*amount; if charge<>0 then Sender.DataSet.FieldByName('charge').AsFloat:=charge;end;procedure TForm1.qry1chargeChange(Sender: TField);var price,amount,charger:Real;begin amount:=Sender.DataSet.FieldByName('amount').AsFloat; charge:=Sender.DataSet.FieldByName('charge').AsFloat; if amount<>0 then price:=charge/amount else exit; Sender.DataSet.FieldByName('price').AsFloat:=price;end;[解决办法]
定义一个bo:Boolean全局变量做标记
当前onChange事件赋值前为bo:=True,赋值后bo:=False
其它onChange事件判断是bo,为True的时候就跳过
或者这样,赋值前设置其它的onChange无效,赋值后变回来,如在price的Change事件:
//bo:=True;
qry1.FieldByName('charge').onChange:=nil;
..赋值..
qry1.FieldByName('charge').onChange:=qry1chargeChange;
//bo:=False;
[解决办法]
高手出手了呀
[解决办法]
简单的说,在onChange事件中加判断,不是每次Change就触发代码即可。
嘿嘿。站着说话不腰疼,可耻的飘过。。。
[解决办法]
又见旺旺贝贝呀,在ONEXIT事件中添加这些代码是否也可行呢?
ONEXIT比较值是否已改变或者不比较也行
[解决办法]
学习中
[解决办法]
统一在DATASOURCE的ONSTATECHANGE事件中做也应该可以,但是还是得定义全局变量,
[解决办法]
数据库侧写触发器,呵呵
[解决办法]
加上是否相同的判断(相同则不需要修改)
if (charge<>0) and (Sender.DataSet.FieldByName('charge').AsFloat<>charge) then
Sender.DataSet.FieldByName('charge').AsFloat:=charge;
3个地方都要加
另外要注意浮点的不等于比较
[解决办法]
[解决办法]