Блог


Последние записи


Теги

Информация

Delphi, DevExpress, примеры, решения

Фильтр по тегу: поиск


Поиск в cxGrid

Поиск данных в TcxGridTableView (TcxGrid) на любое вхождение (совпадение), а не только по начальным символам

+
+ Поиск данных в cxGrid
function SearchIncxGrid(AView: TcxGridTableView; AText: string; AFromBeginning: boolean): boolean;
//const
//  MsgDataNotFound = 'Данные, удовлетворяющие условию поиска, не обнаружены';

var
  GroupsIndex: integer;
  GroupsCount: integer;
  ChildCount: integer;
  ColIndex: integer;
  RowIndex: integer;
  RecIndex: integer;
  CurIndex: integer;
  i, j, k: integer;
function
  Compare(ARecIndex, AColIndex: integer): boolean;
  begin
    Result :=
      AnsiContainsText
      (
        AView.DataController.DisplayTexts
        [
          ARecIndex,
          AView.VisibleColumns[AColIndex].Index
        ],
        AText
      );
  end;
begin
  Result := false;
  AView.DataController.ClearSelection;

  if AFromBeginning then
  begin
    // поиск с начала
    // строка  - первая
    // столбец - первый
    RowIndex := 0;
    ColIndex := 0;
  end
  else
  begin
    // поиск с текущей позиции
    // строка  - текущая
    // столбец - слещующий после текущего
    // если текущий столбец последний, то начинаем поиск
    // с первого столбца следующей строки
    RowIndex := AView.Controller.FocusedRowIndex;
    ColIndex := AView.Controller.FocusedColumnIndex;
    if AView.Controller.FocusedColumn.IsLast then
    begin
      ColIndex := 0;
      Inc(RowIndex);
    end
    else
      Inc(ColIndex)
  end;

  if AView.DataController.Groups.GroupingItemCount = 0 then
  begin
    // поиск в несгруппированном представлении
    for i := RowIndex to AView.ViewData.RowCount - 1 do
    begin
      RecIndex := AView.ViewData.Rows[i].RecordIndex;
      if RecIndex = -1 then
        Continue;

      for j := ColIndex to AView.VisibleColumnCount - 1 do
      begin
        Result := Compare(RecIndex, j);
        if Result then
        begin
          AView.Controller.FocusedRecordIndex := RecIndex;
          AView.Controller.FocusedColumnIndex := j;
          Break;
        end;
      end;

      ColIndex := 0;
      if Result then
        Break;
    end;
  end
  else
  begin
    // поиск в сгруппированном представлении
    GroupsCount := TcxDataControllerGroupsProtected(AView.DataController.Groups).DataGroups.Count;
    GroupsIndex := AView.DataController.Groups.DataGroupIndexByRowIndex[RowIndex];
    for i := GroupsIndex to GroupsCount - 1 do
    begin
      ChildCount := AView.DataController.Groups.ChildCount[i];
      for j := 0 to ChildCount - 1 do
      begin
        RecIndex := AView.DataController.Groups.ChildRecordIndex[i, j];
        if RecIndex = -1 then
          Continue;

        CurIndex := AView.DataController.GetRowIndexByRecordIndex(RecIndex, false);
        if (CurIndex > -1) and (CurIndex < RowIndex) then
          Continue;

        for k := ColIndex to AView.VisibleColumnCount - 1 do
        begin
          Result := Compare(RecIndex, k);
          if Result then
          begin
            AView.Controller.FocusedRowIndex     := AView.DataController.GetRowIndexByRecordIndex(RecIndex, true);
            AView.Controller.FocusedColumnIndex := k;
            Break;
          end;
        end;

        ColIndex := 0;
        if Result then
          Break;
      end;

      if Result then  Break;
    end;
  end;

  if Result then
    AView.Controller.FocusedRecord.Selected := true;
end;

отсюда:https://www.sql.ru/forum/actualutils.aspx?action=gotomsg&tid=681593&msg=7448693






*************************************************************

Поиск IncSearch (по начальным символам) по всем колонками

Я хочу, чтобы конечные пользователи могли найти текст в любом месте, но в свойству OptionsBehavior.IncSearhItem можно присвоить только одну колонку.
Рекомендуем использовать <GridView>.OnFocusedItemChanged и присвоить OptionsBehavior.IncSearhItem значение AFocusedItem, передаваемый обработчику событий. Это позволит вам достичь требуемого поведения:

