"EhLib.Com" https://forum.ehlib.com/ru/ |
|
SearchPanel новые возможности https://forum.ehlib.com/ru/viewtopic.php?f=4&t=2070 |
Страница 1 из 1 |
Автор: | maratvg [ 03 окт 2016, 07:44 ] |
Заголовок сообщения: | SearchPanel новые возможности |
Добрый день. Предлагаю подумать над такими возможностями SearchPanel: 1. Поиск по таймеру. Т.е., пока идет набор символов, искать не надо, лучше подождать. Актуально на больших наборах данных. 2. Прерывание поиска нажатием Esc. Бывает, напишешь в поиск всякий ерунды (забыл переключить раскладку) и ждешь, пока ничего не найдется, чтобы снова искать. 3. Поиск нескольких слов, разделенных пробелом. Тут возможны варианты как искать: ищем любое из слов в любой из колонок или ищем записи, в которых присутствуют все слова (могут быть в разных колонках). |
Автор: | Cinemaizer [ 04 окт 2016, 16:58 ] |
Заголовок сообщения: | Re: SearchPanel новые возможности |
Полностью поддерживаю по все пунктам. |
Автор: | Administrator [ 04 окт 2016, 17:46 ] | ||
Заголовок сообщения: | Re: SearchPanel новые возможности | ||
Добрый день. Цитата: 1. Поиск по таймеру. Т.е., пока идет набор символов, искать не надо, лучше подождать. Актуально на больших наборах данных. В текущей версии примерно так работает. Если во время поиска грид определяет наличие нажатой клавиши, то поиск прерывается. Цитата: 2. Прерывание поиска нажатием Esc. Бывает, напишешь в поиск всякий ерунды (забыл переключить раскладку) и ждешь, пока ничего не найдется, чтобы снова искать. Примем к рассмотрению. Цитата: 3. Поиск нескольких слов, разделенных пробелом. Тут возможны варианты как искать: ищем любое из слов в любой из колонок или ищем записи, в которых присутствуют все слова (могут быть в разных колонках). Уже реализовано в виде Демо проекта. См. <EhLib>\Demos\DBGridEh.SearchPanel\ закладка Demo3
|
Автор: | maratvg [ 05 окт 2016, 06:00 ] |
Заголовок сообщения: | Re: SearchPanel новые возможности |
1. Не совсем такое поведение подразумевалось. Попробуйте на примере MainDemo.Exe - Working with huge data. Если в searchpanel написать что-то по-русски (в dataset нет данных на русском), то хорошо видно, что на каждую букву происходит поиск (заметно торможение). Если бы поиск запускался по таймеру, то этого можно было бы избежать. |
Автор: | Administrator [ 11 ноя 2016, 10:53 ] |
Заголовок сообщения: | Re: SearchPanel новые возможности |
Добрый день. В новой сборке 9.0.031 изменили способ прерывания при поиске в SearchPanel. * Изменение: В DBGridEh в SearchPanel изменен режим поиска. При поиске в таблице с большим количеством данных, поиск автоматически прерывается и возобновляется по мере набора текста в редакторе. Долгий поиск можно прервать клавишей Esc. Проверьте, пожалуйста, насколько получилось удобно. |
Автор: | maratvg [ 22 дек 2016, 11:31 ] |
Заголовок сообщения: | Re: SearchPanel новые возможности |
Ваших правок недостаточно. Прерывание поиска всё еще тормозит. Могу предложить на рассмотрение наше решение: Код: procedure TCustomDBGridEh.SetSearchFilter(const FilterStr: String); ... begin FSearchFilter := FilterStr; if IsAnyKeyPress then // добавлено Exit; // добавлено ... end procedure TCustomDBGridEh.SearchFilterEvent(DataSet: TDataSet; var Accept: Boolean); begin ... Accept := False; if IsAnyKeyPress then // добавлено Exit; // добавлено ... end или вы можете сами решить куда еще нужно поставить проверки. Про поиск по таймеру думали? Когда пользователь знает что ищет и хочет ввести слово для поиска целиком, то не надо пытаться искать каждую букву и прерывать поиск, потому что нажата следующая буква. Гораздо проще выждать n-ное количество времени и один раз поискать. |
Автор: | EhLibSupport [ 01 янв 2017, 03:43 ] |
Заголовок сообщения: | Re: SearchPanel новые возможности |
Добрый день. Цитата: Если в searchpanel написать что-то по-русски (в dataset нет данных на русском), то хорошо видно, что на каждую букву происходит поиск (заметно торможение). Поиск действительно выполняется, но не удается воспроизвести эффект "(заметно торможение)". Заметно торможение чего? Каких операций? При поиске и без поиска набор текста для пользователя выполняется с той-же "обычной" скоростью. |
Автор: | maratvg [ 03 янв 2017, 08:07 ] |
Заголовок сообщения: | Re: SearchPanel новые возможности |
Понял в чем отличие вашего теста от нашего. Если вы включите FilterOnTyping в примере "Working with huge data", то получите тормоза во всей красе. Кстати, наших правок тоже оказалось недостаточно, так что вопрос остается открытым. |
Автор: | EhLibSupport [ 07 янв 2017, 11:58 ] |
Заголовок сообщения: | Re: SearchPanel новые возможности |
Добрый день. Мы добавили возможность прерывания фильтрации в сборку EhLib 9.0 Build 9.0.037. Теперь возможность изменения текста без задержки в SearchPanel должна работать и в режиме FilterOnTyping. |
Автор: | maratvg [ 24 янв 2017, 10:57 ] |
Заголовок сообщения: | Re: SearchPanel новые возможности |
Добрый день. Чтобы закончить тему с поиском хотелось бы уточнить вопрос Код: 3. Поиск нескольких слов, разделенных пробелом. Тут возможны варианты как искать: ищем любое из слов в любой из колонок или ищем записи, в которых присутствуют все слова (могут быть в разных колонках). Насколько я понял, ваш advanced поиск находится еще в стадии концепта (в виде демо). Он реализован в варианте, когда под условие попадают любые данные, где есть хотя бы одно из слов. Назовем вариант "ИЛИ". Хочется еще вариант "И", где слова задаются так же через пробел, но ищутся только те строки данных, где есть все эти слова, причем они могут встречаться в разных колонках. Смысл такого поиска в том, что мы может поискать "инженер Иван", что покажет нам всех по фамилии Иванов или по имени Иван, должность которых содержит "инженер". Ну это упрощенно. |
Автор: | EhLibSupport [ 25 янв 2017, 01:01 ] |
Заголовок сообщения: | Re: SearchPanel новые возможности |
Добрый день. Через события SearchPanel.OnSearchEditChange SearchPanel.OnCheckCellHitSearch SearchPanel.OnGetHighlightStrings можно реализовать почти любой логически-обоснованный метод поиска в гриде. Ниже приведен пример реализации событий для поиска по описанному вами алгоритму в примере <EhLib archive>\Demos\DBGridEh.SearchPanel Код: unit Frame3;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Types, Dialogs, StrUtils, DBGridEhGrouping, ToolCtrlsEh, DBGridEhToolCtrls, MemTableDataEh, Db, StdCtrls, MemTableEh, GridsEh, DBGridEh, ExtCtrls, Mask, DBCtrlsEh, DynVarsEh, EhLibVCL, DBAxisGridsEh, ComCtrls; type TfrFrame3 = class(TFrame) MemTableEh1: TMemTableEh; DataSource1: TDataSource; PageControl1: TPageControl; TabSheet1: TTabSheet; TabSheet2: TTabSheet; DBMemoEh1: TDBMemoEh; DBGridEh1: TDBGridEh; Panel2: TPanel; Label2: TLabel; procedure DBGridEh1SearchPanelCheckCellHitSearch(Grid: TCustomDBGridEh; Column: TColumnEh; var Accept: Boolean); procedure DBGridEh1SearchPanelGetHighlightStrings( Grid: TCustomDBGridEh; Column: TColumnEh; var Strings: TStringDynArray); procedure DBGridEh1SearchPanelSearchEditChange(Grid: TCustomDBGridEh; SearchEdit: TDBGridSearchPanelTextEditEh); private { Private declarations } public { Public declarations } FSearchStrArr: TStringDynArray; function WordPresentInRecord(s: String): Boolean; constructor Create(AOwner: TComponent); override; end; implementation {$R *.dfm} function FindDelimiter(const Delimiters, S: string; StartIdx: Integer = 1): Integer; var Stop: Boolean; Len: Integer; begin Result := 0; Len := Length(S); Stop := False; while (not Stop) and (StartIdx <= Len) do if IsDelimiter(Delimiters, S, StartIdx) then begin Result := StartIdx; Stop := True; end else Inc(StartIdx); end; function SplitString(const S, Delimiters: string): TStringDynArray; var StartIdx: Integer; FoundIdx: Integer; SplitPoints: Integer; CurrentSplit: Integer; i: Integer; begin Result := nil; if S <> '' then begin SplitPoints := 0; for i := 1 to Length(S) do if IsDelimiter(Delimiters, S, i) then Inc(SplitPoints); SetLength(Result, SplitPoints + 1); StartIdx := 1; CurrentSplit := 0; repeat FoundIdx := FindDelimiter(Delimiters, S, StartIdx); if FoundIdx <> 0 then begin Result[CurrentSplit] := Copy(S, StartIdx, FoundIdx - StartIdx); Inc(CurrentSplit); StartIdx := FoundIdx + 1; end; until CurrentSplit = SplitPoints; Result[SplitPoints] := Copy(S, StartIdx, Length(S) - StartIdx + 1); end; end; constructor TfrFrame3.Create(AOwner: TComponent); begin inherited Create(AOwner); // Text := 'Use Full Filter Panel facilities when the Grid is connected to TMemTableEh. Filtering in a selected area is supported'; end; function TfrFrame3.WordPresentInRecord(s: String): Boolean; var i: Integer; ColText: String; Pos: Integer; begin Result := False; s := NlsUpperCase(s); for i := 0 to DBGridEh1.Columns.Count-1 do begin ColText := NlsUpperCase(DBGridEh1.Columns[i].DisplayText); Pos := PosEx(s, ColText); if Pos > 0 then begin Result := True; Break; end; end; end; procedure TfrFrame3.DBGridEh1SearchPanelCheckCellHitSearch( Grid: TCustomDBGridEh; Column: TColumnEh; var Accept: Boolean); var S, SubStr: String; Pos: Integer; i: Integer; begin Accept := False; if Length(FSearchStrArr) = 0 then Exit; S := NlsUpperCase(Column.DisplayText); Accept := True; for i := 0 to Length(FSearchStrArr)-1 do begin if not WordPresentInRecord(FSearchStrArr[i]) then begin Accept := False; Break; end; end; if Accept then begin for i := 0 to Length(FSearchStrArr)-1 do begin SubStr := NlsUpperCase(FSearchStrArr[i]); Pos := PosEx(SubStr, S); if Pos > 0 then begin Accept := True; Break; end else Accept := False; end; end; end; procedure TfrFrame3.DBGridEh1SearchPanelGetHighlightStrings( Grid: TCustomDBGridEh; Column: TColumnEh; var Strings: TStringDynArray); var Accept: Boolean; i: Integer; begin Accept := True; for i := 0 to Length(FSearchStrArr)-1 do begin if not WordPresentInRecord(FSearchStrArr[i]) then begin Accept := False; Break; end; end; if Accept then Strings := FSearchStrArr; end; //procedure TfrFrame3.DBGridEh1SearchPanelCheckCellHitSearch( // Grid: TCustomDBGridEh; Column: TColumnEh; var Accept: Boolean); //var // S, SubStr: String; // Pos: Integer; // i: Integer; //begin // S := NlsUpperCase(Column.DisplayText); // for i := 0 to Length(FSearchStrArr)-1 do // begin // SubStr := NlsUpperCase(FSearchStrArr[i]); // Pos := PosEx(SubStr, S); // if Pos > 0 then // begin // Accept := True; // Break; // end else // Accept := False; // end; //end; //procedure TfrFrame3.DBGridEh1SearchPanelGetHighlightStrings( // Grid: TCustomDBGridEh; Column: TColumnEh; var Strings: TStringDynArray); //begin // Strings := FSearchStrArr; //end; procedure TfrFrame3.DBGridEh1SearchPanelSearchEditChange( Grid: TCustomDBGridEh; SearchEdit: TDBGridSearchPanelTextEditEh); begin FSearchStrArr := SplitString(SearchEdit.Text, ' '); end; end. |
Автор: | maratvg [ 27 авг 2018, 11:14 ] | ||
Заголовок сообщения: | Re: SearchPanel новые возможности | ||
Подниму старую тему. Вы сделали хорошие обработчики SearchPanel для организации всевозможного поиска. Почему бы не сделать еще один шаг и добавить пропертю в SearchPanel которая бы говорила какой режим поиска использовать: стандартный, продвинутый по "или" (ищутся строки, в который присутствует хотя бы одно слово из SearchPanel), продвинутый по "и" (ищутся строки, в который присутствуют все слова из SearchPanel). Примеры реализации этих поисков вы сами приводили в этой ветке. Если бы они были встроены в сам грид, было бы просто здорово. Второе. Во вложенном файле демонстрация некорректного поведения при фильтрации данных. Пояснение в видео: В SearchPanel включен FilterOnTyping. Попеременно зажимаем любую букву и Backspace. Повторяем несколько раз. Последним зажимаем Backspace. Наблюдаем тормоза. Такое ощущение, что SearchPanel применяет фильтрацию несколько раз, не дожидаясь окончания изменения строки поиска. Хочется, чтобы фильтрация запускалась по окончании изменений в строке поиска.
|
Автор: | maratvg [ 24 дек 2018, 10:13 ] |
Заголовок сообщения: | Re: SearchPanel новые возможности |
Господа разработчики. Был бы вам ужасно благодарен, если бы вы реализовали вот это: Цитата: Вы сделали хорошие обработчики SearchPanel для организации всевозможного поиска. Почему бы не сделать еще один шаг и добавить пропертю в SearchPanel которая бы говорила какой режим поиска использовать: стандартный, продвинутый по "или" (ищутся строки, в который присутствует хотя бы одно слово из SearchPanel), продвинутый по "и" (ищутся строки, в который присутствуют все слова из SearchPanel). Примеры реализации этих поисков вы сами приводили в этой ветке. Если бы они были встроены в сам грид, было бы просто здорово.
|
Автор: | Виктор [ 23 дек 2022, 13:28 ] |
Заголовок сообщения: | Re: SearchPanel новые возможности |
Предложенный 25.01.2018 EhLibSupport способ поиска нескольких вхождений неплохо работает, правда, с оговоркой: приведенная функция StringSplit наивно полагает, что число слов в строке всегда равно числу разделителей плюс 1. И если в строке присутствуют два-три пробела подряд, или есть пробелы в начале или конце строки, она выдает мусорный результат. Так что я ее переписал, заодно можно выкинуть ненужную теперь функцию FindDelimiter: Код: function SplitString(const S: string; const Delimiters: string=' '): TStringDynArray; var argLength, i, WordCount, StartIdx: Integer; begin Result:=nil; argLength:=Length(S); if argLength=0 then Exit; StartIdx:=1; // Пропускаем начальные пробелы while (StartIdx<=argLength) and IsDelimiter(Delimiters, S, StartIdx) do Inc(StartIdx); if StartIdx>argLength then Exit; WordCount:=0; // Считаем слова, разделенные пробелами или чем там еще i:=StartIdx; repeat while (i<=argLength) and (not IsDelimiter(Delimiters, S, i)) do Inc(i); Inc(WordCount); while (i<=argLength) and IsDelimiter(Delimiters, S, i) do Inc(i); until i>argLength; SetLength(Result, WordCount); WordCount:=0; // Заполняем выходной массив i:=StartIdx; repeat while (i<=argLength) and (not IsDelimiter(Delimiters, S, i)) do Inc(i); Result[WordCount]:=Copy(S, StartIdx, i-StartIdx); Inc(WordCount); while (i<=argLength) and IsDelimiter(Delimiters, S, i) do Inc(i); StartIdx:=i; until i>argLength; end; Так оно лучше. |
Страница 1 из 1 | Часовой пояс: UTC |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |