Форум: "Базы";
Текущий архив: 2005.11.06;
Скачать: [xml.tar.bz2];
ВнизПоиск по контексту с помощью SQL запроса Найти похожие ветки
← →
Jioniro (2005-09-22 11:47) [0]Привет всем!!!
Имеется таблица Paradox с наименованиями товаров(String[254]).
Выполняю поиск по контексту с помощью запроса
SELECT Name FROM "Art.db" Art where
(UPPER(Name) LIKE ""%"+AnsiUpperCase(Edit1.Text)+"%"")
и результат вывожу в DbGrid. Запрос выполняется при каждом изменении
значения Edit1.Text.
Таблица имеет порядка 20000 записей. Как можно догадаться поиск выполняется с задержками
1-2 сек (при выполнении запроса).
Подскажите плз можно ли ускорить выполнение запроса или предложите другой
способ поиска по контексту.
← →
Chris © (2005-09-22 11:51) [1]Ха! Засунуть столбец Name в безразмерный массив и поиск осуществлять уже в памяти.
← →
Val © (2005-09-22 11:51) [2]Задержку небольшую на выполнение запроса при изменении текста выставить, чтоб не на каждый вводимый символ сразу запрос шел.
← →
Sergey13 © (2005-09-22 11:52) [3]>Запрос выполняется при каждом изменении значения Edit1.Text.
Т.е. при вводе следующей буквы пошел запрос? А нафига. Ввел то что хотел полностью - "нажми на кнопку получишь результат".
Запросы с LIKE "%....." по определению тормозные.
← →
sniknik © (2005-09-22 11:53) [4]> или предложите другой способ поиска по контексту
сделай кнопочку "искать" рядом с Edit1. пусть юзер сам решает когда ему его(поиск/выборку) делать.
← →
Jioniro (2005-09-22 12:26) [5]Дело в том что операции поиска юзер должен делать постоянно, а нажатие на клавишу "искать" - это лишняя операция, что делает программу неудобной...
>Ха! Засунуть столбец Name в безразмерный массив и поиск осуществлять уже в памяти.
не совсем понял... если можно кусочек кода плз.
← →
Val © (2005-09-22 13:02) [6]>Jioniro (22.09.05 12:26)
что попало...до чего же народ любит себе на задницу искать..
нажатие ввода-проблема? вам поисковики неудобны? или раскройте задачу полнее, вместо того, чтоб все записи тянуть в память, а там искать..хотя - хозяин - барин - таки сам поиск будет быстрее :)
← →
Курдль © (2005-09-22 13:25) [7]Такие проблемы (при небольшом количестве записей) решаются по OnFilterRecords в DataSet-е.
← →
evvcom © (2005-09-22 13:31) [8]+ используй параметры. На парсинг тоже время тратится.
← →
Курдль © (2005-09-22 13:32) [9]Подработайте под свою задачу рабочий код:
procedure TfrmSubjects.dxFilterCurChange(Sender: TObject);
begin
inherited;
FFilterValue := AnsiUpperCase((Sender As TdxBarEdit).CurText);
(Sender As TdxBarEdit).Text := (Sender As TdxBarEdit).CurText;
FilterDataSet;
end;
procedure TfrmSubjects.FilterDataSet;
begin
sdqSubjects.DisableControls;
try
sdqSubjects.Filtered := false;
FField := dxDBGrid1.FocusedField;
sdqSubjects.Filtered := (FFilterValue <> "") and (FField <> nil);
finally
sdqSubjects.EnableControls;
end;
end;
← →
msguns © (2005-09-22 13:43) [10]>Курдль © (22.09.05 13:32) [9]
>Подработайте под свою задачу рабочий код:
А ты уверен, что включение фильтра, сканирование исх. НД с переносом данных в некий грид (очевидно, не TDBGrid), затем его выключение и позиционирование НД к исходной точке будет выполняться быстрее, чем простой запрос ? Да еще по каждому тыку по клаве юзера.
Прежде чем советовать, попробуй сам - увидишь, что получится ;)
>Jioniro (22.09.05 12:26) [5]
>Дело в том что операции поиска юзер должен делать постоянно, а нажатие на клавишу "искать" - это лишняя операция, что делает программу неудобной...
"Лишним" будет дерганье картинки на мониторе с тормозами, когда я, как пользователь, захочу найти все записи с "Jioniro". Прежде чем мне удасться ввести все 7 букв, комп 6 раз задумается и моргнет экраном, хотя я четко знаю, что мне нужно.
← →
sniknik © (2005-09-22 13:46) [11]> Такие проблемы (при небольшом количестве записей) решаются по OnFilterRecords в DataSet-е.
не. это проблема менталитета... и решается или приказом, заставить делать как нужно, или долгими уговорами (не помогут) и последующим печальным опытом, когда нарвется на особо вредного пользователя (который в сердцах не по монитору стукнет а по стяшему рядом разработчику... ;)
допустим я пользователь этой системы... (не дай бог ;) вижу в данных какую то ахинею, вот она рядом. подозреваю не одна запись с подобным "мусором" есть. пытаюсь отфильтровать по этой ахинее (например псевдографика или др. "нестандартные" символы, или просто трудно запоминаемый набор символов), вроде решение очевидно "срисовать" весь набор, и нажать поиск... но ваша система очевидного не даст сделать, любое ошибочное нажатие клавиши просто "сбросит" данные с экрана, и не факт, что удаление этого лишнего символа вернет прошлые значения на экран... и т.д.
в общем предвижу много "ласковых" слов от юзеров в адресраз работчика. ;о))
p.s. если уж делать подобное то хотябы не на каждое нажатие кнопки, а по таймауту, когда активный ввод значения предположительно прекратился.
← →
Курдль © (2005-09-22 13:46) [12]2 msguns ©
А вот здесь ты не прав! Особенно насчет "попробуй"! :)
Код взят из базового класса списочных форм, успешно работающих во многих приложениях. Ты еще кнопку не успеешь отпустить, как фильтр уже отработает!
← →
Jioniro (2005-09-22 13:52) [13]>Val
Подробнее задача выглядит след образом:
Ассортимент магазина порядка 20000 наименований товара,
когда приходит накладная на товар ее необходимо быстро ввести и
передать продавцам цены, ценники и т.д.
Наименование товара выглядит примерно так -
"Масло Долина Сканди 400 гр 80% Легкое Щвеция"
Сам понимаешь поиск в 20000 таких записей должен быть удобным и с минимальным кол-вом операций. При этом он должен быть по нескольким контекстам потому что глупый юзер может назвать запись -
"Долина Сканди Масло 400 гр 80% Легкое Щвеция" или ещё как-нить,
кстати задержку попробовал - к сожалению не подходит.
← →
msguns © (2005-09-22 13:53) [14]>sniknik © (22.09.05 13:46) [11]
SELECT Name FROM "Art.db" Art where
(UPPER(Name) LIKE ""%"+AnsiUpperCase(Edit1.Text)+"%"")
и результат вывожу в DbGrid. Запрос выполняется
Найденные записи отображаются в другом гриде. Исходный не трогается.
>Курдль © (22.09.05 13:46) [12]
>А вот здесь ты не прав! Особенно насчет "попробуй"! :)
>Код взят из базового класса списочных форм
"Базовый" класс работает с парадоксом на сети ? И исходный (фильтруемый) НД получен через TXXTable ?
← →
Sergey13 © (2005-09-22 13:59) [15]ИМХО, самое правильное (с интерфейсной точки зрения) и простое это отловить в Едите клавишу "Enter" и/или потерю фокуса и вызвать при этом обработчик кнопки "Искать".
← →
sniknik © (2005-09-22 14:11) [16]для накладных самый удобный ввод по баркоду со сканера штрихкодов товара, одно нажатие (просто пронос товара мимо сканера) и никакой путаници. баркоды уникальны (некоторые исключения есть но это именно исключения).
← →
Jioniro (2005-09-22 14:17) [17]Нет поиск должен быть при каждом нажатии - сокращая кол записей.
При таком описании товара "Масло Долина Сканди 400 гр 80% Легкое Щвеция" как показала практика юзер должен непрерывно видеть результат поиска.
Представь что юзер вводит "Мас" и нажимает ентер помимо всех записей с "масло" будут "маслины", "Масловка" и так далее. Тогда он продолжает ввод и вводит уже "масло" - а этих масел сотни. Таким образом юзер вынужден кучу раз тыкать ентер или "Искать" и лупиться в монитор в поисках необходимой записи.
← →
Курдль © (2005-09-22 14:17) [18]
> Sergey13 © (22.09.05 13:59) [15]
>
> ИМХО, самое правильное (с интерфейсной точки зрения) и простое
> это отловить в Едите клавишу "Enter" и/или потерю фокуса
> и вызвать при этом обработчик кнопки "Искать".
>
Это чье юзибилити утвердило?
Если прога открывается утром, выключается вечером, а ассортимент товара меняется раз в месяц - тогда и б БД нефиг лазить со своими запросами !
> Jioniro (22.09.05 13:52) [13]
А нормализовать БД не пробовали?
Например, делить товары по типам, упаковке, жирности и т.п.?
Тогда бы не пришлось выискивать по контексту из названия!
← →
msguns © (2005-09-22 14:22) [19]>Jioniro (22.09.05 13:52) [13]
Видимо, речь идет о накладных со склада в магазин..
Тогда см.sniknik © (22.09.05 14:11) [16]
И попутно вопрос: а зачем накладную на внутреннее перемещение вообще вводить - она что, не может передаваться в эл.виде и автоматом класться на остатки ?
Если же это приходная (от поставщика) накладная, то для поиска лучше использовать дерево товаров или фильтр по поставщику, что существенно упрощает поиски.
← →
Jioniro (2005-09-22 14:23) [20]> А нормализовать БД не пробовали?
> Например, делить товары по типам, упаковке, жирности и т.
> п.?
>
> Тогда бы не пришлось выискивать по контексту из названия!
>
нет этого просто нельзя делать, потому что поддерживается импорт других каталогов (например - поставщика) а там типы могут быть другие, по этому запись неделимая но при составлении её выдерживается правило - ВИД. МАРКА, ДОПОЛНЕНИЕ (например: Водка Довгань 0.5 л 40% Дамская Воронеж ЛВЗ)
← →
Val © (2005-09-22 14:25) [21]>[17] Jioniro (22.09.05 14:17)
1:
> как показала практика юзер должен непрерывно видеть результат
> поиска.
2:
> Таким образом юзер вынужден кучу раз тыкать ентер или "Искать"
> и лупиться в монитор в поисках необходимой записи.
сами знаете, что хотите?
← →
Jioniro (2005-09-22 14:26) [22]
> И попутно вопрос: а зачем накладную на внутреннее перемещение
> вообще вводить - она что, не может передаваться в эл.виде
> и автоматом класться на остатки ?
>
> Если же это приходная (от поставщика) накладная, то для
> поиска лучше использовать дерево товаров или фильтр по поставщику,
> что существенно упрощает поиски.
Накладную на внутреннее перемещение точно также как на приход необходимо заполнить товаром - для этого тоже нужен поиск в каталоге товаров...
Согласен, фильтр по поставщику присутствует, но что если поставщик поставляет 500 наименований например "Метро"
← →
Jioniro (2005-09-22 14:27) [23]
> сами знаете, что хотите?
я хочу первое, а мне предлагают второе!!!
← →
msguns © (2005-09-22 14:34) [24]>Jioniro (22.09.05 14:27) [23]
>но что если поставщик поставляет 500 наименований например "Метро"
Оператор должен набрать образец:
Метро..400..люкс
и нажать "Поиск"
Это будет много быстрее того, что ты делаешь
← →
sniknik © (2005-09-22 14:35) [25]> но что если поставщик поставляет 500 наименований например "Метро"
тогда у него есть свой внутренний код/артикул, иначе он сам свой товар с однотипным названием не разберет.
и этот код/артикул есть на накладной, иначе невозможна отгрузка/поставки/сверки...
в дополнению к фильтру по поставшику этот код будет уникальным значением... не всегда правда ;(, они сами путаются, но в 99,9% случаев, ошибка по нему будет не чаще чем по наименованию.
используй его.
← →
sniknik © (2005-09-22 14:40) [26]> я хочу первое, а мне предлагают второе!!!
загнать таблицу в память, и делать фильтром. уже предлагали, быстрее не будет (при передаче в память (клиенстский рекордсет к примеру) еще и привести названия к верхшему регистру чтобы в фильтре с одной стороны хотябы не делать постоянно).
энтузиазма предложение не вызвало... вот и предлагают то что считают лучшим. а ты нос воротиш.
← →
msguns © (2005-09-22 14:43) [27]Кстати, если речь идет о формировании накладной со склада в розницу (кладовщик или оператор склада/офиса), то очень сильно упрощает и ускоряет набор накладной наличие "Заказа" в этот магазин, в котором просто чекаются соотв.позиции и затем чекнуе скопом переносятся в фактуру, куда проставляется фактически только кол-во и изредка меняется розничная цена.
В целом же не вижу проблемы, т.к. такая накладная формируется для каждого магазина не чаще 2-х раз за день. А магазинов, как правило, не более 2-х десятков. Нарисовать за раб.день 40 накладных, куда, как показывает практика, вставляется не более сотни позиций, имхо, не такая уж большая нагрузка даже для одного опытного оператора.
← →
Jioniro (2005-09-22 14:45) [28]> тогда у него есть свой внутренний код/артикул, иначе он
> сам свой товар с однотипным названием не разберет.
> и этот код/артикул есть на накладной, иначе невозможна отгрузка/поставки/сверки.
> Оператор должен набрать образец:
>
> Метро..400..люкс
>
> и нажать "Поиск"
а если один и тот же товар поставляет в разное время несколько поставщиков, такое бывает постоянно, стои кому-нить из поставщиков снизить цены хоть на 10 копеек.
Мастера - моя задача поставлена и продумана ещё 3 года назад, более того первая версия программного обеспечения написана и юзается, она же и показала недостатки таких методов фильтрации и поиска как по поставшику или при нажатии "Искать".
Как показала 3-х летняя практика необходим поиск по нескольким контекстам именно по наименованию товара и при каждом нажатии клавиши, я очень прошу если есть идеи подскажите как сделать такой поиск. Не надо меня переубеждать что нужен другой - мне задачу поставили и её необходимо выполнить.
Заранее сенкс.
← →
Jioniro (2005-09-22 14:47) [29]> загнать таблицу в память, и делать фильтром. уже предлагали,
> быстрее не будет (при передаче в память (клиенстский рекордсет
> к примеру) еще и привести названия к верхшему регистру чтобы
> в фильтре с одной стороны хотябы не делать постоянно).
> энтузиазма предложение не вызвало... вот и предлагают то
> что считают лучшим. а ты нос воротиш.
нет я нос не ворочу!!! я пробую все варианты!!!Спасибо!
← →
Jioniro (2005-09-22 14:51) [30]> В целом же не вижу проблемы, т.к. такая накладная формируется
> для каждого магазина не чаще 2-х раз за день. А магазинов,
> как правило, не более 2-х десятков. Нарисовать за раб.день
> 40 накладных, куда, как показывает практика, вставляется
> не более сотни позиций, имхо, не такая уж большая нагрузка
> даже для одного опытного оператора.
в первой версии программного обеспечения так и сделано, но что если магазин только открылся и его наполняют товаром - тогда по 2 тыс наименований в день, или когда приходится догонять магазин - необходимо до пересменка успеть ввести все наименования, да ещё приходы, переброски, переоценки, списания и т.д за эту неделю.
← →
Курдль © (2005-09-22 14:55) [31]
> Как показала 3-х летняя практика необходим поиск по нескольким
> контекстам именно по наименованию товара и при каждом нажатии
> клавиши, я очень прошу если есть идеи подскажите как сделать
> такой поиск. Не надо меня переубеждать что нужен другой
> - мне задачу поставили и её необходимо выполнить.
> Заранее сенкс.
>
Тогда в забытом мною фрагменте примера, указанного выше, следует подработать получение значения параметра Ассерt не одним поиском субстроки, а несколькими.
procedure TfrmSubjects.sdqSubjectsFilterRecord(DataSet: TDataSet;
var Accept: Boolean);
begin
inherited;
Accept := pos(FFilterValue, AnsiUpperCase(FField.AsString)) > 0;
end;
← →
Sergey13 © (2005-09-22 15:04) [32]2 [18] Курдль © (22.09.05 14:17)
> Это чье юзибилити утвердило?
Мое. На это указывает абревиатура в начале поста.
>Если прога открывается утром, выключается вечером, а ассортимент товара меняется раз в месяц - тогда и б БД нефиг лазить со своими запросами !
Вот с этим не спорю. Но автору надо "с помощью SQL запроса". 8-)
← →
Jioniro (2005-09-22 15:28) [33]> Курдль © (22.09.05 14:55) [31]
> Тогда в забытом мною фрагменте примера, указанного выше,
> следует подработать получение значения параметра Ассерt
> не одним поиском субстроки, а несколькими.
нормально сработало, вроде довольно быстро при 20000 записей! попробую если больше но думаю подойдёт!
Сенкс всем!!!
← →
Курдль © (2005-09-22 15:54) [34]
> Как показала 3-х летняя практика необходим поиск по нескольким
> контекстам именно по наименованию товара и при каждом нажатии
> клавиши
Думаю, что без 3-хлетней практики не постичь мастерства одновременного нажатия клавиш в нескольких контекстах одновременно :)
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2005.11.06;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.04 c