Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Сложная фильтрация, база данных 
:(
    Опции темы
MacTep
  Дата 11.10.2004, 08:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

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



У меня такой вопрос: допустим в базе данных есть несколько полей (Фамилия, Имя, Отчество, Хобби). Одно из них (например, Хобби) содержит текст, состоящий из нескольких слов (например, "коллекционирование марок"). Как отфильтровать таблицу таким образом, чтобы условием фильтрации могла быть подстрока, которая входит в строку поля, например, Хобби? Т.е. например подстрока: "кционир". Тогда программа должна отфильтровать нбор данных так, чтобы остались лишь записи, у которых в строке, которая находится в поле Хобби была такая строка, в которой есть введенная подстрока. Очень надо, а вот с какой стороный подойти, поке не додумался! Помогите, пожалуйста.


--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
Alex
Дата 11.10.2004, 08:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4147
Регистрация: 25.3.2002
Где: Москва

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



SELECT ... FROM ... WHERE UPPER(Где ищем COLLATE PXW_CYRL) CONTAINING что ищем (приведенное к верхнему регистру с помощью AnsiUpperCase)


--------------------
Написать можно все - главное четко представлять, что ты хочешь получить в конце. 
PM Skype   Вверх
MacTep
Дата 11.10.2004, 10:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

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



а через функции компонента TTable как-нибудь можно? А если черех SQL, то можно подробнее, например, весь запрос целиком. Please!


--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
Akella
Дата 11.10.2004, 13:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

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



s:=AnsiUpperCase(Edit1.Text);
s:=StringReplace(s,'*', '%', [rfReplaceAll]);//если пользователь вводить для поиска коллекц* или *колл*

Query1.Close;
Query1.SQL.Clear;
Query1.AQL.Add('SELECT * FROM Table WHERE UPPER(Field1) LIKE '+QuotedStr(s)));
Query1.Open;

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


Эксперт
***


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

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



MacTep, через функции TTable - смотри OnFilterRecords. в нём делаешь обычный Pos (...).



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


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

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



но учти, что на медленных машинах событие OnFilterRecords работает очень медленно
PM MAIL   Вверх
MacTep
Дата 11.10.2004, 13:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

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



Цитата
но учти, что на медленных машинах событие OnFilterRecords работает очень медленно
Машина вроде ничего, думаю, тормозит сильно не будет.
Цитата
через функции TTable - смотри OnFilterRecords. в нём делаешь обычный Pos (...).
Могу попросит примерчик? Делаю Pos, а потом выставляю переменную Accept?


--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
x77
Дата 11.10.2004, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



MacTep, да. например, Accept := (Pos (...) <> 0); при необходимости параметры Pos приводи к одному регистру через AnsiUpperCase.



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


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

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



x77, спасибо! А насколько этот процесс может быть медленным. Приблизительно на каких машинах и при каких размерах базы данных можно заметить тормоза?



--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
x77
Дата 11.10.2004, 16:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



это зависит впервую очередь от самого обработчика. для достаточно простых, типа Pos, будет работать довольно шустро, вполне сравнимо со скоростью классической фильтрации через свойство Filter. а вот если ты в этом обработчике будешь использовать "громоздкие" по времени операторы и функции, типа вызовов RecordCount или поиска по другой таблице, тормоза будут огромадными. в принципе для таблицы до 100000 записей особых тормозов быть не должно. но это очень расплывчато. надо пробовать для конкретной базы и смотреть.

использование условия в TQuery.SQL быстрее потому, что результирующий НД не будет фетчиться целиком, вся обработка произойдёт на стороне сервера (для парадокса его роль выполняет сама БДЕ), а в TTable - будет.


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


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

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



bFilterFilials - глобальная переменная
если true, то можно фильтровать

Код
procedure TfmMain.tZayFilterRecord(DataSet: TDataSet; var Accept: Boolean);
begin
 if bFilterFilials then
   Accept := DataSet['ZFilial'] = lcbFilials.KeyValue;
end;

procedure TfmMain.tZayFilterRecord(DataSet: TDataSet; var Accept: Boolean);
begin
 if   DataSet['ZFilial'] = 'филиал' then
 Accept := true;
