On-line: Pasha, PSP, гостей 2. Всего: 4 [подробнее..]
АвторСообщение



Пост N: 55
Зарегистрирован: 03.12.08
ссылка на сообщение  Отправлено: 06.04.12 11:51. Заголовок: Помогите с реализацией задумки


Привет всем ! Есть задача .
Имеется DBF-ка :
A ,B ,C, D, - числовые поля (геометрические размеры)
CODE - код товара

Необходимо сделать фильтрацию по введенным полям да ещё и "приправить " дополнительными формами ввода (от /до)
-------------------------------------------------------------------------------------------
| Размер А от [ ] до [ ]
| Размер B от [ ] до [ ]
| Размер C от [ ] до [ ]
| Размер D от [ ] до [ ]
|
| [Искать] [Выход]
|
--------------------------------------------------------------------------------------------
Вводим числовые параметры ... По кнопке [Искать] - должно быть отфильтровано по введённым полям
Пока продумываю как это лучше реализовать : Форма ввода и алгоритм фильтрации .... Поиск может быть при разном количестве заполненных полей . Разумеется - если поле не заполнено - то оно и не участвует в поиске ....
Буду признателен за какие-то примерчики вашей реализации подобного задания ...


Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 26 , стр: 1 2 All [только новые]


постоянный участник


Пост N: 755
Зарегистрирован: 27.01.07
ссылка на сообщение  Отправлено: 06.04.12 13:09. Заголовок: Могу предложить так:..


Могу предложить так:

#define  NTRIM( x )                    ( AllTrim( Str( x ) ) ) 


LOCAL cFilter := ""
LOCAL nAMin, nAMax
LOCAL nBMin, nBMax
LOCAL nCMin, nCMax
LOCAL nDMin, nDMax


... тут get-ы ...


cFilter := IF( ! Empty( nAMin ), "BASE->AMin >=" + NTRIM( nAMin ), "" )
cFilter += IF( ! Empty( nAMax ), IF( ! Empty( cFilter ), ".and.", "" ) + "BASE->AMax <=" + NTRIM( nAMax ), "" )
cFilter += IF( ! Empty( nBMin ), IF( ! Empty( cFilter ), ".and.", "" ) + "BASE->BMin >=" + NTRIM( nBMin ), "" )
cFilter += IF( ! Empty( nBMax ), IF( ! Empty( cFilter ), ".and.", "" ) + "BASE->BMax <=" + NTRIM( nBMax ), "" )
cFilter += IF( ! Empty( nCMin ), IF( ! Empty( cFilter ), ".and.", "" ) + "BASE->CMin >=" + NTRIM( nCMin ), "" )
cFilter += IF( ! Empty( nCMax ), IF( ! Empty( cFilter ), ".and.", "" ) + "BASE->CMax <=" + NTRIM( nCMax ), "" )
cFilter += IF( ! Empty( nDMin ), IF( ! Empty( cFilter ), ".and.", "" ) + "BASE->DMin >=" + NTRIM( nDMin ), "" )
cFilter += IF( ! Empty( nDMax ), IF( ! Empty( cFilter ), ".and.", "" ) + "BASE->DMax <=" + NTRIM( nDMax ), "" )

IF ! Empty( cFilter )
BASE->( DBSetFilter( &( "{ || " + cFilter + "}" ), cFilter ) )
END // IF



Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 756
Зарегистрирован: 27.01.07
ссылка на сообщение  Отправлено: 06.04.12 13:31. Заголовок: P.S. с добавлением &..


P.S. с добавлением ".and." надо доработать, могут быть ошибки, когда, например, введена только nAMin

Upd: Пример изменил. Должно работать. :)

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 308
Зарегистрирован: 06.02.07
ссылка на сообщение  Отправлено: 06.04.12 14:40. Заголовок: Не по реализации - ч..


Не по реализации - чуть в оффтоп... Softlog86 пишет:

 цитата:
A ,B ,C, D, - числовые поля (геометрические размеры)

Ну, к примеру, A/B/C я понимаю - длина/ширина/высота... а D тогда какой "геометрический размер"? (просто интересно) А по теме - я бы тоже как-то подобно выше написанному стал бы решать.

Спасибо: 0 
ПрофильЦитата Ответить





Пост N: 222
Зарегистрирован: 12.11.06
ссылка на сообщение  Отправлено: 06.04.12 16:49. Заголовок: Если интересно, то м..


Если интересно, то мой "колхозный" подход: в примере поиск, но ... нашел и фильтрацию... крайне медленная операция по сети

