所以我有一个AdoTable连接到数据库(mdb)和使用它的DataSource。这个DataSource由DBGrid ...
使用我尝试根据用户输入过滤AdoTable。有三个重要的列:名称,姓氏和ID。我想出了这样的临时解决方案:
AdoTable.filter:='surname like ' +
QuotedStr('%'+edit1.text+'%')+' or name like ' +
QuotedStr('%'+edit1.text+'%')+' or ID like ' +
QuotedStr('%'+edit1.text+'%');
AdoTable.filtered:=true;
它确实有效,但它并没有完全按照我的意愿去做...(当搜索名称时,它确实找不到任何内容,因为它只在一列中查找)。 所以后来我将代码修改为:
AdoTable.filter:='surname & " " & name like ' +
QuotedStr('%'+edit1.text+'%')+' or name & " " & surname like ' +
QuotedStr('%'+edit1.text+'%')+' or ID like ' +
QuotedStr('%'+edit1.text+'%');
AdoTable.filtered:=true;
现在这将是我想做的事情,但它会引发异常(EOleException:参数类型错误,超出可接受的范围,或者彼此冲突)。 这让我很吃惊,因为我认为它应该像sql命令中的where子句一样(并且它作为命令完美地运行)。
我尝试更换'&'用' +'。 我可以分割一个输入文本,但我不想这样做(如果你有像Robin van Persie,Ahmad ibn Hanbal等名字那么它会很糟糕。)
或者我可以重写整个程序来使用查询而不是表格,但我并不是真的想要这样做(这也意味着我将获得新的记录集EVERYTIME用户将改变edit1.text而不仅仅是过滤)。
有什么想法吗?
编辑: 所以有效的命令看起来像这样
select * from person where surname & " " & name like '%John Smith%' or name & " " & surname like '%John Smith%' or ID like '%John Smith%'
过滤器看起来像这样(并触发异常)
surname & " " & name like '%John Smith%' or name & " " & surname like '%John Smith%' or ID like '%John Smith%'
请注意,史密斯可能会出现这样的情况。而不是约翰史密斯'所以它也会找到Kahn Smithers'等
答案 0 :(得分:1)
以下代码适用于访问Delphi employee
数据库中dbdemos.mdb
表的AdoTable。我的AdoConnection正在使用Microsoft Jet 4.0 OLE DB
驱动程序。
procedure TForm1.Button1Click(Sender: TObject);
var
FilterExpr : String;
begin
AdoTable1.Filtered := not AdoTable1.Filtered;
if AdoTable1.Filtered then begin
FilterExpr := 'FirstName like ' + QuotedStr('%' + Edit1.Text + '%') + ' or LastName like ' + QuotedStr('%' + Edit1.Text + '%');
AdoTable1.Filter := FilterExpr;
end;
end;
我认为您的错误可能是使用了您提到的特定于Access的语法。您正在通过ADO层访问该表,并且AFAIK需要与您使用的语法相同的语法,例如:对于Sql Server后端。
从您的评论中,似乎您想要覆盖用户在Edit1.Text中键入名字的片段,然后是空格后跟片段或姓氏的情况。以下将这样做:
procedure TForm1.Button1Click(Sender: TObject);
var
FilterExpr : String;
P : Integer;
S1,
S2 : String;
begin
AdoTable1.Filtered := not AdoTable1.Filtered;
if AdoTable1.Filtered then begin
P := Pos(' ', Trim(Edit1.Text));
if P > 0 then begin
S1 := Copy(Trim(Edit1.Text), 1, P - 1);
S2 := Copy(Trim(Edit1.Text), P + 1, MaxInt);
FilterExpr := '(FirstName like ' + QuotedStr('%' + S1 + '%') + ')';
FilterExpr := FilterExpr + ' or (LastName like ' + QuotedStr('%' + S2 + '%') + ')';
end
else
FilterExpr := 'FirstName like ' + QuotedStr('%' + Edit1.Text + '%') + ' or LastName like ' + QuotedStr('%' + Edit1.Text + '%');
AdoTable1.Filter := FilterExpr;
end;
end;
更新:如果您想允许用户输入类似
的内容 史密斯然后您可以使用像这样的FilterRecord事件而不是上面的代码。
procedure TForm1.ADOTable1FilterRecord(DataSet: TDataSet; var Accept: Boolean);
var
S : String;
begin
S := LowerCase(DataSet.FieldByName('FirstName').AsString + ' ' + DataSet.FieldByName('LastName').AsString);
Accept := Pos(LowerCase(Edit1.Text), S) > 0;
end;
显然,转换为LowerCase是为了忽略用户可能使用的任何大写字母。
答案 1 :(得分:1)
我发现了这个:Using LIKE statement for filtering并使用了接受的答案,它运作得很好。 (由于问题差异很大,因此无法及时找到它)
在表格过滤器上:
procedure TDataModule1.ADOTableFilterRecord(DataSet: TDataSet;
var Accept: Boolean);
var
nameSurname :string;
surnameName :string;
begin
nameSurname:= DataSet.FieldByName('name').AsString+' '+DataSet.FieldByName('surname').AsString;
surnameName:= DataSet.FieldByName('surname').AsString+' '+DataSet.FieldByName('name').AsString;
if assigned(MainForm) then
Accept := (Pos(MainForm.edit1.Text, nameSurname) > 0)
or (Pos(MainForm.edit1.Text, surnameName) > 0)
or (Pos(MainForm.edit1.Text, DataSet.FieldByName('ID').AsString) > 0);
end;
编辑更改:
procedure TMainForm.edit1Change(Sender: TObject);
begin
DataModule1.AdoTable.Filtered:=false;
if edit1.Text<>'' then
DataModule1.AdoTable.Filtered:=True;
end;
感谢您的时间......我会把它留在这里......我想最终有人可能需要它