Francisco Thiago
Francisco Thiago

Reputation: 1

TFDMemTable lost/clearing data after filtering

I have created a FDMemTable with following structure:

Cds_NaMenu := TFDMemTable.Create(nil);
Cds_NaMenu.FieldDefs.Add('ID', ftInteger);
Cds_NaMenu.FieldDefs.Add('MN_TELA_CODIGO', ftInteger);
Cds_NaMenu.FieldDefs.Add('MN_MENU_PESQUISA', ftString, 500);
Cds_NaMenu.FieldDefs.Add('DISPONIBILIDADE', ftInteger);
Cds_NaMenu.IndexDefs.Add('Ordem', 'MN_TELA_CODIGO', []);
Cds_NaMenu.CreateDataSet;
Cds_NaMenu.LogChanges := False;
Cds_NaMenu.IndexName := 'Ordem';

I put data in TFDMemTable like this:

Cds_NaMenu.Append;
Cds_NaMenu.FieldByName('DISPONIBILIDADE').AsInteger := 1;
Cds_NaMenu.Post;

Well... The problem ocurrs when a set filtered property to True and back to False. The RecordCount property goes to 0; None data has found in, even I use saveToFile procedure. Aparently the data was losted.

_recCount := Cds_NaMenu.RecordCount; // Result = 867;
Cds_NaMenu.Filter := 'DISPONIBILIDADE=1 AND MN_MENU_PESQUISA like ' + QuotedStr('%' + sTexto + '%');
Cds_NaMenu.Filtered := True;
_recCount := Cds_NaMenu.RecordCount; // Result = 0;
Cds_NaMenu.Filtered := False;
Cds_NaMenu.Filter := '';
_recCount := Cds_NaMenu.RecordCount; // Result = 0;

PS: With ClientDataSet, this code works perfectly

Upvotes: 0

Views: 3867

Answers (2)

Victoria
Victoria

Reputation: 7912

If you're working with a pure memory table, there should not be any problem to query record count by the RecordCount property. Maybe you expect having NULL and empty value records included in a filtered view when having filter Value LIKE '%%', but it's not so. When having dataset like this:

ID | Value
1  | NULL
2  | ''
3  | 'Some text'

And applying filter like this:

var
  S: string;
begin
  S := '';
  FDMemTable.Filtered := False;
  FDMemTable.Filter := 'Value LIKE ' + QuotedStr('%' + S + '%');
  FDMemTable.Filtered := True;
  { ← FDMemTable.RecordCount should be 1 here for the above dataset }
end;

The empty and NULL value records should not be included in the view. Here is a short proof:

var
  S: string;
  MemTable: TFDMemTable;
begin
  MemTable := TFDMemTable.Create(nil);
  try
    MemTable.FieldDefs.Add('ID', ftInteger);
    MemTable.FieldDefs.Add('Value', ftString, 500);
    MemTable.IndexDefs.Add('PK_ID', 'ID', [ixPrimary]);
    MemTable.CreateDataSet;

    MemTable.AppendRecord([1, NULL]);
    MemTable.AppendRecord([2, '']);
    MemTable.AppendRecord([3, 'Some text']);

    S := '';
    MemTable.Filtered := False;
    MemTable.Filter := 'Value LIKE ' + QuotedStr('%' + S + '%');

    ShowMessage(Format('Total count: %d', [MemTable.RecordCount])); { ← should be 3 }
    MemTable.Filtered := True;
    ShowMessage(Format('Filtered count: %d', [MemTable.RecordCount])); { ← should be 1 }
    MemTable.Filtered := False;
    ShowMessage(Format('Total count: %d', [MemTable.RecordCount])); { ← should be 3 }
  finally
    MemTable.Free;
  end;
end;

Upvotes: 1

MartynA
MartynA

Reputation: 30715

I think this is just a minor FD quirk. The code below works as expected, with Cds_NaMenu declared as a TFDMemTable (though it would have been nice if you could have dropped the Cds_ to avoid confusion).

The key difference, I think, is the call to .Locate after the filter is cleared. The reason I put it there is because it causes the dataset to scroll and, I imagine, to recalculate its RecordCount as a result. Probably any other operation which causes a scroll would have the same effect, even MoveBy(0) - try it.

procedure TForm1.FormCreate(Sender: TObject);
var
  _recCount : Integer;
  ID : Integer;
  sTexto : String;
begin
  sTexto := 'xxx';  // added

  Cds_NaMenu.FieldDefs.Add('ID', ftInteger);
  Cds_NaMenu.FieldDefs.Add('MN_TELA_CODIGO', ftInteger);
  Cds_NaMenu.FieldDefs.Add('MN_MENU_PESQUISA', ftString, 500);
  Cds_NaMenu.FieldDefs.Add('DISPONIBILIDADE', ftInteger);
  Cds_NaMenu.IndexDefs.Add('Ordem', 'MN_TELA_CODIGO', []);
  Cds_NaMenu.CreateDataSet;
  Cds_NaMenu.LogChanges := False;
  Cds_NaMenu.IndexName := 'Ordem';


  Cds_NaMenu.Append;
  Cds_NaMenu.FieldByName('ID').AsInteger := 666;  // added
  Cds_NaMenu.FieldByName('DISPONIBILIDADE').AsInteger := 1;
  Cds_NaMenu.Post;


  _recCount := Cds_NaMenu.RecordCount; // Result = 1

  ID := Cds_NaMenu.FieldByName('ID').AsInteger;  // added

  Cds_NaMenu.Filter := 'DISPONIBILIDADE=1 AND MN_MENU_PESQUISA like ' + QuotedStr('%' + sTexto + '%');
  Cds_NaMenu.Filtered := True;
  _recCount := Cds_NaMenu.RecordCount; // Result = 0;
  Cds_NaMenu.Filtered := False;
  Cds_NaMenu.Filter := '';

  // Now force the dataset to scroll
  if Cds_NaMenu.Locate('ID', ID, []) then;  // added
  _recCount := Cds_NaMenu.RecordCount; // Result = 1;
  Caption := IntToStr(_recCount);  // added
end;

Upvotes: 0

Related Questions