Delphi TClientDataSet&;删除记录会导致某些记录在while循环中被遍历两次(如果使用索引)

Delphi TClientDataSet&;删除记录会导致某些记录在while循环中被遍历两次(如果使用索引),delphi,while-loop,delphi-xe4,delete-row,tclientdataset,Delphi,While Loop,Delphi Xe4,Delete Row,Tclientdataset,我有以下代码遍历TClientDataSet中的所有数据,目的是删除除DocKey=20381之外的所有记录 但在下面的代码中,您会注意到DocKey=20381的记录被遍历了两次(遍历次数=6,假设是5次,因为我们在TClientDataSet中只有5条记录) 如果我们启用此行->D.IndexFieldNames:='docky',则数据将正确遍历。我可以知道这是Delphi的bug吗?或者除了使用IndexFieldNames之外,还有什么方法可以解决这个问题 var D: TClie

我有以下代码遍历
TClientDataSet
中的所有数据,目的是删除除
DocKey=20381
之外的所有记录

但在下面的代码中,您会注意到DocKey=20381的记录被遍历了两次(遍历次数=6,假设是5次,因为我们在
TClientDataSet
中只有5条记录)

如果我们启用此行->
D.IndexFieldNames:='docky'
,则数据将正确遍历。我可以知道这是Delphi的bug吗?或者除了使用
IndexFieldNames
之外,还有什么方法可以解决这个问题

var
  D: TClientDataSet;
begin
  D := TClientDataSet.Create(Self);
  with D do begin
    FieldDefs.Add('DocKey', ftInteger);
    CreateDataSet;
    AppendRecord([20157]);
    AppendRecord([20162]);
    AppendRecord([20381]);
    AppendRecord([20372]);
    AppendRecord([20377]);
  end;
  // D.IndexFieldNames := 'DocKey';

  D.First;
  while not D.Eof do begin
    if D.Fields[0].AsInteger = 20381 then
      D.Next
    else
      D.Delete;
  end;
end;

此行为符合设计和规范要求

如果删除的记录是数据集中的最后一条记录,则前一条记录将成为当前记录

不被删除的记录将成为数据集中的最后一条记录,因此在最后一条记录上不存在删除,而不是该行为

20157 -> delete 20162 -> delete 20372 -> delete 20377 -> delete 20381 -> next
谢谢你的回复。是因为编写for循环代码的方法不正确,还是为了避免出现问题,有更好的编写方法?我是否应该首先将书签添加到TList(用于删除那些记录)中,而不是直接调用TClientDataSet。在for循环中删除,然后根据TList删除记录。为什么这是一个问题?我实际上希望数据集像20377->Delete(last record->next(no more record)->eof这样遍历下一条记录但是你的期望是唯一的问题吗?它只发生一次,所有记录都按预期删除。我没有得到真正的问题谢谢你的更新。我有一些代码遍历数据集来执行算术计算,每个记录只遍历一次而不是两次,以避免错误的计算。同时,如果详细数据集.recordcount=0(主数据集和详细数据集链接),则删除不需要的主记录
D.IndexFieldNames := 'DocKey';
20157 -> delete 20162 -> delete 20372 -> delete 20377 -> delete 20381 -> next
var 
  D: TClientDataSet;
  LRecNo : Integer;
begin
  D := TClientDataSet.Create(Self);
  with D do begin
    FieldDefs.Add('DocKey', ftInteger);
    CreateDataSet;
    AppendRecord([20157]);
    AppendRecord([20162]);
    AppendRecord([20381]);
    AppendRecord([20372]);
    AppendRecord([20377]);
  end;
  // D.IndexFieldNames := 'DocKey';

  D.First;
  while not D.Eof do 
  begin

    LRecNo := D.RecNo;

    if D.Fields[0].AsInteger = 20381 then
      D.Next
    else
      D.Delete;

    if LRecNo > D.RecNo then
      Break;

  end;
end;