Using LIKE statement for filtering - delphi

Im using this code to filter my table:
Table.Filtered := False;
Table.Filter := '[' + Field_Search + '] LIKE ''%' + Edit_Search.Text + '%''';
Table.Filtered := True;
but it raises this exception:
"Operation not applicable."
where is problem?

A TTable.Filter isn't a SQL query. LIKE isn't supported (neither is IN). The supported operators are =, <>, >, <, >=, '<=,AND,NOTandOR`, according to the documentation
For more complicated filtering, use the TDataSet.OnFilterRecord event:
procedure TForm1.Table1FilterRecord(Dataset: TDataset; var Accept: Boolean);
begin
// Don't remember if D7 supports DataSet[FieldName] syntax; if not,
// use DataSet.FieldByName instead, or a persistent field.
Accept := Pos(Edit_Search.Text, DataSet[SearchField].AsString) > 0;
end;

Table.Filtered := False;
Table.Filter := Field_Search + ' LIKE ' + QuotedStr('*' + Edit_Search.Text + '*');
Table.Filtered := True;

you should use this :
DataModule.Table.Filtered := False;
DataModule.Table.Filter := 'Field_Name' + ' LIKE ' + QuotedStr(Edt_SearchByCode.Text +'%');
DataModule.Table.Filtered := True;
and will work like a Magic and no use of TQuery any more ....
and if you want Matching does not take case-sensitivity into account.
you should use this code instead:
DataModule.Table.Filtered := False;
DataModule.Table.FilterOptions := [foCaseInsensitive];
DataModule.Table.Filter := 'Field_Name' + ' LIKE ' + QuotedStr(Edt_SearchByCode.Text +'%');
DataModule.Table.Filtered := True;

The following Code will work as Like as well:
if Edit1.Text <>'' then
begin
Query1.Filter :='FieldName ='+quotedstr('*'+ edit1.Text +'*');
Query1.Filtered:=true;
end
else
begin query1.Filtered :=false; end;

I found this topic looking for something else. I always use the TDataSet.OnFilterRecord event, and in most cases I use a TEdit.OnChange event so the search is "Active";
var
Criteria : string;
...
...
procedure TForm1.Edit1Change(Sender: TObject);
begin
Table.Filtered := False;
Criteria := Edit1.text;
Table.Filtered := True;
end;
and with the OnFilter event
procedure TForm1.TableFilterRecord(DataSet: TDataSet;
var Accept: Boolean);
begin
Accept := AnsiContainsStr(Table.Fields[xx].asString,Criteria);
end;
Works for me.

I am using mostly with TEdit here is the code
if (EditSerarch.Text <> '') then
begin
FDQQuery.Filtered := false;
FDQQuery.Filter:= 'Name LIKE'+ QuotedStr('%'+EditSerarch.Text+'%') +
' OR Company LIKE '+ QuotedStr('%'+EditSerarch.Text+'%') +
' OR Phone LIKE '+ QuotedStr('%'+EditSerarch.Text+'%') +
' OR Mobile LIKE '+ QuotedStr('%'+EditSerarch.Text+'%');
FDQQuery.Filtered:= True;
end else FDQQuery.Filtered := false;

I recommend to use a SQL Query to perform this operation.
Example:
query1.SQL.Text:='Select * FROM table_name WHERE field like '+ QuotedStr(edit1.text+'%');
query1.Active:=true;

Related

Filtering ADOTable error - "could not convert type Null to type OleStr"

