Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Delphi: Общие вопросы > поиск по базе |
Автор: Chyslyvchyk 26.7.2004, 13:03 | ||||||
В поле для поиска Edit вводится слово. Нужно: 1) пройтись ПО ВСЕМ полям базы и проверить есть ли такое слово 2) перейти к той записи, которая содержит такое слово в любом поле 3) перейти к следующей записи, которая содержит такое слово в любом поле .... Это работает:
А так - не хочет:
Ругается: Variant is not an array Такая же проблема с этим:
|
Автор: x77 26.7.2004, 13:57 | ||
ты не путай. если в FieldNames перечисляются несколько полей, то и в FieldValues надо перечислять несколько значений. а стандартного поиска по всем полям нет. но его достаточно легко реализовать:
писал навскидку, так что отлаживать придётся самому ![]() |
Автор: Chyslyvchyk 26.7.2004, 15:42 |
Тут возникает проблема в том, что Table.Fields [i].AsString и MyText должны полностью совпадать. А если человек помнит только часть поля? Например, название фирмы "Рога и копыта", а человек помнит только слово "рога"...... ![]() |
Автор: Orient 26.7.2004, 15:58 |
Тогда используй Locate: Found := FALSE; Table.First; while not Table.Eof do begin for i := 0 to Table.Fields.Count - 1 do if Table.Locate( Table.Fields [i].AsString, MyText, [ loPartialKey ] ) then begin Found := TRUE; Break; end; if Found then Break; Table.Next; end; Кстати, когда используешь Locate для поиска по нескольким полям, то писать надо вот как: Table.Locate( 'Field1;Field2', VarArrayOf( [ FieldValue1, FieldValue2 ], [] ) ) |
Автор: x77 26.7.2004, 15:58 |
Chyslyvchyk, поиск по части: if Pos (MyText, Table.Fields [i].AsString) <> 0 then ... поиск по началу: if Pos (MyText, Table.Fields [i].AsString) = 1 then ... поиск без регистра: if Pos (AnsiUpperCase (MyText), AnsiUpperCase (Table.Fields [i].AsString)) <> 0 then ... поиск без регистра по началу: if Pos (AnsiUpperCase (MyText), AnsiUpperCase (Table.Fields [i].AsString)) = 1 then ... и т.д. |
Автор: Orient 26.7.2004, 16:00 |
Кстати, не плохо было бы проверять тип поля, чтобы искать только по текстовым, а не по всем. |
Автор: x77 26.7.2004, 16:09 |
Orient, а ты когда-нибудь пробовал locate по каждому полю, если полей так штук 100, а записей - миллион - другой? |
Автор: Orient 26.7.2004, 16:19 |
x77. Честно? Нет. Но! Я немного изменил именно твой код, где перебираются именно 100 полей и вагон записей. Хочешь сказать, что банальный перебор записей быстрее чем Locate? ![]() |
Автор: Chyslyvchyk 26.7.2004, 16:33 | ||||||||
Живая задача: Форма с уймой полей: данные про клиентов. Пользователю нужно найти все данные про клиента по ключевому слову и вывести это на форму. Но сам пользователь в одном случае помнит только имя клиента, в другом - его телефон, в третьем - фирму и т.д. Решение задачи? Locate: Метод Locate ищет первую запись, удовлетворяющую критерию поиска, и если такая запись найдена, делает ее текущей. В этом случае в качестве результата возвращается True. Если запись не найдена - False. Значицца так - вот что у меня получилось с помощью x77:
Но поиск перебирает все поля, которые совпадают с SearchEd.Text и останавливается на последнем. Как его остановить на первом? Может break де-то не там находится? Добавлено @ 16:36
А что не заметно, что попытка использовать Locate уже была? ![]() Смотри первое мое сообщение. Тама было:
|
Автор: Orient 26.7.2004, 16:42 |
И чем же Locate то не подходит? Можно же по введеным данным от оператора узнать по каким полям надобно искать, закатываешь это все в Locate и находишь именно первую запись. Попытка использования Locate была, я помню. Просто я привел пример как искать по несколким полям. Добавлено @ 16:47 А не пробовал генерить динамический SQL-запрос? Будет там тебе список записей. Составлять его в зависимости от полей поиска. |
Автор: x77 26.7.2004, 18:49 | ||
Chyslyvchyk, что значит "останавливается на последнем поле"??? на уровне таблицы нет понятия "текущее поле", это понятие грида. соответственно делаем:
|
Автор: Chyslyvchyk 27.7.2004, 13:44 | ||||
Ээээээ, как это нет такого понятия??? Но записи ж нумеруются! TableClient.RecNo := 10 ---> перейти к записи с номером 10 А если после этой записи больше нет записей - значит она последняя. Разве не так?
У меня нема грида, у меня все данные таблицы выводятся в Эдиты, Комбобоксы и ДейтТаймПикеры. Проблема поиска уже решена. Спасибо всем за помошь!! ![]() |
Автор: x77 27.7.2004, 15:20 |
Chyslyvchyk, не путай поля и записи ![]() |
Автор: Chyslyvchyk 27.7.2004, 15:42 | ||
Да, да, да!! Сорри!!! ![]() Таблица состоит из записей, а запись из полей. |
Автор: Ingvar Riga 27.7.2004, 20:51 |
Грм, Уважаемые, а слабо использовать конструкцию SELECT ..... LIKE ? Вообще, при таких размерах таблиц Дурильон на Дофига желательно использовать СУБД с SQL. При этом выбор данных производиться гораздо шустрее... |
Автор: Chyslyvchyk 28.7.2004, 11:41 | ||||
Дык ведь не Дурильон на Дофига то... А с SQL мы пока не дружим.... ![]() Кому интересно, задача была решена так:
|
Автор: 78125 28.7.2004, 11:52 |
вот сморю я на код с безусловным переходом и меня аж передергивает! ![]() |
Автор: Chyslyvchyk 28.7.2004, 12:06 | ||
![]() |
Автор: Girder 28.7.2004, 12:17 |
А что тебя передергивает? Думаеш если у тебя нет переходов, то их и не будет в скомпилированной программе? |
Автор: Akella 30.7.2004, 09:02 | ||
Процедура поиска по всем полям
Пример использования [/code] FindRec(edFindText.Text,'',dm.tSpis,['Dirname','Type','PathName','Prim'],False,cbRegister.Checked,False);[CODE] |
Автор: 78125 30.7.2004, 09:57 |
Girder Я имел ввиду неоткомпилированный код.... Безусловный переход всегда можно заменить циклами и условными переходами и тд. А скомпилированный код меня не интересцует впринципе.... |