« MyBaseを試してみる。(AppendとInsert) | トップページ | MyBaseを試してみる。(インデックスを使わずに、行の追加、挿入、削除編) »

MyBaseを試してみる。(CloneCursorでOnFilterRecord)

次のようにDBGridを2段配置して、下段にフィルター処理されたレコードを表示させてみました。期待する動作は、 CloneCursorでClientDataSet2を設定し、更にClientDataSet2.OnFilterRecordを設定して、それによりフィルター処理されることです。

Design_2


// サンプルデータ
procedure MakeSample(DataSet: TDataSet);
var
  No: Integer;
  F: Boolean;
begin
  F := DataSet.Active;
  if not F then
    DataSet.Open;
  try
    // サンプルデータの追加
    No := 0;
    with DataSet do
    begin
      Appendrecord(['iPod Touch']);
      Appendrecord(['Zaurus C-860']);
      Appendrecord(['Delphi 2009 Handbook']);
      Appendrecord(['GEORGIA BLACK']);
      CheckBrowseMode;
    end;
  finally
    if not F then
      DataSet.Close;
  end;
end;

// データベースの作成
procedure CreateDB(CDS: TClientDataSet; UsingIndex: Boolean);
var
  I, No: Integer;
begin
  CDS.Close;
  CDS.FieldDefs.Add('ITEM',ftWideString,20);
  CDS.CreateDataSet;
  CDS.Close;

  for I := 0 to CDS.FieldDefs.Count - 1 do
    CDS.FieldDefs[I].CreateField(CDS);

  CDS.Open;
  MakeSample(CDS);
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  // データベースの作成
  CreateDB(ClientDataSet1, False);
end;

procedure TForm1.ClientDataSet1FilterRecord(DataSet: TDataSet;
  var Accept: Boolean);
begin
  Accept := AnsiPos(Edit1.Text,DataSet.FieldByName('ITEM').AsString) > 0
end;

procedure TForm1.ClientDataSet2FilterRecord(DataSet: TDataSet;
  var Accept: Boolean);
begin
  Accept := AnsiPos(Edit2.Text, DataSet.FieldByName('ITEM').AsString) > 0
end;


// Filter
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  ClientDataSet2.Filtered := not ClientDataSet2.Filtered;
  if ClientDataSet2.Filtered then
  begin
    ClientDataSet2.CloneCursor(ClientDataSet1, False, False);
    ClientDataSet2.Filtered := True;
  end;
end;


しかしながら、いざ実行してみると正しくフィルターできませんでした。というかClientDataSet1のOnFilterRecordのデータが表示されています。

Tryfilter_2


CloneCursorのヘルプを読んでみると、第2のパラメーターの設定によることがわかりました。
procedure CloneCursor(Source: TCustomClientDataSet;
  Reset: Boolean;  KeepSettings: Boolean = False); virtual;

Online Help for Delphi® XE2 and C++Builder® XE2 DBClient.TCustomClientDataSet.CloneCursor
日本語ページを見つけられなかったので、ヘルプを読んでね(^-^)


CloneCursor側のOnFilterRecordを使う場合には、次のようにすると動作しました。
procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
  ClientDataSet2.Filtered := not ClientDataSet2.Filtered;
  if ClientDataSet2.Filtered then
  begin
    ClientDataSet2.CloneCursor(ClientDataSet1, TRUE, False);
    ClientDataSet2.OnFilterRecord := ClientDataSet2FilterRecord;
    ClientDataSet2.Filtered := True;
  end;
end;

Correct_2

|

« MyBaseを試してみる。(AppendとInsert) | トップページ | MyBaseを試してみる。(インデックスを使わずに、行の追加、挿入、削除編) »