end;

если Accept = true, то запись попадет в набор данных
и так попадут в набор данных все записи, которые имеют значение 'филиал' в поле 'ZFilial'


это событие срабатывает тогда, когда ты выполняешь фильтрацию, причем в свойсве
Filter не обязательно должно быть выражение фильтрации, просто выполняешь
Код
Table1.Filtered:=True

т.е. здесь можно фильтровать записи с помощью язывка высокого уровня, а не пятью операторами SQL hehe.gif



Это сообщение отредактировал(а) dsergey - 12.10.2004, 13:55
PM MAIL   Вверх
MacTep
Дата 12.10.2004, 22:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1292
Регистрация: 4.8.2003
Где: г. Самара

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



dsergey, вот ето круто, а чуть подробнее, а то слышу звон, а не знаю, где он smile.gif



--------------------
(A)bort, (R)etry, (I)gnore = Haфиг, Heфиг, Пoфиг ... :)
PM MAIL   Вверх
Akella
Дата 18.1.2005, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

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



Кстати в DRKB мало примеров на тему "Событие OnFilterRecord".
Событие OnFilterRecord срабатывает каждый раз, когда выполняется код Table1.Filtered:=True;

вот пример для одновления фильтра
Код

procedure UpdateFilter(DataSet: TDataSet);
var
 FR: TFilterRecordEvent;
begin
 with DataSet do
 begin
   FR := OnFilterRecord;
   if Assigned(FR) and Active then
   begin
     DisableControls;
     try
       OnFilterRecord := nil;
       OnFilterRecord := FR;
     finally
       EnableControls;
     end;
   end;
 end;
end;

использовать можно так
Код

Table1.Filtered := TRUE;
UpdateFilter(Table1);


сюда можно писать код сравнения, условий и т.д.
Код

procedure TForm1.tZayFilterRecord(DataSet: TDataSet; var Accept: Boolean);
begin
//пример
  Accept := DataSet['BooleanField'] = True;
end;

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

есть переменная Accept, если эта переменная в итоге получает значение True, то текущая запись будет показана, TTable переходит к следующей запси и все с начала
вот еще пример (бессмысленные, просто ради примера)
Код

procedure TForm1.tZayFilterRecord(DataSet: TDataSet; var Accept: Boolean);
var
i:integer;
begin
I:=random(100);
if i=50 then begin
 if DataSet.FieldByName('MyField').AsInteger = 50 then Accept = True;//запись будет показана
end else begin
 if DataSet.Fields[0] = 100 then accept = false;//запись не будет показана
end;
end;


Добавлено @ 16:40
чем сложнее условия, сообветственно медленее будет работать

еще пример, фильтрация на частичное совпадение.
Кстати, если работать (фильтровать) со строками, то могут быть проблемы с кодировкой и функцией Upper в SQL, а здесь SQL не применяется smile
Код

procedure TForm1.tZayFilterRecord(DataSet: TDataSet; var Accept: Boolean);
Var
s:string;
begin
 //Можно применить AnsiUpperCase
 //т.е. фильтрация без учета регистра и с частичным совпадением
 s:=AnsiUpperCase(DataSet.FieldByName('MyStringField').AsSting);
 accept:= POS(AnsiUpperCase(Edit1.Text), s) <> 0;
end;



Это сообщение отредактировал(а) dsergey - 18.1.2005, 16:41
PM MAIL   Вверх
Bes
Дата 20.1.2005, 11:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Хе... А на чем база-то?
PM MAIL   Вверх
Akella
Дата 21.1.2005, 10:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

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



У меня Paradox, но похожий алгоритм можно, наверное и на другие переложить
Добавлено @ 10:38
По крайней мере в IBQuery и IBTable тоже есть такие же события, соответственно smile

Это сообщение отредактировал(а) dsergey - 21.1.2005, 10:39
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Базы данных и репортинг"
Vit
Петрович

Запрещено:

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

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


Обязательно указание:

1. Базы данных (Paradox, Oracle и т.п.)

2. Способа доступа (ADO, BDE и т.д.)


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

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Vit, Петрович.

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


 




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


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

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