2011-01-24 30 views
0

我有一個DBGrid,我試圖做一個計費表,但有時它不做計算。我怎樣才能避免呢?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; 

回答

2

實現計算的更好方法實際上是將計算移動到網格鏈接到的TTable組件。 Total字段實際上不應該是數據庫中的字段,而應該是基於來自其他字段值的計算字段。只需使用表格的字段編輯器添加一個額外的字段,輸入字段名稱Total,選擇正確的數據類型,然後選擇字段類型爲Calculated。單擊確定,然後添加類似的代碼,這對錶的OnCalcField事件:

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

一般的經驗法則是計算的值不應該保存到數據庫中,除非真的有必要。最好將它們作爲計算字段添加到數據集中,然後將網格鏈接到數據集。所有計算的字段將顯示在網格中,每行將根據該行的值顯示正確的計算值。

1

我覺得你混合業務邏輯(如總計算)與用戶交互邏輯(像一些表格列失去焦點的情況下),這就是你的應用程序的不穩定行爲的根源。

看起來你甚至都不知道它在哪裏發生,哪裏沒有發生。

考慮使用Field的事件(例如OnChange事件)來執行這種計算。

如果您使用具有聚合功能的數據集(如TClientDataSet),那麼您很幸運,因爲您只需要declare what you want in a TAggregateField,而忘記了「手動」進行計算。

不是你的問題,但 ...小心你使用try /終於也......例如,在該位的代碼的方式:

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

注意,如果由於某些原因try和finally子句之間的界限發生異常,變量tot將會有一個未定義的值(在本例中爲前一個賦值的結果),所以對Torcamen_SUB.total字段的賦值將是錯誤的,之後所有。我不確定它是否真的是你想要的。

+0

塔克你是對的你說的是對的。我會重新啓動這個過程謝謝。 – 2011-01-25 11:38:55