procedure TForm1.cxGridViewRepository1DBTableView1FocusedItemChanged(
  Sender: TcxCustomGridTableView; APrevFocusedItem,
  AFocusedItem: TcxCustomGridTableItem);
begin
  Sender.OptionsBehavior.IncSearchItem := AFocusedItem;
end;




Отсюда: http://www.devexpress.com/Support/Center/KB/p/A1676.aspx

P.S.
Может возникнуть проблема, если сетка отсортирована, а именно - неправильное позиционирование после поиска.



Ещё один способ с "пробегом" в одну сторону:
procedure TfmEdit.SearchGrid(Grid: TcxGridDbTableView);
Var
 ARecordIndex, i: integer;
begin
  if Grid.DataController.FilteredRecordCount <= 0 then exit;

  Grid.DataController.BeginUpdate;
  try
    for I := 0 to Pred(Grid.DataController.FilteredRecordCount) do
    begin
      ARecordIndex := Grid.DataController.FilteredRecordIndex[i];

      {Можно использовать DisplayTexts и Values, разницу см. в справке}
      if (Pos(edSearch.EditingText, Grid.DataController.DisplayTexts[ARecordIndex, GridDB1TEL.Index] ) <> 0) then
      begin
        Grid.DataController.FocusedRecordIndex := ARecordIndex;//фокусируемся на строку
        break;
      end;//if
    end;//for

//    cxGrid1.SetFocus;
    //выбираем найденную запись
    with Grid do
    if DataController.FilteredRecordCount > 0 then
    begin
      Controller.ClearSelection;
      Controller.FocusedRow.Selected := True;
    end;

  finally
    Grid.DataController.EndUpdate;
  end;
end;



Так же смотрите справки по методам: FindRecordIndexByKeyValue, FindRecordIndexByText, GridView.DataController.Search. Но все эти методы ищут только по первыми символам.


Поиск в Master/Detail cxGrid
http://www.devexpress.com/Support/Center/Question/Details/Q356653




iterating through a grid to find a value
Цикл по cxGrid для поиска записей по всем столбцам
http://www.devexpress.com/Support/Center/Question/Details/Q398416
var
  I, J: Integer;
  AValue: Variant;
begin
  for I := 0 to AView.DataController.RecordCount - 1 do
    for J := 0 to AView.DataController.ItemCount - 1 do
    begin
      AValue := AView.DataController.Values[I, J];
      if AValue = <YourSearchValue> then
        //Perform your actions
    end;
end;



function cxGrid_SearchText
  (const aTableView : TcxGridTableView;
   const aSearchText : String) : Boolean;
var
  RecordIndex : Integer;
  ItemIndex : Integer;
  AValue : Variant;
begin
  result := false;

  aTableView.BeginUpdate;
  try

    for RecordIndex := 0 to aTableView.DataController.RecordCount - 1 do begin
      for ItemIndex := 0 to aTableView.DataController.ItemCount - 1 do begin

        AValue := aTableView.DataController.DisplayTexts[RecordIndex,ItemIndex];
        if AnsiContainsText(AValue,aSearchText) then begin

// my positioning code
          aTableView.Controller.ClearSelection;
          aTableView.DataController.FocusedRecordIndex := RecordIndex;
          aTableView.Controller.FocusedColumnIndex :=
            aTableView.Columns[ItemIndex].VisibleIndex;

          if Assigned(aTableView.Controller.FocusedRecord) then begin
            aTableView.Controller.FocusedRecord.Selected := true;
          end; // if Assigned(aTableView.Controller.FocusedRecord)
// my positioning code

          result := true;
          exit;
        end; // if AnsiContainsText(AValue,aSearchText)

      end; // for ItemIndex := 0 to
    end; // for RecordIndex := 0 to

  finally
    aTableView.EndUpdate;
  end;
end;
добавлено: 13 июл 12 просмотры: 6251, комментарии: 2



cxGrid контекстный поиск

При контекстном поиске результат показывается внизу.
Как сделать его вверху:
procedure <You>Form.<Your>GridTableViewFocusedRecordChanged(Sender: TcxCustomGridTableView;
  APrevFocusedRecord, AFocusedRecord: TcxCustomGridRecord; ANewItemRecordFocusingChanged: Boolean); begin
  if Sender.Controller.IsIncSearching then
    if AFocusedRecord.Index > 0 then Sender.Controller.TopRecordIndex := AFocusedRecord.Index - 1
    else Sender.Controller.TopRecordIndex := AFocusedRecord.Index;
end;
добавлено: 12 июл 12 просмотры: 1329, комментарии: 0