Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» DBGridEh query и скрытие записей

Автор: ironwit
Дата сообщения: 12.06.2003 13:00
Задача.

нужно проверить все поля и все записи в query на наличие в строках подстроки, в каких записях\полях есть подстрока - те записи оставляем, в каких нет - нужно скрыть. Причем если подстрока меняется, то нужно начать все с нуля, не делая никаких дополнительных запросов к query. Вот собственно вопрос. Если невнятно пояснил, уточняйте
Автор: MrZeRo
Дата сообщения: 12.06.2003 16:11
ironwit
В Query написать обработчик OnFilterRecord и установить Filtered := True.
При изменении подстроки "передернуть" Filtered:
Filtered := False;
Filtered := True;

Обработчик OnFilterRecord - что-то вроде следующего:

Accept :=True;
for i:=0 to DataSet.FieldCount-1 do
if Pos(s, DataSet.Fields[i].AsString)<>0 then
begin
Accept := False;
exit;
end;

Автор: ironwit
Дата сообщения: 12.06.2003 16:29
MrZeRo
спасибо за идею. В итоге получилось такое

Accept :=false;
for i:=0 to DataSet.FieldCount-1 do
if length(edit1.text)>0 then
begin
if Pos(edit1.text, DataSet.Fields[i].AsString)<>0 then
begin
Accept := true;
exit;
end;
end else
Accept := true;
Автор: MrZeRo
Дата сообщения: 12.06.2003 16:50
ironwit
Что-то твой код не выглядит оптимальным. Если при нулевой длине текста Accept должно быть True, то лучше было бы написать так:

{$B-} //на всякий случай, для повышения производительности
if (length(edit1.text)=0) or ((length(edit1.text)>0) and (Pos(edit1.text, DataSet.Fields[i].AsString)<>0)) then
begin
Accept := true;
exit;
end;
Автор: ironwit
Дата сообщения: 13.06.2003 07:25
MrZeRo

Цитата:
length(edit1.text)

а не получается ли при твоей оптимизации что два раза идет проверка длины строки?

P.S.
Цитата:
{$B-}
это чего значит?
Автор: MrZeRo
Дата сообщения: 13.06.2003 11:31
ironwit
{$B-} - это отключение полного вычисления логических выражений (Complete boolean evaluation). В данном случае если не выполнится условие length(edit1.text)>0, то Pos и вычисляться не будет, так как в любом случае результат будет false.
Я обратил на это внимание, так как OnFilterRecord должно максимально быстро вычисляться.
Конечно, можно было бы сначала вычислить длину строки, а потом ею оперировать, с возражением согласен. Просто я попытался исправить то, что бросилось в глаза в твоем варианте - продолжение цикла в случае если Accept=true при Length(..)=0.
Говорят, в чужом глазу соринку видно, так что не суди строго
Хотелось помочь.
Автор: ironwit
Дата сообщения: 13.06.2003 12:07
тады так

Accept :=false;
for i:=0 to DataSet.FieldCount-1 do
if length(edit1.text)>0 then
begin
if Pos(edit1.text, DataSet.Fields[i].AsString)<>0 then
begin
Accept := true;
exit;
end;
end else
begin
Accept := true;
exit;
end;

таким образом длина строки вычисляется только один раз. И цикл завершается.
Автор: MrZeRo
Дата сообщения: 13.06.2003 13:03
ironwit
Не возражаю.
Единственно, что можно еще добавить, в зависимости от твоих данных, может, было бы более рационально начинать поиск с Accept:=True и инвертировать условия поиска. Это зависит от того, больше ли вероятности найти Accept=True или Accept=False, то есть какое из этих условий наиболее вероятно найти как можно быстрее, чтобы прекратить цикл. Я бы рекомендовал реализовать оба варианта и при работе сохранять количество проходов в каждом случае, а потом выбрать алгоритм, который работает быстрее. (хотя это зависит от задачи, может, и сразу будет ясно, как быстрее)

Страницы: 1

Предыдущая тема: Синтез звуков в C#


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.