I am trying to filter an ADOTable for records with a field 'OwnerName' value matches the one in a edit on my GUI component. When entering a name that does not exist, i get the above mentioned error. When there are no names in the database that match the filter, I just want the dbgrid to display nothing, how can this be done? Still a noob, so could anyone enlighten me?
Code used:
procedure TOwners.edt_Name_FilterChange(Sender: TObject);
begin
Filter;
end;
//-----------------------------------------------------------
procedure TOwners.Filter;
begin
if edt_Name_Filter.text = '' then
begin
CarOwners.tbl_Owners.Filtered := false;
exit;
end;
with CarOwners do
begin
tbl_Owners.Filtered := false;
tbl_Owners.Filter := 'OwnerName LIKE ''' + '%' + edt_Name_Filter.text +
'%' + '''';
if tbl_owners['OwnerName'] = null then
begin
tbl_owners.filter := '';
end;
tbl_Owners.Filtered := true;
end;
end;

how to display to a dbgrid my query in this code?

hello is it possible for this code to display to a tdbgrid the search results in a list like style? (e.g. if i searched for john, all the data conataining john on a certain field will be displayed to the tdbgrid)
procedure Tspcb.dccolbtnClick(Sender: TObject);
begin
zdctable.First;
while not zdctable.EOF do
begin
if (zdctable.FieldByName('Collector').AsString = dcedit.Text)
then begin
cn.Caption := zdctable.FieldByName('Client_Name').AsString;
col.Caption := zdctable.FieldByName('Collector').AsString;
pay.Caption := zdctable.FieldByName('Daily_Payment').AsString;
date.Caption := zdctable.FieldByName('Date').AsString;
ddate.Caption := zdctable.FieldByName('Due_Date').AsString;
id.Caption := zdctable.FieldByName('ID').AsString;
la.Caption := zdctable.FieldByName('Loan').AsString;
tc.Caption := zdctable.FieldByName('Total_Collectibles').AsString;
end;
ShowMessage('click ok for next profile');
zdctable.Next;
end;
end;
Just add a datasource, set property dataset to your dataset zdctable, add a DBgrid to your form and set the property datasource to the datasource.
The only piece of code you will need is in the OnchangeEvent of dcedit
procedure TForm3.dceditChange(Sender: TObject);
begin
zdctable.FilterOptions:=[foCaseInsensitive]; // if wished
zdctable.Filtered := Length(dcEdit.Text) > 0;
if zdctable.Filtered then
// zdctable.Filter := 'Collector like ' + QuotedStr('%' + dcEdit.Text + '%')
zdctable.Filter := 'Collector like ' + QuotedStr('*' + dcEdit.Text + '*') // Zeos- Syntax
else zdctable.Filter := '';
end;

Exporting DBgrid to CSV?

I have a DB grid which is sorted (the user clicked a few radio buttons and checkboxes to influence the display).
I would like to export all of the data (not just what is visible in the grid), sorted identically, to CSV - how do I do so? The data - not the user settings, just to clarify.
Thanks in advance for any help
[Update] I build sqlQuery bit by bit, depending on the user's settings of checkboxes & radio groups, then, when one of them changes, I
ActivityADQuery.SQL.Clear();
ActivityADQuery.SQL.Add(sqlQuery);
ActivityADQuery.Open(sqlQuery);
That is to say that there isn't a hard coded query, it varies and I want to export the current settings.
I don't know enough if I want to export from the grid or the dataset (I am just not a db guy, this is my first DBgrid), but I suspect that I want the grid, because it has a subset of fields of he dataset.
I guess that TJvDBGridCSVExport is a Jedi component(?) I have tried to avoid them so far, great as they sound, because I prefer discreet, stand-alone, components to installing a huge collection. That may not be the cleverest thing to do, but it's how I feel - ymmv (and prolly does)
Another solution, works also with (multi)selected rows:
procedure TReportsForm.ExportToCSV(const aGrid : TDBGrid; const FileName : String);
Var
I, J : Integer;
SavePlace : TBookmark;
Table : TStrings;
HeadTable : String;
LineTable : String;
First : Boolean;
Begin
HeadTable := '';
LineTable := '';
Table := TStringList.Create;
First := True;
Try
For I := 0 To Pred(aGrid.Columns.Count) Do
If aGrid.Columns[I].Visible Then
If First Then
Begin
// Use the text from the grid, in case it has been set programatically
// E.g., we prefer to show "Date/time" than "from_unixtime(activity.time_stamp, "%D %b %Y %l:%i:%S")"
// HeadTable := HeadTable + aGrid.Columns[I].FieldName;
HeadTable := HeadTable + ActivityReportStringGrid.Columns[i].Title.Caption + ','; // Previous separated wth semi-colon, not comma! (global)
First := False;
End
Else
begin
// HeadTable := HeadTable + ';' + aGrid.Columns[I].FieldName;
HeadTable := HeadTable + ActivityReportStringGrid.Columns[i].Title.Caption + ',';
end;
Delete(HeadTable, Length(HeadTable), 1); // Remove the superfluous trailing comma
Table.Add(HeadTable);
First := True;
// with selection of rows
If aGrid.SelectedRows.Count > 0 Then
Begin
For i := 0 To aGrid.SelectedRows.Count - 1 Do
Begin
aGrid.DataSource.Dataset.GotoBookmark(pointer(aGrid.SelectedRows.Items[i]));
For j := 0 To aGrid.Columns.Count - 1 Do
If aGrid.Columns[J].Visible Then
If First Then
Begin
lineTable := lineTable + aGrid.Fields[J].AsString;
First := False;
End
Else
lineTable := lineTable + ',' + aGrid.Fields[J].AsString;
Delete(LineTable, Length(LineTable), 1); // Remove the superfluous trailing comma
Table.Add(LineTable);
LineTable := '';
First := True;
End;
End
Else
//no selection
Begin
SavePlace := aGrid.DataSource.Dataset.GetBookmark;
aGrid.DataSource.Dataset.First;
Try
While Not aGrid.DataSource.Dataset.Eof Do
Begin
For I := 0 To aGrid.Columns.Count - 1 Do
If aGrid.Columns[I].Visible Then
If First Then
Begin
lineTable := lineTable + aGrid.Fields[I].AsString;
First := False;
End
Else
lineTable := lineTable + ',' + aGrid.Fields[I].AsString;
Delete(LineTable, Length(LineTable), 1); // Remove the superfluous trailing comma
Table.Add(LineTable);
LineTable := '';
aGrid.DataSource.Dataset.Next;
First := True;
End;
aGrid.DataSource.Dataset.GotoBookmark(SavePlace);
Finally
aGrid.DataSource.Dataset.FreeBookmark(SavePlace);
End;
End;
Table.SaveToFile(FileName);
Finally
Table.Free;
End;
End; // ExportToCSV()
You could use a own tiny procedure wich could be adapted to your needs
Procedure Dataset2SeparatedFile(ads: TDataset; const fn: String; const Separator: String = ';');
var
sl: TStringList;
s: String;
i: Integer;
bm: TBookmark;
Procedure ClipIt;
begin
s := Copy(s, 1, Length(s) - Length(Separator));
sl.Add(s);
s := '';
end;
Function FixIt(const s: String): String;
begin
// maybe changed
Result := StringReplace(StringReplace(StringReplace(s, Separator, '', [rfReplaceAll]), #13, '', [rfReplaceAll]), #10, '', [rfReplaceAll]);
// additional changes could be Quoting Strings
end;
begin
sl := TStringList.Create;
try
s := '';
For i := 0 to ads.FieldCount - 1 do
begin
if ads.Fields[i].Visible then
s := s + FixIt(ads.Fields[i].DisplayLabel) + Separator;
end;
ClipIt;
bm := ads.GetBookmark;
ads.DisableControls;
try
ads.First;
while not ads.Eof do
begin
For i := 0 to ads.FieldCount - 1 do
begin
if ads.Fields[i].Visible then
s := s + FixIt(ads.Fields[i].DisplayText) + Separator;
end;
ClipIt;
ads.Next;
end;
ads.GotoBookmark(bm);
finally
ads.EnableControls;
ads.FreeBookmark(bm);
end;
sl.SaveToFile(fn);
finally
sl.Free;
end;
end;

Partial Search In Table(BDE)

I made a database with paradox 7. The usual search I do is a syntax like this:
Table.Filter := 'Country=' + QuotedStr(Edit.Text);
This returns rows those country field is same as the entered text in edit. when I want to search for countries are beginning by "L" i use this syntax:
Table.Filter := 'Country=' + QuotedStr(Edit.Text + '*');
But how can I search for fields those are finished with "L"? this syntax does not work:
Table.Filter := 'Country=' + QuotedStr('*' + Edit.Text );
Thanks.
You can use the OnFilterRecord event to carry out a customized filtering. With your example, maybe sth. like this:
procedure TForm1.Table1FilterRecord(DataSet: TDataSet; var Accept: Boolean);
var
s: string;
begin
Accept := False;
if not DataSet.FieldByName('Country').IsNull then begin
s := DataSet.FieldByName('Country').AsString;
Accept := Copy(s, Length(s), 1) = 'L';
end;
end;

is possible filter a TClientDataset using a insensitive case?

i need to filter a TClientDataset, actually i'am using this code.
if Value<>'' then
begin
ClientDataSet1.DisableControls;
try
ClientDataSet1.Filtered := False;
ClientDataSet1.Filter := 'Value LIKE ' + QuotedStr('%'+Value+'%');
ClientDataSet1.Filtered := True;
finally
ClientDataSet1.EnableControls;
end;
end;
but the filter is working in case-sensitive mode, is posible filter the record ignoring the case?
you must use the FilterOptions property with the foCaseInsensitive value.
ClientDataSet1.DisableControls;
try
ClientDataSet1.Filtered := False;
ClientDataSet1.FilterOptions := [foCaseInsensitive];
ClientDataSet1.Filter := 'Value LIKE ' + QuotedStr('%'+Value+'%');
ClientDataSet1.Filtered := True;
finally
ClientDataSet1.EnableControls;
end;

Resources