Скрытый текст



Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 56
Зарегистрирован: 03.12.08
ссылка на сообщение  Отправлено: 06.04.12 22:21. Заголовок: Для простоты я обобщ..


Для простоты я обобщил как "геометрические" ..... Если взять что-то сложнее куба , например , такую автозапчасть как шкив генератора :
A=Посадочный диаметр
B=Внешний диаметр
C=Общая высота
D=Вынос
E=Число ручьёв ремня
....
В общем-то и задумывается как поиск по Метрическим и иным параметрам ... Пока готовлю разумный план реализации :) Должно быть как-бы универсальным - подставляй любой файл-набитую базу и получай технический поисковик по параметрам :)

PS: Вот-бы что и с GET-ми придумать толковое ...... Формировать форму ввода данных на основе того самого файла DBF где и лежат эти самые искомые (фильтруемые) данные


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2148
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 06.04.12 22:27. Заголовок: AndreyZh пишет: но ..


AndreyZh пишет:

 цитата:
но ... нашел и фильтрацию... крайне медленная операция по сети



Сделай условную индексацию (Клипер 5.3) и будет быстрее в разы !

Спасибо: 0 
ПрофильЦитата Ответить



Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 07.04.12 05:53. Заголовок: A,B,C,D, -это названия столбцов в Excel


Сколько записей в DBF ?
Какой набор значений по каждой колонке ?
Если не очень много - может проще загнать в Excel(или Calc из OpenOffice) ?
А там есть автофильтр, и все Get's -будут в виде комбобоксов

Спасибо: 0 
Цитата Ответить
постоянный участник


Пост N: 307
Зарегистрирован: 13.10.05
ссылка на сообщение  Отправлено: 07.04.12 06:27. Заголовок: Я подобные выборки д..


Я подобные выборки делаю условной индексацией или запросами (ADS). Фильтрация приемлима только для небольших баз.Если после установки фильтра ты еще просматриваешь результат и найдено всего несколько записей, тогда вообще "вешалка".

Спасибо: 0 
ПрофильЦитата Ответить



Пост N: 57
Зарегистрирован: 03.12.08
ссылка на сообщение  Отправлено: 07.04.12 15:31. Заголовок: Записей может быть д..


Записей может быть до 3-5 тыс . Это максимум . Просьба EXCELL вообще не вспоминать . Всё-ж CLIPPER для того и используем :)

Спасибо: 0 
ПрофильЦитата Ответить



Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 07.04.12 15:47. Заголовок: 5 тысяч записей


Для 5 тысяч - без хлопот со сложными фильтрами и индексами-
быстро идет копирование общей таблицы по условию - функция от параметров
во временную локальную таблицу, открываемую заново и экслюзивно после
каждого копирования ( если есть возможность применения локальных таблиц)
..
copy to (tmp) for get_size(a1,b1,a2,b2,..)




Спасибо: 0 
Цитата Ответить
Администратор




Пост N: 2333
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 07.04.12 21:23. Заголовок: 3-5 тыс.записей - эт..


3-5 тыс.записей - это детский размер. Я думал, раз в 100 больше, 300-500 тыс. В таком простом случае для поиска по 4-м параметрам (геометрическим размерам) надо сделать 4 постоянных индекса по каждому из "размеров", и для поиска использовать любой из них.
Такой поиск будет заведомо эффективнее, чем простой фильтр, который предполагает выборку из всей таблицы.
А условный индекс, который предлагают Андрей и Влад, ничем не лучше простого фильтра. Для создания условного индекса, а для каждой операции поиска надо создавать свой условный индекс, необходима такая же выборка всех записей таблицы. Поиск по условному индексу будет очень быстрый, но его создание плюс поиск по нему ничем не лучше простого фильтра.
А если учесть, что для каждой операции поиска придется создавать свой временный условный индекс, то такой способ заведомо хуже, чем простой тупой фильтр.
Так что не стоит предлагать в качестве решения этот метод.


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2155
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 08.04.12 15:22. Заголовок: Pasha пишет: А усло..


Pasha пишет:

 цитата:
А условный индекс, который предлагают Андрей и Влад, ничем не лучше простого фильтра. Для создания условного индекса, а для каждой операции поиска надо создавать свой условный индекс, необходима такая же выборка всех записей таблицы. Поиск по условному индексу будет очень быстрый, но его создание плюс поиск по нему ничем не лучше простого фильтра.
А если учесть, что для каждой операции поиска придется создавать свой временный условный индекс, то такой способ заведомо хуже, чем простой тупой фильтр.



