При использовании замечательно компоненты ExpressQuantumGrid Suite удобно в шапке Grid’а устанавливать фильтры. Но если надо установить фильтр программно, то я столкнулся с таким нюансом. Если просто надо отфильтровать данные по какому-то значению, то это делается легко вызовом такой процедуры:
dxDBGrid1.Filter.Add(AColumn: TdxDBTreeListColumn; const AValue: Variant; const ADisplayValue: string);
где _AColumn _- какую колонку фильтруем _AValue _- по какому значению фильтруем _ADisplayValue _- что отобразить в панели статуса фильтра
Вот мой пример использования:
dxDBGrid1.Filter.Add(dxDBGrid1SOOTVCUSTOMERS, 777, '777');
Это значит, что колонка dxDBGrid1SOOTVCUSTOMERS будет отфильтрована по значению, равному 777 и в панели статуса будет написано: “(Название_колонки = 777)”
Но вот незадача, мне надо отфильтровать не по равенству, а по неравенству, но задать условие NOT в этой процедуре нельзя. Заглядываем в код процедуры и видим:
procedure TdxDBGridFilter.Add(AColumn: TdxDBTreeListColumn; const AValue: Variant; const ADisplayValue: string);
begin
TdxDBGridCriteria(FCriteria).RemoveItemsByColumn(AColumn);
TdxDBGridCriteria(FCriteria).AddItem(nil, AColumn, otEqual, AValue, ADisplayValue, False);
FDBGrid.SetFilterMode;
end;
Как видим, вызывается процедура AddItem, смотрим и ее код:
function TdxDBGridCriteria.AddItem(AItemList: TdxCriteriaItemList; AColumn: TdxDBTreeListColumn;
AOperator: TdxOperatorType; const AValue: Variant; const ADisplayValue: string;
AIsNot: Boolean): TdxDBGridCriteriaItem;
begin
if AItemList = nil then
AItemList := Root;
Result := TdxDBGridCriteriaItem(AItemList.AddItem(AColumn.Name, AOperator, AValue, ADisplayValue));
Result.IsNot := AIsNot;
end;
Вот тут и стало ясно, что последним параметром как раз идет указание на равенство или неравенство, задаваемому условию. Почему в TdxDBGrid процедура Filter.Add не имеет этого параметра и он указан жестко false остается загадкой. Можно создать свой класс-наследник от TdxDBGrid и в нем написать свою процедуру AddItem, но тогда нам придется в проекте вручную создавать Grid и все его колонки, что очень не хотелось бы. Поэтому придется написать процедуру добавления фильтра с возможностью указания этого нужного параметра. Добавляем два типа:
uses dxGrFltr, dxFilter;
type
TMyDBGrid = class(TCustomdxDBGrid);
TMyDBGridFilter = class(TdxDBGridFilter);
И пишем в нашем объекте процедуру:
procedure TForm1.AddFilter(Column: TdxDBTreeListColumn; Value: Variant; DisplayValue: string; Operator: TdxOperatorType = otEqual; NotCriteria: Boolean = False);
var
Grid: TMyDBGrid;
Criteria: TdxCriteria;
begin
if Column = nil then
Exit;
Grid := TMyDBGrid(Column.TreeList);
Criteria := TMyDBGridFilter(Grid.Filter).Criteria;
with TdxDBGridCriteria(Criteria).AddItem(nil, Column, Operator, Value, DisplayValue, False) do
if NotCriteria then
IsNot := True;
Grid.SetFilterMode;
end;
Далее в коде наш фильтр будет выглядеть так:
AddFilter(dxDBGrid1SOOTVCUSTOMERS, 777, '777', otEqual, true);
По материалам статьи How to create a filter for the Grid at runtime