SearchKey не работает

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Sergey_Afanasyev
новенький
Сообщения: 49
Зарегистрирован: 22.02.2012 19:30:27

SearchKey не работает

Сообщение Sergey_Afanasyev »

dm.TAnketa.IndexName := 'ifam' ;
KeyValues := TRIM(Edit1.Text);
Lf := FALSE;
L := dm.TAnketa.SearchKey(KeyValues,stGreaterEqual,Lf);
if L = TRUE then DBGrid1.Refresh
else ShowMessage(' NOT FOUND ' );

Останавливается на первой записи, NOT FOUND не сообщает т.е. L = TRUE.
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

KeyValues в тип Variant не пробовали переводить?
Sergey_Afanasyev
новенький
Сообщения: 49
Зарегистрирован: 22.02.2012 19:30:27

Сообщение Sergey_Afanasyev »

KeyValues сразу был объявлен как variant, это следует из шаблона функции:
function SearchKey(Key: Variant; SearchType: TSearchKeyType): Boolean;
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

Да что Вы? Позвольте Вас опровергнуть. ;-) Вот Ваш код:
Sergey_Afanasyev писал(а):KeyValues := TRIM(Edit1.Text);

Из него со всей очевидностью следует, что у Вас KeyValues объявлено как string и ни какой шаблон функции тут не при чём.
Sergey_Afanasyev
новенький
Сообщения: 49
Зарегистрирован: 22.02.2012 19:30:27

Сообщение Sergey_Afanasyev »

Тип данных variant позволяет менять тип соответствующих ему
данных прямо во время программы, т.е. можно записать:

var KeyValues : variant;
begin
KeyValues := 1.5;
KeyValues := 'Иванов И.И.';
KeyValues := TRUE;
И, наконец, KeyValues :=TRIM(Edit1.Text);
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

Наверное Вы меня не поняли. Вы НЕ УКАЗАЛИ в своём коде, какой тип данных у переменной KeyValues. То что знаете Вы - не знаю я, поэтому будьте добры отвечайте на поставленный вопрос.
У Вас в БД строки в какой кодировке хранятся и в какой кодировке Вы даёте строку для поиска?
Sergey_Afanasyev
новенький
Сообщения: 49
Зарегистрирован: 22.02.2012 19:30:27

Сообщение Sergey_Afanasyev »

Все таблицы БД хранятся в кодировке UTF 8.

Добавлено спустя 1 час 45 минут 24 секунды:
Что интересно, такой способ поиска, как Locate тоже не работает.
Это касается поиска по фамилии сотрудника. Но вместо фамилии пользователь может ввести идентификационный код человека. Это тоже сивольное данное состоящее из 10 цифр. Программа распознает по первому символу, что ввели подключает соответствующий индекс и осуществляет поиск. Так вот поиск по коду работает и в SearchKey и в Locate. В чем разница? Разница в том, что цифры в кодирорвке UTF8 занимают по одному байту, а русские буквы по два.
Аватара пользователя
alexs
долгожитель
Сообщения: 4069
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

Sergey_Afanasyev писал(а):Разница в том, что цифры в кодирорвке UTF8 занимают по одному байту, а русские буквы по два.

А в чём проблема?

Код: Выделить всё

S:=Trim(Edit1.Text);
C:=Val(S, R);
if R = 0 then
  Поиск по коду
else
  Поиск по фамилии

И нет никаких проблема что текст в UTF8
Sergey_Afanasyev
новенький
Сообщения: 49
Зарегистрирован: 22.02.2012 19:30:27

Сообщение Sergey_Afanasyev »

Уважаемый alexs ! Проблема не в том как организовать поиск по коду или фамилии, а в том, что SearchKey и Locate не ищут по фамилии.
Аватара пользователя
alexs
долгожитель
Сообщения: 4069
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь
Контактная информация:

Сообщение alexs »

А доступ к данным чем организован? В чем хранится и какие компоненты доступа?
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

alexs
Товарищ работает с TDbf, т.к. SearchKey больше нигде не осталось.

Добавлено спустя 2 минуты 38 секунд:
Sergey_Afanasyev
У меня есть определённые подозрения на этот счёт, но чтобы их проверить, попробуйте:
1) в поле фамилии ввести слова на английском и посмотреть, будет ли осуществлятся поиск с помощью SearchKey() этих английских слов.
2) Удалите индекс по полю фамилий (именно удалите, а не отключите и вообще любые индексы, в которые включено поле фамилий) и ищите русские фамилии с помощью Locate() без опции loPartialKey. Что будет?
Sergey_Afanasyev
новенький
Сообщения: 49
Зарегистрирован: 22.02.2012 19:30:27

Сообщение Sergey_Afanasyev »

Если удалить индексный файл, то Locate работает. Спасибо за помощь.
Vadim
долгожитель
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Сообщение Vadim »

Sergey_Afanasyev
В общем, вот моя мысль по этому поводу, которую Вы косвенно подтвердили. :-)
TDbf до сих пор считает, что строка в таблице - исключительно однобайтная и поэтому строит индексы исходя из этого принципа. Поэтому в индексах, в случае применения многобайтных алфавитов, творится сущая билиберда. SearchKey() работает исключительно с индексами, поэтому и результат поиска такой абсурдный. Locate() же работает с индексами только если они есть, если нету, то производит поиск обычным перебором строк и хотя теряет при этом в скорости, но имеет нужный результат, когда сравнение происходит на предмет полного соответствия.
Sergey_Afanasyev
новенький
Сообщения: 49
Зарегистрирован: 22.02.2012 19:30:27

Сообщение Sergey_Afanasyev »

Если TDbf не работает с многобайтными алфавитами, то как объяснить тот факт, что когда программа обнаруживает, что поиск будет по фамилии и выбирает соответствующий индекс
dm.TAnketa.IndexName := 'ifam' ;
в Гриде, который расположен на форме, данные действительно выстраиваются по алфавиту. Но
Locate и SearchKey при этом не работают.
Аватара пользователя
Vapaamies
постоялец
Сообщения: 292
Зарегистрирован: 24.07.2012 22:37:59
Откуда: Санкт-Петербург
Контактная информация:

Сообщение Vapaamies »

Мне кажется, что индекс строится по байтам, и ему всё равно, какие данные на входе. Но байты, поступающие на вход SearchKey, отличаются от байтов, по которым построен индекс, поэтому ничего и не находится. Предполагаю, что индекс строится по фактическому представлению данных в DBF в однобайтовой кодировке (1251 или 866), а SearchKey передает строку UTF-8.
Ответить