Модераторы: Poseidon, Snowy, bems, MetalFan

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> поиск по базе, TTable 
:(
    Опции темы
Chyslyvchyk
Дата 26.7.2004, 13:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 446
Регистрация: 9.5.2004

Репутация: 1
Всего: 5



В поле для поиска Edit вводится слово.
Нужно:
1) пройтись ПО ВСЕМ полям базы и проверить есть ли такое слово
2) перейти к той записи, которая содержит такое слово в любом поле
3) перейти к следующей записи, которая содержит такое слово в любом поле
....

Это работает:
Код

...
var LookUpResults: Variant;
...
LookUpResults:=Table.Lookup('Surname', SearchEd.Text, 'Surname;Name');
If VarIsArray(LookUpResults) then
  begin
    If LookUpResults[0] <> Null then SurnameEd.Text:=LookUpResults[0];
    If LookUpResults[1] <> Null then NameEd.Text:=LookUpResults[1];


А так - не хочет:

Код
...
...
LookUpResults:=Table.Lookup('Surname;Name', SearchEd.Text, 'Surname;Name');
...

Ругается: Variant is not an array

Такая же проблема с этим:
Код
Table.Locate('Surname;Name', SearchEd.Text, [loCaseInsensitive])


Это сообщение отредактировал(а) Chyslyvchyk - 26.7.2004, 16:37


--------------------
Простота - сестра таланта!
PM MAIL   Вверх
x77
Дата 26.7.2004, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



ты не путай. если в FieldNames перечисляются несколько полей, то и в FieldValues надо перечислять несколько значений. а стандартного поиска по всем полям нет. но его достаточно легко реализовать:

Код

 Found := FALSE;
 Table.First;
 while not Table.Eof do begin
   for i := 0 to Table.Fields.Count - 1 do
     if Table.Fields [i].AsString = MyText then begin
       Found := TRUE;
       Break;
     end;
   if Found then
     Break;
   Table.Next;
 end;


писал навскидку, так что отлаживать придётся самому smile.gif


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
Chyslyvchyk
Дата 26.7.2004, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 446
Регистрация: 9.5.2004

Репутация: 1
Всего: 5



Тут возникает проблема в том, что Table.Fields [i].AsString и MyText должны полностью совпадать.
А если человек помнит только часть поля? Например, название фирмы "Рога и копыта", а человек помнит только слово "рога"...... smile.gif


--------------------
Простота - сестра таланта!
PM MAIL   Вверх
Orient
Дата 26.7.2004, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 144
Регистрация: 17.7.2004

Репутация: нет
Всего: нет



Тогда используй 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 ], [] ) )

PM MAIL   Вверх
x77
Дата 26.7.2004, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



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 ...

и т.д.


--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
Orient
Дата 26.7.2004, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 144
Регистрация: 17.7.2004

Репутация: нет
Всего: нет



Кстати, не плохо было бы проверять тип поля, чтобы искать только по текстовым, а не по всем.
PM MAIL   Вверх
x77
Дата 26.7.2004, 16:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



Orient, а ты когда-нибудь пробовал locate по каждому полю, если полей так штук 100, а записей - миллион - другой?



--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
Orient
Дата 26.7.2004, 16:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 144
Регистрация: 17.7.2004

Репутация: нет
Всего: нет



x77.
Честно? Нет. Но! Я немного изменил именно твой код, где перебираются именно 100 полей и вагон записей. Хочешь сказать, что банальный перебор записей быстрее чем Locate? smile.gif В принципе, на самом деле, мне хотелось бы знать живую задачу, когда нужно делать поиск по всем полям. Может тут имеются проблемы со структурой БД, и все можно сделать проще? Если конечно можно.
PM MAIL   Вверх
Chyslyvchyk
Дата 26.7.2004, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 446
Регистрация: 9.5.2004

Репутация: 1
Всего: 5



Живая задача:
Форма с уймой полей: данные про клиентов. Пользователю нужно найти все данные про клиента по ключевому слову и вывести это на форму. Но сам пользователь в одном случае помнит только имя клиента, в другом - его телефон, в третьем - фирму и т.д.
Решение задачи?
Locate:
Метод Locate ищет первую запись, удовлетворяющую критерию поиска, и если такая запись найдена, делает ее текущей. В этом случае в качестве результата возвращается True. Если запись не найдена - False.


Значицца так - вот что у меня получилось с помощью x77:
Код

var i:integer;
     Found:boolean;
