[英]FDQuery and OnCalcFields, get the previous line
Delphi 10.3.3 FireDAC:DBGrid / FDQuery / MySQL VCL
大家好,
我有一個包含這些字段的表
----------------------
| id | data |
----------------------
| 1 | 0=A;1=B;2=C |
| 2 | 2=Z |
| 3 | |
| 4 | 0=Y;1=X |
| 5 | |
| 6 | |
每一行數據只代表表中的變化
我希望它顯示在 DBGRID 中:
-----------------------
| id | C0 | C1 | C2 |
-----------------------
| 1 | A | B | C |
| 2 | A | B | Z |
| 3 | A | B | Z |
| 4 | Y | X | Z |
| 5 | Y | X | Z |
| 6 | Y | X | Z |
我現在能做的只有下表:
-----------------------
| id | C0 | C1 | C2 |
-----------------------
| 1 | A | B | C |
| 2 | | | Z |
| 3 | | | |
| 4 | Y | X | |
| 5 | | | |
| 6 | | | |
為了獲得這個結果,我在事件 FDQuery1.BeforeOpen 中創建了額外的列,在事件 OnCreateFields 中,我填充了每一列,但我不知道前一行的內容,
那么,我該如何填寫 DBgrid 中缺少的字段呢? 謝謝弗蘭克
我認為您的意思是OnCalcFields
,而不是OnCreateFields
。
您需要的當然是可能的,無論是服務器端使用例如 SQL 子查詢從前一行派生必要的值,還是使用計算字段的客戶端。 這個答案是關於在客戶端做的。
進行涉及另一個數據集行的客戶端計算的問題是,要做到這一點,您需要能夠在 OnCalcFields 事件期間移動數據集 cursor。 但是,當時,DataSet 將位於 dsCalcFields 或 dsInternalCalc state 中,盡管如此,但您不能輕易移動到數據集中的另一行。 可以這樣做,但需要聲明一個后代數據集 class (TMyFDQuery) 以便您可以訪問必要的SetTempState
以在您從“其他”行中獲取必要的信息后恢復到之前的 state,如果您需要的不僅僅是一個字段,您需要在某個地方臨時存儲這些值。 所以這樣做會很混亂。
更簡潔的方法涉及使用 FireDAC 的數據集和 TClientDataSets 之間的功能相似性。 TClientDatasSets 的優點之一是您可以輕松地在兩個 CDS 之間移動數據集內容,只需執行以下操作
CDS2.Data := CDS1.Data;
FireDAC 數據集可以做同樣的事情,但在任何 FD 數據集類型之間。 所以這是我在你的情況下會做的:
procedure TForm2.FDQuery1AfterOpen(DataSet: TDataSet);
begin
FDQuery1.DisableControls;
try
FDMemTable1.Data := FDQuery1.Data;
FDMemTable1.Open;
finally
FDQuery1.First;
FDQuery1.EnableControls;
end;
end;
FDQuery1.First 是在 FDMemTable 數據可用時強制它重新計算字段(在初始 FDQuery1.Open 期間,當然不能)。
procedure TForm2.FDQuery1CalcFields(DataSet: TDataSet);
begin
if FDMemTable1.Active then begin
if FDMemTable1.Locate('ContactID', FDQuery1.FieldByName('ContactID').AsInteger, []) then begin
FDMemTable1.Prior;
if not FDMemTable1.Bof then begin
// Set FDQuery1's calculated fields that depend on prior row
FDQuery1.FieldByName('PriorRowID').AsInteger := FDMemTable1.FieldByName('ContactID').AsInteger;
end;
end;
end;
end;
在這個例子中,我查詢的數據集有一個ContactID
主鍵,計算的值就是前一行的 ContactID 值。 當然,在現實生活中,使用持久字段變量比繼續調用FieldByName
更有效。
我想另一種可能性可能是使用 CloneCursor 方法來獲取查找 cursor 以訪問“先前”行,但是我自己沒有嘗試過,而且無論如何可能都不可能(CloneCuror 副本中的計算字段會發生什么情況?)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.