【问题标题】:Dbgrid calculationDbgrid 计算
【发布时间】:2011-06-14 20:21:32
【问题描述】:

我有一个 DBGrid,我正在尝试做一个帐单,但有时它不做计算。我怎样才能避免这种情况?

procedure TOrcamentos.DBGridEh1ColExit(Sender: TObject);
var
  percent: double;
  Unid: double;
  tot: currency;
  vaz: string;
begin
  if Dorcamen_SUB.DataSet.State in [dsEdit, dsInsert] then
    try  
      Dorcamen_SUB.DataSet.Post;
    finally
      vaz := DBGridEh1.Columns[3].Field.text;
      if (vaz<> '') then
        try
          Torcamen_SUB.Edit;
          Unid := (Torcamen_SUB.FieldByName('QT').AsFloat);
          tot := (Torcamen_SUB.FieldByName('Precovenda').AsFloat);
          percent := (Torcamen_SUB.FieldByName('Desconto').AsFloat);
          try
            tot := tot+(tot * percent)/ 100;
          finally
            Torcamen_SUB.FieldByName('Total').AsFloat := unid*tot;
            Torcamen_SUB.Post;
            Orcamentos.TotalExecute(self);
          end;
        except
        end;
    end;
end;

【问题讨论】:

    标签: delphi dbgrid


    【解决方案1】:

    实现计算的更好方法实际上是将计算移动到网格链接到的 TTable 组件中。 Total 字段实际上不应该是数据库中的字段,而是基于其他字段值的计算字段。只需使用表格的字段编辑器添加一个额外的字段,输入字段名称 Total,选择正确的数据类型,然后选择字段类型作为计算。单击确定,然后为表的 OnCalcField 事件添加类似的代码:

    Torcamen_SUB.FieldByName('Total').AsFloat := Torcamen_SUB.FieldByName('QT').AsFloat * ( Torcamen_SUB.FieldByName('Precovenda').AsFloat + (Torcamen_SUB.FieldByName('Precovenda').AsFloat * Torcamen_SUB.FieldByName('Desconto').AsFloat)/100) ;

    一般的经验法则是,除非确实有必要,否则不应将计算值保存到数据库中。最好将它们作为计算字段简单地添加到数据集,然后将网格链接到数据集。然后所有计算字段将显示在网格中,每行将根据该行的值显示正确的计算值。

    【讨论】:

      【解决方案2】:

      我认为您将业务逻辑(例如计算总数)与用户交互逻辑(例如某些网格列失去焦点的事件)混合在一起,这就是您的应用程序行为不稳定的根源。

      看起来你甚至都不知道它在哪里发生,在哪里没有发生。

      考虑使用字段的事件(例如,OnChange 事件)来执行这种计算。

      如果您使用的是具有聚合功能的数据集(如 TClientDataSet),您会很幸运,因为您只需 declare what you want in a TAggregateField 就可以忘记“手动”进行计算。

      不是您的问题,但是...请注意您使用 try/finally 的方式...例如,在这段代码中:

      try
        tot := tot+(tot * percent)/ 100;
      finally
        Torcamen_SUB.FieldByName('Total').AsFloat := unid*tot;
        //other things
      end;
      

      请注意,如果由于某种原因在 try 和 finally 子句之间的行发生异常,则变量 tot 将具有未定义的值(在这种情况下,是先前赋值的结果),因此对 Torcamen_SUB 的赋值毕竟,.total 字段是错误的。我不确定它是否真的是你想要的。

      【讨论】:

      • Thak 你说得对。我会重新制定这个过程,谢谢。
      • 我正在使用 Mdb。数据库,当我想制作一个 TAggregateField 时,它确实让我像在链接中那样做。有办法吗?
      • @ml 你在使用 ClientDataSets 吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-01
      • 1970-01-01
      相关资源
      最近更新 更多