begin
 Found := FALSE;
 while not Table.Eof do
 begin
    for i := 0 to Table.Fields.Count - 1 do
    begin
      if Pos (AnsiUpperCase(SearchEd.Text), AnsiUpperCase(Table.Fields [i].AsString)) <> 0 then
      begin
      SurnameEd.Text := Table.FieldByName('Surname').AsString;
      ...
      Found := TRUE;
      Break;
      end;
    end;
  Table.Next;
  end;

      if Found = FALSE then
      begin
      ShowMessage('no record');
      end;
end;

Но поиск перебирает все поля, которые совпадают с SearchEd.Text и останавливается на последнем. Как его остановить на первом? Может break де-то не там находится?

Добавлено @ 16:36
Цитата(Orient @ 26.7.2004, 15:58)
.....
Кстати, когда используешь Locate для поиска по нескольким полям, то писать надо вот как: Table.Locate( 'Field1;Field2', VarArrayOf( [ FieldValue1, FieldValue2 ], [] ) )

А что не заметно, что попытка использовать Locate уже была? smile.gif

Смотри первое мое сообщение. Тама было:
Цитата

.....
Такая же проблема с этим:
Код

Table.Locate('Surname;Name', SearchEd.Text, [loCaseInsensitive])


Это сообщение отредактировал(а) Chyslyvchyk - 26.7.2004, 16:42


--------------------
Простота - сестра таланта!
PM MAIL   Вверх
Orient
Дата 26.7.2004, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 144
Регистрация: 17.7.2004

Репутация: нет
Всего: нет



И чем же Locate то не подходит?
Можно же по введеным данным от оператора узнать по каким полям надобно искать, закатываешь это все в Locate и находишь именно первую запись.


Попытка использования Locate была, я помню. Просто я привел пример как искать по несколким полям.
Добавлено @ 16:47
А не пробовал генерить динамический SQL-запрос?
Будет там тебе список записей. Составлять его в зависимости от полей поиска.

Это сообщение отредактировал(а) Orient - 26.7.2004, 16:44
PM MAIL   Вверх
x77
Дата 26.7.2004, 18:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



Chyslyvchyk, что значит "останавливается на последнем поле"??? на уровне таблицы нет понятия "текущее поле", это понятие грида. соответственно делаем:

Код

 if Pos (...) then begin
   DbGrid1.SelectedField := Table1.Fields [i];
   Found := TRUE;
   ...




--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
Chyslyvchyk
Дата 27.7.2004, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 446
Регистрация: 9.5.2004

Репутация: 1
Всего: 5



Цитата
Chyslyvchyk, что значит "останавливается на последнем поле"??? на уровне таблицы нет понятия "текущее поле", это понятие грида.

Ээээээ, как это нет такого понятия??? Но записи ж нумеруются!
TableClient.RecNo := 10 ---> перейти к записи с номером 10
А если после этой записи больше нет записей - значит она последняя. Разве не так?

Цитата
... это понятие грида. соответственно делаем:

У меня нема грида, у меня все данные таблицы выводятся в Эдиты, Комбобоксы и ДейтТаймПикеры.



Проблема поиска уже решена. Спасибо всем за помошь!!
thumbs-up.gif


--------------------
Простота - сестра таланта!
PM MAIL   Вверх
x77
Дата 27.7.2004, 15:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Участник Клуба
Сообщений: 1255
Регистрация: 25.3.2002

Репутация: 19
Всего: 22



Chyslyvchyk, не путай поля и записи smile.gif ты сказал, что "останавливается на последнем поле", поля можно делать "текущими" только в гриде, но не в таблице, таблицы оперируют с записями.



--------------------
Я никогда не сопротивлялся искушению, поскольку узнал: что мне
не нравится, то меня не искушает.
© Джордж Бернард Шоу (Ирландия)
PM MAIL ICQ   Вверх
Chyslyvchyk
Дата 27.7.2004, 15:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 446
Регистрация: 9.5.2004

Репутация: 1
Всего: 5



Цитата(x77 @ 27.7.2004, 15:20)
Chyslyvchyk, не путай поля и записи smile.gif ты сказал, что "останавливается на последнем поле", поля можно делать "текущими" только в гриде, но не в таблице, таблицы оперируют с записями.

Да, да, да!! Сорри!!! adv/yes.gif
Таблица состоит из записей, а запись из полей.

Это сообщение отредактировал(а) Chyslyvchyk - 27.7.2004, 15:51


--------------------
Простота - сестра таланта!
PM MAIL   Вверх
Ingvar Riga
Дата 27.7.2004, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 31.3.2004

Репутация: нет
Всего: нет



Грм, Уважаемые, а слабо использовать конструкцию SELECT ..... LIKE ?
Вообще, при таких размерах таблиц Дурильон на Дофига желательно использовать СУБД с SQL. При этом выбор данных производиться гораздо шустрее...
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Общие вопросы"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0870 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.