Паша, ты не прав.
Я имел ввиду, что условный индекс БУДЕТ строиться по уже индексированному полю базы (можно допустим по А).
Это будет быстро и просто по написанию кода. Сразу после индекса выводит TBROWSE().
Тем более будет всего 3-5 тыс.записей ....
Я таким вариантом пользовался еще с 1997 года, да и на хХарборе пока оставил.

А на больший размер, конечно твой вариант будет правильней !

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2337
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 08.04.12 17:37. Заголовок: Andrey пишет: Паша,..


Andrey пишет:

 цитата:
Паша, ты не прав.
Я имел ввиду, что условный индекс БУДЕТ строиться по уже индексированному полю базы (можно допустим по А).
Это будет быстро и просто по написанию кода. Сразу после индекса выводит TBROWSE().
Тем более будет всего 3-5 тыс.записей ....
Я таким вариантом пользовался еще с 1997 года, да и на хХарборе пока оставил.

А на больший размер, конечно твой вариант будет правильней !



Это с использованием опции usecurrent, что ли ? Допустим, имеется постоянный индекс по полю A. А условный индекс будет по какому полю, и что в условии for ? Условие while, record используется ?
Условный индекс ты предлагаешь создавать для каждой операции поиска, а затем удаляешь его ?


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2156
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 08.04.12 18:43. Заголовок: Pasha пишет: Допуст..


Pasha пишет:

 цитата:
Допустим, имеется постоянный индекс по полю A. А условный индекс будет по какому полю, и что в условии for ? Условие while, record используется ?



Можно условие for использовать....
DBSELECT(1) // переключаемся на открытый индекс A
// далее условный индекс для Клипера 5.3
INDEX ON &cIndexTo TAG "ONE" TO (cTempFileIndex) ;
EVAL MES_BARW( aBeg, IIF( lFlag, RECNO(), ORDKEYNO() ), nKolRecords ) ;
EVERY nKolRecords / 10 FOR &cFilter ADDITIVE
ORDSETFOCUS( "ONE" )
DBSETORDER(2)

где MES_BARW() - моя функция бегунка и cFilter - как предложил PSP
В клипере по условная индексация по уже открытому индексу вход. в условин отбора - очень ШУСТРО строится, даже по сети.
А SET FILTER TO по условию индексного файла отрабатывает лучше чем в Харборе.
Просто в Клипере есть(включена) оптимизация для SET FILTER, в Харборе такого нет !
Я такую конструкцию использую и сейчас, хотя улучшил для Харбора по твоей рекомендации (см. условную индексацию здесь на форуме) !

Pasha пишет:

 цитата:
Условный индекс ты предлагаешь создавать для каждой операции поиска, а затем удаляешь его ?


Да, именно так.



Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2338
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 08.04.12 19:09. Заголовок: Andrey пишет: В кли..


Andrey пишет:

 цитата:
В клипере по условная индексация по уже открытому индексу вход. в условин отбора - очень ШУСТРО строится, даже по сети.
А SET FILTER TO по условию индексного файла отрабатывает лучше чем в Харборе.
Просто в Клипере есть(включена) оптимизация для SET FILTER, в Харборе такого нет !



Для создания индекса таким образом необходима выборка всех записей файла, от первой и до последней. Чудес не бывает. И чем это лучше обычной выборки с фильтром ?
Ничем не лучше, а наоборот хуже, поскольку помимо выборки выполняется формирование индекса, т.е. построение бинарного дерева и его запись на диск. А если учесть, что такой индекс одноразовый, такой способ совсем уж абсурдный.
А что за оптимизация set filter в клиппере ? Какой ее механизм ? Как вообще set filter можно оптимизировать ? Что это за фантастика ?

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2158
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 08.04.12 19:46. Заголовок: Pasha пишет: А что ..


Pasha пишет:

 цитата:
А что за оптимизация set filter в клиппере ? Какой ее механизм ? Как вообще set filter можно оптимизировать ? Что это за фантастика ?



Ну я с этим сталкивался еще при переходе на хХарбор.
SET FILTER (для CDX) в Клипере 5.3 даже по сети работает на несколько порядков быстрей чем в хХарборе.
Там по документации описана вкл/отк. ОПТИМИЗАЦИИ запросов. Это не фантастика.
В клипере 5.2 такого не было, это появилось только в 5.3
Мне потом пришлось переделывать под хХарбор логику по выборке из базы,
т.е. в Клипере 5.3 я делал SET FILTER TO (условие) - и получал даже по сети, очень быстро данные.
Я на Клипере 5.3 долго сидел с 1994 года. Есть даже примеры по этим выборкам. Если надо, поищу.

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2339
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 08.04.12 20:01. Заголовок: Andrey пишет: Ну я ..


