Mysql FDQuery和OnCalcFields,获取上一行

Mysql FDQuery和OnCalcFields,获取上一行,mysql,delphi,firedac,Mysql,Delphi,Firedac,德尔菲法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 | |

德尔菲法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中创建了其他列 在EventOnCreateFields中,我填充每一列,但不知道前一行的内容

那么,如何填写DBgrid中缺少的字段呢? 谢谢
弗兰克

我想你的意思是
oncalfields
,而不是
OnCreateFields

你需要什么 这当然是可能的,通过从前面的 使用SQL子查询的行或使用计算字段的客户端。这个答案是关于这样做的 客户端

涉及另一个数据集行的客户端计算的问题是 为此,您需要能够在OnCalcFields事件期间移动数据集光标。但是,此时,数据集将处于dsCalcFields或dsInternalCalc状态 而且,尽管如此,您不能轻松地移动到数据集中的另一行。这是可能的,但是 需要声明子数据集类(TMyFDQuery),以便可以访问
SetTempState
从“其他”中获取必要信息后,必须恢复到先前的状态 行,并且,如果需要涉及多个字段,则需要在某个位置临时存储这些值。 所以这样做会让事情变得一团糟

更干净的方法是使用FireDAC数据集和TclientDataSet之间的功能相似性。 TclientDataSet的一个很好的特性是,您可以轻松地在两个数据集之间移动数据集内容 简单地做两件事

CDS2.Data := CDS1.Data;
FireDAC数据集也可以使用相同的技巧,但是在任何FD数据集类型之间。这就是我在你家里要做的 情况:

  • 将FDMemTable添加到表单/datamodule中,并在FDQuery的AfterOpen事件中将查询数据复制到其中,如 这:
  • FDQuery1.首先是在FDMemTable数据可用后强制它重新执行其计算字段 (在最初的FDQuery1.Open期间,当然不能打开)

  • 在FDQuery的OnCalcFields事件中,使用这样的代码以计算字段的 从上一行拾取的值上的值(如果有,当然是第一行 行不能有“前一行”:
  • 在本例中,我查询的数据集有一个
    ContactID
    主键,计算的值只是上一行的ContactID值。在现实生活中,当然是这样 使用持久字段变量比一直调用
    FieldByName
    更有效

    我想另一种可能是使用CloneCursor方法来获取查找游标 访问“Previor”行,但我自己没有尝试过,而且可能无论如何都不可能
    (克隆库副本中的计算字段会发生什么情况?。

    您可以使用
    TStringGrid
    。第一行是否始终包含所有状态?您需要编辑或添加行吗?Olivier:我已经尝试使用TStringGrid,但更新(5次)需要更多时间。sddk:第一行并不总是包含所有状态。我不需要编辑或添加行,只需显示它。您所说的“更多时间更新”是什么意思?要显示网格?不应该。您有多少行?非常感谢您的完整回答。我使用FDmemTable做了一些测试,这似乎就是解决方案。我现在需要将其集成到我的应用程序中。再次感谢!很乐意帮忙。一旦你完成了整合,如果你能接受这个答案(点击左边的勾号图标),那就太好了。
    procedure TForm2.FDQuery1AfterOpen(DataSet: TDataSet);
    begin
      FDQuery1.DisableControls;
      try
        FDMemTable1.Data := FDQuery1.Data;
        FDMemTable1.Open;
      finally
        FDQuery1.First;
        FDQuery1.EnableControls;
      end;
    end;
    
    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;