在搜索如何循环遍历 TDataSet
时,我发现了
使用 Eof 和 Bof 属性。但是,我发现当通过
Eof
检索最后一条记录时,Next()
变为 true,而不是在检索不存在的记录后,如文档所示。数据库是使用 FireDAC 的 SQLite。
基本上,这缺少最后一条记录:
dataset->Filter = _D("MyFieldToSetDefaultValue is NULL");
dataset->Filtered = true;
dataset->First();
while (!dataset->Eof) {
dataset->Edit();
// ...
dataset->Post();
dataset->Next();
}
// oops - if there were 3 records the above loop only handled 2 of them, if I check
// the record returned after Next() it is the last record, only Eof is now true?
这有效(即使只存在 1 条记录):
dataset->Filter = _D("MyFieldToSetDefaultValue is NULL");
dataset->Filtered = true;
dataset->First();
bool eof = dataset->Eof;
while (!eof) {
dataset->Edit();
// ...
dataset->Post();
eof = dataset->Eof;
dataset->Next();
}
更新1:
好吧,这变得更有趣了。这有效:
dataset->Filter = _D("MyFieldToSetDefaultValue is NULL");
dataset->Filtered = true;
dataset->First();
while (!dataset->Eof) {
dataset->Next();
}
我注意到的一件事是处理记录的顺序与上面的不同。上面的内容按字母顺序排列,这就是网格当前排序的顺序。此过程在添加了多个记录的导入例程之后运行,因此它会按照网格中的顺序在最后一条记录上报告
Eof
,但是当使用 Edit()
/ Post()
时,它的顺序是不同的。换句话说,它添加了 3 项:
New eAcc Net
当它在不起作用的循环中处理它们时,它的顺序是:
eAcc New Net
在处理完
New
记录后,Eof
报告为true,它将被排序。
那么,在禁用控件之前我可能需要做一些事情,或者延迟?还有其他人遇到过这个吗?你怎么处理?
更新2:
如果我只是设置
dataset->Filtered = false
,它就会按预期工作。我宁愿使用过滤器,也不愿处理每条记录并以这种方式检查字段。
在我看来,也许是因为我修复的条件不再存在,它对
Eof
是什么感到困惑,因为过滤器排除了它?也许只是一遍又一遍地打电话First()
?
更新3:
是的,看起来这可行,但是有更好的方法吗?
dataset->Filter = _D("MyFieldToSetDefaultValue is NULL");
dataset->Filtered = true;
dataset->First();
while (!dataset->Eof) {
dataset->Edit();
// ...
dataset->Post();
dataset->First(); // call first again instead of next since updated record no longer in filter.
}
如果编辑记录的操作是从当前过滤器中删除记录,那么当编辑的记录被删除时,数据集中的下一条记录可能会成为新的活动记录。这在
Filtered
属性的文档中进行了说明:
注意:启用过滤后,用户对记录的编辑可能意味着该记录不再满足过滤器的测试条件。当过滤器生效时,下次尝试从数据集中读取记录时,该记录将不可见。如果发生这种情况,下一条通过过滤条件的记录将成为活动记录。
因此,也许尝试根本不在循环内寻找数据集
dataset->Filter = _D("MyFieldToSetDefaultValue is NULL");
dataset->Filtered = true;
dataset->First();
while (!dataset->Eof) {
dataset->Edit();
// ...
dataset->Post(); // active record is removed from the filter
// so, do not call First() or Next() here!
}