Andrey пишет:

 цитата:
Ну я с этим сталкивался еще при переходе на хХарбор.
SET FILTER (для CDX) в Клипере 5.3 даже по сети работает на несколько порядков быстрей чем в хХарборе.
Там по документации описана вкл/отк. ОПТИМИЗАЦИИ запросов. Это не фантастика.
Мне потом пришлось переделывать под хХарбор логику по выборке из базы,
т.е. в Клипере 5.3 я делал SET FILTER TO (условие) - и получал даже по сети, очень быстро данные.
Я на Клипере 5.3 долго сидел с 1994 года. Есть даже примеры по этим выборкам. Если надо, поищу.



По-видимому, имеется в виду команда set optimize. Оптимизация при этом сводится к использованию открытого индекса при выборке по фильтру, то есть это просто неявное использование scope.
Но ничего не мешает явно использовать scope, если в выражении фильтра присутствуют индексные поля. Наоборот, это делать крайне необходимо, если хочется получить быстрый фильтр.
Но опять таки, временный условный индекс здесь ни каким боком не прицепишь.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 2160
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 09.04.12 08:27. Заголовок: Pasha пишет: Но опя..


Pasha пишет:

 цитата:
Но опять таки, временный условный индекс здесь ни каким боком не прицепишь.


Ну не буду спорть. На данную задачу это может и не нужно....
Я просто предложил как вариант.

Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2341
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 13.04.12 11:57. Заголовок: Здесь есть еще такой..


Здесь есть еще такой ньюанс
При построении индекса индексный доступ к файлу не используется, т.е при индексации неявно устанавливается set order to 0.
При этом для выборки записей для индексации не надо блокировать индекс, и выборка по сети выполняется намного быстрее.
Чтобы достигнуть такой же производительности при выборке с фильтром, необходимо также задать:

set order to 0

или

dbOrderInfo(DBOI_READLOCK,,, .t.)
а после выборки:
dbOrderInfo(DBOI_READLOCK,,, .f.)
это конечно команды харбора

При индексации еще для чтения записей используется буфер 64К. Но не это дает такую высокую скорость выборки, так как буфер ОС все равно используется, а именно отсутствие необходимости блокировать индекс.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник


Пост N: 87
Зарегистрирован: 29.05.10
ссылка на сообщение  Отправлено: 14.04.12 08:59. Заголовок: Pasha пишет: Поиск ..


Pasha пишет:

 цитата:
Поиск по условному индексу будет очень быстрый, но его создание плюс поиск по нему ничем не лучше простого фильтра.
А если учесть, что для каждой операции поиска придется создавать свой временный условный индекс, то такой способ заведомо хуже, чем простой тупой фильтр.
Так что не стоит предлагать в качестве решения этот метод.


Пользуюсь именно этим методом :) Берем базу с разными полями (числ., стр., дата...) .Хочется в ней сделать какую-то выборку,
Причем сразу может быть и не ясны конкретные "рамки" . Другими словами ставим один "фильтр" потом по рузультату второй и т.д.
( кстати , временный условный индекс создается только раз, далее в него просто добавляются условия )
Вот на картинке бровс с базой с выбранным индексом по коду. Можно "щелкнуть" по наменованию -индекс сменится. Теперь выбираем любое интересующее нас поле и по правой клавише мыши выбираем условие выборки .К примеру больше нуля. Вот один фильтр :) Теперь повторяем операцию и берез значение меньше 10. Вот уже второй ... Становимся на другое поле ... и т.д. Все наглядно и быстро
Приблизительно так...
mykey:=indexkey()
MOldOrd:=ordname()
MOldBag:=ORDBAGNAME()
If временный индекс не создан
index on &mykey to tsmy_idx for !deleted() CUSTOM ADDITIVE
Endif
set order to tag (MOldBag)
.......
do case
case valtype(wot)=='C'//.and.::lDostext
myblock:=&('{||iif('+bloo+alltrim(znak)+'"'+alltrim(wot)+'",ORDKEYADD("TSMY_IDX","tsmy_idx.cdx",'+mykey+'),)}')
case valtype(wot)=='N'
........
case valtype(wot)=='D'
........
endcase
dbeval(myblock)

SET ORDER TO TAG tsmy_idx
Go top
http://shot.qip.ru/008r16-38walgHwn/



Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 26 , стр: 1 2 All [только новые]
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 338
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет