Как мне найти запись (осуществить 'Find') в TQuery?
Я привел ниже код, который я использую в своей работе, правда, в нем еще необходимо организовать обработку исключительных ситуаций, но это дело времени. Когда пользователь нажимает кнопку "Найти", обработчик события OnClick вызывает процедуру SearchName.
Объявляем: FindSearch : Boolean и инициализируем значением True.
function LookForString(target, source: string): boolean;
{ в случае игнорирования перед вызовом pos необходимо
преобразовать source и target в верхний регистр }begin
LookForString := pos(target, source);
end;
procedure SearchName(searchtype: string; stringtofind: string);
var
OldCursor: TCursor;
CurrentPos: TBookmark;
found: boolean;
beginif Form1.Query1.State = dsEdit then
Form1.Query1.Post;
if StringToFind = '' then
exit;
OldCursor := Screen.Cursor;
Screen.Cursor := crHourGlass;
with Form1 dobegin
CurrentPos := Query1.GetBookmark;
Query1.DisableControls;
found := false;
if searchtype <> 'prev' then{ первый или следующий }beginif searchtype = 'first' then
Query1.First
elseifnot Query1.EOF then
Query1.Next;
while (not Query1.EOF) and (not found) dobeginif LookForString(StringToFind, MemberName) <> 0 then
found := true;
ifnot found then
Query1.Next;
end;
endelsebegin{ prev }ifnot Query1.BOF then
Query1.Prior;
while (not Query1.BOF) and (not found) dobeginif LookForString(StringToFind, MemberName) <> 0 then
found := true;
ifnot found then
Query1.Prior;
end;
end;
Screen.Cursor := OldCursor;
if found thenbegin
FindSearch := false;
ChangeFindCaption;
UpdateStatusLabel;
endelsebegin
MessageDlg('Больше ничего не найдено.', mtInformation,
[mbOK], 0);
Query1.GotoBookmark(CurrentPos);
end;
Query1.EnableControls;
Query1.FreeBookmark(CurrentPos);
end; { конец работы с Form1 }end;
procedure TForm1.FindButtonClick(Sender: TObject);
beginif FindSearch then
SearchName('first', Page0Edit.Text)
else
SearchName('next', Page0Edit.Text);
end;
Перевод текста на русский язык:
Код, предоставленный ниже, написан на Delphi и использует компонент TQuery для взаимодействия с базой данных. Цель - найти конкретный рекорд в базе данных по строке поиска, введенной пользователем.
Следующий процесс происходит при клике кнопки "Найти":
При клике кнопки "Найти" вызывается процедура SearchName.
В SearchName код сначала проверяет, находится ли запрос в режиме редактирования и отправляет любые pending обновления.
Если строка поиска пустая, процедура выходит без выполнения дальнейших действий.
Код отключает контролы запроса, чтобы предотвратить взаимодействие пользователя с базой данных во время поиска.
Он устанавливает маркер для текущей позиции в запросе с помощью Query1.GetBookmark.
В зависимости от того, является ли это первым или следующим поиском, код либо перемещается к первому рекорду (Query1.First), либо к следующему (Query1.Next).
Пока не достигнут конца результата и не найден, код проверяет, содержит ли текущий рекорд строку поиска, вызывая LookForString. Если он содержит, то устанавливает флаг found в True.
Если флаг все еще False после проверки всех рекордов, код перемещается к следующему (Query1.Next).
После выполнения поиска код восстанавливает контролы запроса и маркер, а также обновляет GUI.
Функция LookForString просто ищет целевую строку в исходной строке с помощью встроенной функции Delphi Pos, которая возвращает позицию первого вхождения целевой строки в исходную строку. Если целевая строка не найдена, она возвращает 0.
Для улучшения этого кода можно добавить более robust ошибку обработки для случаев, когда запрос fails или строка поиска является недопустимой. Может быть также полезно добавить визуальное обратное отображение при выполнении поиска, например, курсор busy или прогресс-бар.
Вот альтернативное решение с использованием TADOTable вместо TQuery:
procedureTForm1.SearchName(searchtype:string;stringtofind:string);varOldCursor:TCursor;found:boolean;beginifForm1.ADOQuery1.State=dsEditthenForm1.ADOQuery1.Post;ifStringToFind=''thenexit;OldCursor:=Screen.Cursor;Screen.Cursor:=crHourGlass;tryForm1.ADOQuery1.DisableControls;found:=false;ifsearchtype<>'prev'thenbeginForm1.ADOQuery1.First;whilenotForm1.ADOQuery1.EofandnotfounddobeginifLookForString(StringToFind,ADOQuery1.FieldByName('MemberName').AsString)>0thenfound:=true;ifnotfoundthenForm1.ADOQuery1.Next;end;elsebeginForm1.ADOQuery1.Last;whilenotForm1.ADOQuery1.BeforeFirstandnotfounddobeginifLookForString(StringToFind,ADOQuery1.FieldByName('MemberName').AsString)>0thenfound:=true;ifnotfoundthenForm1.ADOQuery1.Prior;end;end;Screen.Cursor:=OldCursor;iffoundthenbeginFindSearch:=false;ChangeFindCaption;UpdateStatusLabel;elsebeginMessageDlg('Больше ничего не найдено.',mtInformation,[mbOK],0);Form1.ADOQuery1.GotoBeginning;end;Form1.ADOQuery1.EnableControls;finallyScreen.Cursor:=OldCursor;end;end;procedureTForm1.FindButtonClick(Sender:TObject);beginifFindSearchthenSearchName('first',Page0Edit.Text)elseSearchName('next',Page0Edit.Text);end;
В этом коде используется TADOTable вместо TQuery, а также включен блок try-finally для обеспечения восстановления курсора даже в случае возникновения исключения при выполнении поиска.
В статье описывается способ поиска записи в TQuery с помощью процедуры SearchName, которая выполняет поиск в направлении "первого" или "следующего" элемента, соответствующего введенному строковому параметру.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.