- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在下面的 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 的连接或将其设置为非事件状态以保存最后的网格状态时,网格将更改为空白网格。最后一个代码是最好的解决方案还是有更好的方法在过滤工作时显示未过滤的结果?
最佳答案
有几件事即使不是“错误”,也与您的代码不太相符。
您应该使用Next
,不是FindNext
移动到数据集中的下一行。 Next
移动到数据集中的下一行,而 FindNext
移动到与您已经设置的搜索条件相匹配的下一行,例如使用DataSet.SetKey; ...
- 阅读 FindKey
的在线帮助用法。
您不应该尝试使用 For
遍历数据集环形;使用While not FDMemData.Eof do
环形。 Eof
代表“文件结束”,一旦数据集位于最后一行,则返回 true。
您应该调用FDMemTable1.DisableControls
在循环之前和 FDMemTable1.EnableControls
在它之后。这可以防止像 DBGrid 这样的数据库感知控件在循环内更新,否则会在网格更新时减慢循环速度。
除非您有充分的理由不这样做,否则请始终以与设置数据集过滤器相同的方法清除数据集过滤器,否则,如果您忘记过滤器处于事件状态,可能会出现一些非常令人困惑的错误。
尽量避免使用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/
当您有一个 TDBGrid,全行选择,并且始终显示选择(即使没有聚焦时),并且您想要完全由所有者绘制它时,您可以选择已弃用的事件 OnDrawDataCell ,和一个新事件 DrawColumnCe
我正在使用 TDBGrid首次。 我什至没有注意到 Columns对象检查器中的属性,一切都很顺利:网格已填充。 然后我看到了Columns属性(property)并尝试过。当我使用对象昆虫器将项目添
这个问题已经有答案了: Printing a TDBGrid (4 个回答) 已关闭 6 年前。 如何在不安装或下载组件的情况下打印 DBGrid? 或者 如何将 DBGrid 的数据放入 RichE
我有一个名为 myDbGrid 的 TDBGrid,我想在数据库更改(插入/更新/删除)后更新它。如何在不完全重新加载表单的情况下执行此操作? myDbGrid 使用 myDataSource 并使用
我只是尝试使用delphi XE,在此之前我一直是Delphi7的忠实粉丝。 我看到新的 dbgrid 允许使用主题和渐变样式。 我正在使用渐变并设置行选择,它具有用于列标题的渐变开始和结束的属性。
我正在使用 Delphi 2009,我确实需要创建一个可以打印 DBGrid 中所有数据的按钮。我感谢我能得到的所有帮助。 最佳答案 由于它是一个数据库网格,因此您可以使用您拥有的任何报告组件创建报告
我正在将一些软件从 Delphi 5 转换为 Delphi 10.2。 我们有一个 TDBGrid,它链接到一个数据源,该数据源又链接到一个表。所以像这样: TDBGrid.DataSource :=
我想从 TDBGrid 中检索所选行的值,该怎么办? procedure TForm7.Button2Click(Sender: TObject); var i, j: Integ
我想在 TDBGrid 的右下角显示一些东西,但我不想覆盖滚动条。 有确定滚动条是否可见的好方法吗? (以及它们的大小) 最佳答案 可能最好的方法是使用 ClientRect属性,它以自己的坐标给出控
我正在开发一个具有简单数据库的应用程序。所有功能都运行良好,但是当用户从程序中编辑数据库时,其他用户无法立即看到内容。其他用户需要关闭程序并重新打开它才能显示数据及其DBGrid。使用其他计算机上的这
我正在使用连接到 TDataSource 的 TDBGrid。 此 TDataSource 使用 TADOQuery 作为其数据集。 TADOQuery 连接到 Oracle10g 数据库并保存以下查
我编写了一个简单的方法来对 TDBGrid 中的列进行排序。如果 Option.RowSelect 设置为 False,则一切正常,但如果 RowSelect 为 True,则水平位置滚动在排
我有一个小按钮,我想添加到 Delphi TDBGrid 组件的左上角(在标题/标题单元格中)。我可以轻松放置按钮,但现在未处理单击事件。我猜该事件正在被网格捕获。有什么办法可以强制这个特定事件转到按
如何限制 TDBGrid 中就地编辑器的最大文本长度? (德尔福柏林) 数据类型为浮点型。 最佳答案 TDBGrid 中的就地编辑器将通过调用更新其内容 procedure TInplaceEdit.
我的项目中有一个 TDbGrid,并且我试图在每次更改所选行时触发一个事件。行中的任何更改都已经更新了链接到同一数据源的所有数据感知控件,但还需要进行其他更改,我需要一个事件处理程序。 我认为 OnC
在下面的代码中,我们对某些选定的行进行一些操作(不是删除)。 但是,有时,完成后,顶部选定的行会滚动,使其显示在网格下方 1/2 处。有没有办法避免这种滚动? (如果我的遍历下面选定行的代码由于某些不
我有一个带有预定义列的 TDBGrid,但我无法获得正确的宽度。我可以在表单设计器中弄乱列的宽度属性,并使宽度在设计时看起来恰到好处,但在运行时,无论出于何种原因,列往往会明显更宽,最终会出现滚动条在
有一个包含一些数字列的网格,需要为每个列实现一个聚合(总和或计数)并将其显示在相应的列下。 我知道一些套件(DevExpress 或其他)已经“默认”实现。但是有办法使用默认控件或 JVCL 来实现吗
我想在给定 VisibleRows 参数的情况下调整 TDBGrid 高度。网格可能有也可能没有标题。 假设我从数据库中选择 100 条记录,但我希望调整网格高度以显示前 10 行(使它们可见)。数据
我的 dbgrid 中有一个基于查找字段的列。 问题在于最终用户无法为该字段设置空白值 - 他们只能从查找表中选择值。 如何允许最终用户删除或“空白”列的值? 最佳答案 在相应的 TDBGrid Ke
我是一名优秀的程序员,十分优秀!