Delphi TEdit使用Access筛选Tstringgrid

Delphi TEdit使用Access筛选Tstringgrid,delphi,ms-access,filter,firemonkey,Delphi,Ms Access,Filter,Firemonkey,我正在使用Delphi10和Firemonkey,我对它有点陌生。我有一个TStringGrid,我用LiveBindings绑定到access数据库。我需要的是,当我按下按钮或输入任何键时,用TEdit的文本过滤此表或TStringGrid,并在同一TStringGrid的结果中显示它。就像一个定制的搜索/过滤框 我还没有这方面的代码。但我认为这就像一个疑问 程序TForm3.Edit2Typing(发送方:TObject); 开始 adoquery1.关闭; adoquery1.SQL.Te

我正在使用Delphi10和Firemonkey,我对它有点陌生。我有一个TStringGrid,我用LiveBindings绑定到access数据库。我需要的是,当我按下按钮或输入任何键时,用TEdit的文本过滤此表或TStringGrid,并在同一TStringGrid的结果中显示它。就像一个定制的搜索/过滤框

我还没有这方面的代码。但我认为这就像一个疑问
程序TForm3.Edit2Typing(发送方:TObject);
开始
adoquery1.关闭;
adoquery1.SQL.Text:='select*from instrutor,其中nome类似于“%”+edit2.Text+“%”;
adoquery1.打开;
结束


我已经试过了,但是因为我已经有了一个与adotable和stringgrid的livebinding,我不知道我应该如何链接这个Tedit。下面的例子是一个在TAdoQuery和TStringGrid之间使用livebinding的最小应用程序。我把它作为VCL应用程序而不是FMX应用程序来做是为了方便,但这对如何在计算机上进行过滤没有任何影响 实时绑定AdoQuery

它使用2个TEDIT指定要匹配的筛选器值和字段名称 进行筛选(实际上,最好使用可用字段名填充列表框)

主要“工作”在
UpdateFilter
过程中完成

它使用活动绑定这一事实对如何将过滤器应用于数据集没有任何影响。但是,到StringGrid的实时绑定要比传统(VCL)TDBGrid慢得多。要避免的一件重要事情是,数据集有大量字段,并且每个字段都有一个stringgrid列,因为这会使应用程序对筛选条件的更改做出非常缓慢的响应。减轻此影响的一种方法是,通过将stringgrid的ColCount设置为适当的低值,将stringgrid列的数量限制为更低的数量。另一种方法是为数据集定义持久字段,但只创建其中的几个字段

在下面的代码中,我使用了TEdits的OnChange事件来更新FilterFieldName和FilterValue字段,但显然您可以使用单独的按钮来单击以调用UpdateFilter过程

代码:

TForm1=class(TForm)
ADO连接1:TADOConnection;
ADOQuery1:TADOQuery;
StringGrid1:TStringGrid;
绑定列表1:t绑定列表;
数据源1:TDataSource;
LinkGridToDataSource1:TLinkGridToDataSource;
BindSourceDB1:TBindSourceDB;
edFilterFieldName:TEdit;
edFilterValue:TEdit;
过程表单创建(发送方:ToObject);
程序EDFilterFieldName更改(发送方:ToObject);
程序edFilterValueChange(发送方:ToObject);
私有的
FFilterFieldName:字符串;
FFilterValue:字符串;
过程SetFilterFieldName(常量值:字符串);
过程SetFilterValue(常量值:字符串);
程序更新过滤器;
公众的
属性FilterFieldName:字符串读取FilterFieldName写入SetFilterFieldName;
属性FilterValue:字符串读取FilterValue写入SetFilterValue;
结束;
[...]
过程TForm1.FormCreate(发送方:TObject);
开始
FilterFieldName:=edFilterFieldName.Text;
FilterValue:=edFilterValue.Text;
结束;
程序TForm1.edFilterFieldNameChange(发送方:ToObject);
开始
FilterFieldName:=edFilterFieldName.Text;
结束;
程序TForm1.edFilterValueChange(发送方:ToObject);
开始
FilterValue:=edFilterValue.Text;
结束;
过程TForm1.SetFilterFieldName(常量值:字符串);
开始
如果是FilterFieldName值,则开始
FFilterFieldName:=值;
更新过滤器;
结束;
结束;
过程TForm1.SetFilterValue(常量值:字符串);
开始
如果是FilterValue值,则开始
FFilterValue:=值;
更新过滤器;
结束;
结束;
程序TForm1.UpdateFilter;
变量
表达式:字符串;
开始
AdoQuery1.FILTED:=False;
//下一条语句检查FilterFieldName
//匹配数据集中的字段,如果不匹配则退出。自从
//FilterFieldName值来自编辑框,当用户键入时,该值将不完整
如果AdoQuery1.FieldByName(FilterFieldName)=Nil,则
出口
如果为FilterValue“”,则开始
表达式:=FilterFieldName+'like'+QuotedStr('%'+FilterValue+'%');
AdoQuery1.过滤器:=Expr;
AdoQuery1.已过滤:=真;
结束;
结束;

请将您尝试的代码添加到q。或者你是说你不知道从哪里开始?就像q查询,当然。但在Delphi数据集上下文中,表达式“filter”通常意味着仅对已从数据库检索到Delphi应用程序中的记录子集进行操作(例如显示)。因此,您需要决定是需要查询还是过滤器,然后说。好的,我应该使用AdoTable.filter属性。现在我只需要将其与stringgrid绑定?好的,我使用了您的示例,并且在AdoQuery中使用了过滤器属性,这很好。我只需要将“Like”改为“=”,因为我正在使用access,显然它不接受“Like”。我必须输入它的全名才能出现。当我输入部分名称时,如何使其显示?比如“te”而不是“test”之类的。这是一句话:
adoquery1.Filter:=('Name='+QuotedStr(Edit2.Text))。事实上,我刚刚使用AdoConnection字符串中的Microsoft.Jet.OLEDB.4.0驱动程序对MS Access数据库测试了我的代码,它运行良好,包括对定义为Char(40)的列使用“like”。你用的是什么访问驱动程序?我用的是相同的。我试着输入你和其他类似的过滤器语法,但是没有一个有效。对我来说,这样做很好,但让它更“动态”会更方便用户。我会把你的回答记为答案,但如果你能帮我找到答案,我将不胜感激嗯,我真的无法推测为什么你的过滤器有问题——可能是任何问题。我要做两件事:首先,在UpdateFilter中,添加过滤器
TForm1 = class(TForm)
  ADOConnection1: TADOConnection;
  ADOQuery1: TADOQuery;
  StringGrid1: TStringGrid;
  BindingsList1: TBindingsList;
  DataSource1: TDataSource;
  LinkGridToDataSource1: TLinkGridToDataSource;
  BindSourceDB1: TBindSourceDB;
  edFilterFieldName: TEdit;
  edFilterValue: TEdit;
  procedure FormCreate(Sender: TObject);
  procedure edFilterFieldNameChange(Sender: TObject);
  procedure edFilterValueChange(Sender: TObject);
private
  FFilterFieldName : String;
  FFilterValue : String;
  procedure SetFilterFieldName(const Value: String);
  procedure SetFilterValue(const Value: String);
  procedure UpdateFilter;
public
  property FilterFieldName : String read FFilterFieldName write SetFilterFieldName;
  property FilterValue : String read FFilterValue write SetFilterValue;
end;

[...]

procedure TForm1.FormCreate(Sender: TObject);
begin
  FilterFieldName := edFilterFieldName.Text;
  FilterValue := edFilterValue.Text;
end;

procedure TForm1.edFilterFieldNameChange(Sender: TObject);
begin
  FilterFieldName := edFilterFieldName.Text;
end;

procedure TForm1.edFilterValueChange(Sender: TObject);
begin
  FilterValue := edFilterValue.Text;
end;

procedure TForm1.SetFilterFieldName(const Value: String);
begin
  if FilterFieldName <> Value then begin
    FFilterFieldName := Value;
    UpdateFilter;
  end;
end;

procedure TForm1.SetFilterValue(const Value: String);
begin
  if FilterValue <> Value then begin
    FFilterValue := Value;
    UpdateFilter;
  end;
end;

procedure TForm1.UpdateFilter;
var
  Expr : String;
begin
  AdoQuery1.Filtered := False;

  //  The next statement checks whether the FilterFieldName
  //  matches a field in the dataset and exits if not.  Since the
  //  FilterFieldName value comes from an edit box, it will be incomplete while the user is typing it in
  if AdoQuery1.FieldByName(FilterFieldName) = Nil then
    exit;
  if FilterValue <> '' then begin
    Expr := FilterFieldName + ' like ' + QuotedStr('%' + FilterValue + '%');
    AdoQuery1.Filter := Expr;
    AdoQuery1.Filtered := True;
  end;
end;