Как использовать TClientDataSet для поиска содержащей строки

Я использую Делфи 2007.

Я знаю, что могу использовать метод .locate TClientDataSet для поиска записи, например:

myClient.locate('имя','Джон',[loPartialKey,loCaseInsensitive]);

Но допустим, я хочу найти любую запись с именем «Джон», содержащим в своем имени что-то вроде

имя типа '%Джон%'

будет делать в регулярном выражении SQL.

Возможно ли это с помощью метода .locate?

Кажется, что [loPartialKey] работает как начальный, а не содержащий.


person delphirules    schedule 03.12.2019    source источник
comment
Вы пытались использовать метод поиска, не уверенный, что это в 2007 году? edn.embarcadero.com/article/29176   -  person Deleted    schedule 03.12.2019


Ответы (4)


В .Locate loPartialKey соответствует первому символу в значении поля, поэтому вы не можете делать то, что хотите, используя только .Locate.

Однако свойство Filter TClientDataSet может содержать like, как при установке свойства Filter CDS на

AField like '%w%'  // matches all AField values containing `w`

или, в коде,

  ClientDataset1.Filtered := False;
  ClientDataset1.Filter :=  'AField like ' + QuotedStr('%' + edFilter.Text + '%');
  ClientDataset1.Filtered := True;

поэтому вы можете использовать фильтр, чтобы сузить количество строк, и использовать «Найти», чтобы найти конкретную, или просто перебрать отфильтрованные строки, чтобы найти именно ту, которая вам нужна.

person MartynA    schedule 03.12.2019
comment
Вы уверены насчет AField? - person Ilyes; 03.12.2019
comment
@Sami: Да, AField - это имя поля. Это, безусловно, работает в D7. - person MartynA; 03.12.2019
comment
Да, я знаю, что вы имели в виду, но это должна быть строка 'FieldName', и вы также должны использовать QuotedStr() вместо '%w%'. Что-то вроде := 'AField like ' + QuotedStr('%w%'); - person Ilyes; 03.12.2019
comment
@ Сами, извините, то, что я процитировал, без кавычек вокруг AField отлично работает, если вводить его с помощью редактора свойств. Спасибо, что поймали это. Я не могу сразу увидеть, что QuotedStr будет иметь какое-либо значение для RHS, но это был долгий день. - person MartynA; 04.12.2019
comment
Я полагаю, вы устали :). но свойство Filter представляет собой строку, поэтому, когда вы передаете строку, как вы предлагаете, она будет 'AField LIKE %w%'. Это действительно? - person Ilyes; 04.12.2019
comment
Хорошо, не знал, что выражение фильтра может содержать как! - person delphirules; 04.12.2019
comment
@Sami: я обновил его, чтобы показать настройку фильтра в коде. Также я могу подтвердить, что при установке через свойство Filter CDS кавычки вокруг %w% не требуются, что, как вы заметили, немного любопытно. Я напомню себе, как анализируется выражение фильтра, и посмотрю, покажет ли это причину. - person MartynA; 04.12.2019

Нет. С первой частью можно частично совпадать. Как упоминалось в справке для «Использование Locate».

Найти перемещает курсор в первую строку, соответствующую заданному набору критериев поиска. В простейшей форме вы передаете Locate имя столбца для поиска, значение поля для сопоставления и флаг параметров, указывающий, является ли поиск нечувствительным к регистру или может ли он использовать сопоставление с частичным ключом. (Частичное сопоставление ключей — это когда строка критерия должна быть только префиксом значения поля.) Например, следующий код перемещает курсор в первую строку в таблице CustTable, где значением в столбце «Компания» является «Professional Divers, Ltd. .":

var
  LocateSuccess: Boolean;
  SearchOptions: TLocateOptions;
begin
  SearchOptions := [loPartialKey];
  LocateSuccess := CustTable.Locate('Company', 'Professional Divers, Ltd.', SearchOptions);
end;

ссылка: онлайн-документация Delphi: Использование Locate

person Brian    schedule 03.12.2019

LocateRecord внутренне использует DSCursor.LocateWithFilter, поэтому я считаю, что можно написать собственный метод, делающий то, что вы хотите.

person vavan    schedule 06.12.2019

Лучше использовать .FindFirst и .FindNext :

myDataset.Filter := 'CustomerName LIKE ' + ('*' + edtSearch.Text + '*').QuotedString;
myDataset.Filtered := False;
Found :=  myDataset.FindFirst

if Found then

Используйте .Locate, когда вы хотите найти ключ, точное значение которого вы знаете.

И использование только Filtered := true будет работать в ситуациях, когда вы не возражаете, если другие записи исчезнут в dbGrid.

person Omid Mehdizadeh    schedule 02.06.2021