数据库网格计算

发布于 2024-10-14 05:33:26 字数 914 浏览 6 评论 0原文

我有一个 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;

I have a DBGrid and I´m trying to do a billing sheet but sometimes it doesn't do the calculations. How can I avoid that??

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

脸赞 2024-10-21 05:33:26

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

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

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

The better way to implement calculations is actually to move the calculation to your TTable component that the grid is linked to. The Total field shouldn't actually be a field in the database since but rather a calculated field based on values from other fields. Simply add an extra field using the field editor of the table, type in the field name Total, select the correct datatype and then select the field type as Calculated. Click Ok and then add code similar to this for the OnCalcField event of the table:

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) ;

A general rule of thumb is that calculated values shouldn't be saved to the database unless really really necessary. It's best to simply add them as calculated fields to the dataset and then link the grid to the dataset. All calculated fields will then be displayed in the grid and each row will show the correct calculated value based on the values for that row.

还如梦归 2024-10-21 05:33:26

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

看起来甚至您都不知道它在哪里发生以及在哪里不发生。

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

如果您使用具有聚合功能的数据集(例如 TClientDataSet),那么您很幸运,因为您只需声明您想要的内容在 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 字段的赋值毕竟是错误的。我不确定这是否真的是你想要的。

I think you're mixing a business logic (like calculating a total) with User Interaction logic (like the event on which some grid column loses the focus) and that's the source of the erratic behavior of your application.

Looks like not even you know where it happens and where it doesn't happen.

Consider using the Field's events (for example, OnChange event) to perform that kind of calculations.

Lucky you if you're using a dataset with aggregation capabilities (like TClientDataSet), because you can just declare what you want in a TAggregateField and forget about doing calculations "by hand".

Not your question but... be careful with the way you're using try/finally also... for example, in this bit of code:

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

be aware that if for some reason an exception occurs on the line between the try and finally clauses, the variable tot will have an undefined value (in this case, the result of the previous assignment), so the Assignment to the Torcamen_SUB.total field will be wrong, after all. I'm not sure if it is really what you want.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文