gpt4 book ai didi

delphi - 如何内部处理过滤后的 tDataSet 记录,使其不显示在 tDBGrid 结果上

转载 作者:行者123 更新时间:2023-12-03 02:37:36 30 4
gpt4 key购买 nike

在下面的 tFDMemTable 中,我尝试对 ID 字段以字母 A、A1、A2 开头的记录的值求和,结果应为 4。

type
TForm1 = class(TForm)
FDMemTable1: TFDMemTable;
DBGrid1: TDBGrid;
DataSource1: TDataSource;
Button1: TButton;
Button2: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
_FieldDef: TFieldDef;
begin
_FieldDef := FDMemTable1.FieldDefs.AddFieldDef;

_FieldDef.Name := 'ID';
_FieldDef.DataType := ftString;
_FieldDef.Size := 5;

_FieldDef := FDMemTable1.FieldDefs.AddFieldDef;

_FieldDef.Name :='value';
_FieldDef.DataType := ftInteger;

FDMemTable1.CreateDataSet;

FDMemTable1.Append;

FDMemTable1.FieldValues['ID'] := 'A1';
FDMemTable1.FieldValues['value'] := 1;

FDMemTable1.Append;

FDMemTable1.FieldValues['ID'] := 'B1';
FDMemTable1.FieldValues['value'] := 2;

FDMemTable1.Append;

FDMemTable1.FieldValues['ID'] := 'A2';
FDMemTable1.FieldValues['value'] := 3;

FDMemTable1.Append;

FDMemTable1.FieldValues['ID'] := 'B2';
FDMemTable1.FieldValues['value'] := 4;
end;

我编写了以下代码,但它按过滤更改了 tDBGrid。我想要的只是一个内部流程,tDBGrid 应该保持不变。

procedure TForm1.Button1Click(Sender: TObject);
var
_ValueSum: Integer;
i: Integer;
begin
FDMemTable1.Filter := 'ID like ' + QuotedStr('A%');

FDMemTable1.Filtered := True;

_ValueSum := 0;

FDMemTable1.FindFirst;

for i := 0 to FDMemTable1.RecordCount - 1 do
begin
_ValueSum := _ValueSum + FDMemTable1.FieldValues['value'];

FDMemTable1.FindNext;
end;

Button1.Caption := IntToStr(_ValueSum);
end;

我知道 tDataSet.Locate 不允许进行下一个搜索,我尝试了这样的原始方法。它工作正常,但看起来有点愚蠢。

procedure TForm1.Button2Click(Sender: TObject);
var
_ValueSum: Integer;
i: Integer;
begin
_ValueSum := 0;

FDMemTable1.First;

for i := 0 to FDMemTable1.RecordCount do
begin
if Copy(FDMemTable1.FieldValues['ID'], 1, 1) = 'A' then
begin
_ValueSum := _ValueSum + FDMemTable1.FieldValues['value'];
end;

FDMemTable1.FindNext;
end;

Button2.Caption := IntToStr(_ValueSum);
end;

当我在过滤之前断开 tFDMemTable 和 tDBGrid 的连接或将其设置为非事件状态以保存最后的网格状态时,网格将更改为空白网格。最后一个代码是最好的解决方案还是有更好的方法在过滤工作时显示未过滤的结果?

最佳答案

有几件事即使不是“错误”,也与您的代码不太相符。

  1. 您应该使用Next ,不是FindNext移动到数据集中的下一行。 Next移动到数据集中的下一行,而 FindNext移动到与您已经设置的搜索条件相匹配的下一行,例如使用DataSet.SetKey; ... - 阅读 FindKey 的在线帮助用法。

  2. 您不应该尝试使用 For 遍历数据集环形;使用While not FDMemData.Eof do环形。 Eof代表“文件结束”,一旦数据集位于最后一行,则返回 true。

  3. 您应该调用FDMemTable1.DisableControls在循环之前和 FDMemTable1.EnableControls在它之后。这可以防止像 DBGrid 这样的数据库感知控件在循环内更新,否则会在网格更新时减慢循环速度。

  4. 除非您有充分的理由不这样做,否则请始终以与设置数据集过滤器相同的方法清除数据集过滤器,否则,如果您忘记过滤器处于事件状态,可能会出现一些非常令人困惑的错误。

  5. 尽量避免使用RecordCount当你绝对不需要的时候。根据您使用的 RDMS,它可能会在服务器甚至网络上造成大量本可避免的处理开销(因为对于某些服务器类型,它会导致将整个数据集检索到客户端)。

    <

将第一个循环更改为

procedure TForm1.Button1Click(Sender: TObject);
var
_ValueSum : Integer;
begin
_ValueSum := 0;

FDMemTable1.Filter := 'ID like ' + QuotedStr('A%');

try
FDMemTable1.DisableControls;
FDMemTable1.First;
while not FDMemTable1.Eof do begin
_ValueSum:= _ValueSum + FDMemTable1.FieldByName('Value').AsInteger;
FDMemTable1.Next;
end
finally
FDMemTable1.Filter := '';
FDMemTable1.Filtered := False;
FDMemTable1.EnableControls;
end;
Button1.Caption := IntToStr(_ValueSum);
end;

如果您这样做,则根本不需要 Button2Click 方法。

正如评论中所述,您可以使用 TBookMark 在循环之前记录您在数据集中的位置,然后返回到它,如下所示

var
_ValueSum : Integer;
BM : TBookMark;
begin
_ValueSum := 0;

BM := FDMemTable.GetBookMark;

FDMemTable1.Filter := 'ID like ' + QuotedStr('A%');

try
[etc]
finally
FDMemTable1.Filter := '';
FDMemTable1.Filtered := False;
FDMemTable1.GotoBookMark(BM);
FDMemTable1.FeeBookMark(BM);
FDMemTable1.EnableControls;
end;

顺便说一句,您可以使用 InsertRecord 来节省一些打字时间并获得更简洁的代码。方法如

FDMemTable1.InsertRecord(['A1', 1]);
FDMemTable1.InsertRecord(['B1', 2]);
FDMemTable1.InsertRecord(['A2', 3]);
FDMemTable1.InsertRecord(['B2', 4]);

顺便说一句#2:使用FindKey的时间是在您设置要查找的 key 后,通过调用 SetKey 使用然后设置键值。

对于数据集的普通导航,请使用标准导航方法,例如Next , Prior , First , Last , MoveBy等等

关于delphi - 如何内部处理过滤后的 tDataSet 记录,使其不显示在 tDBGrid 结果上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56099447/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com