Форум » [x]Harbour » DBFNTX: как грамотно прервать работу SET FILTER ? » Ответить

DBFNTX: как грамотно прервать работу SET FILTER ?

Sergy: Добрый день Есть некая таблица: date D8 idx1 N5 idx2 N5 flags C5 string C80 И есть фрагмент программы: [pre2]filter_sx := "" SELE table SET FILT TO IIF(LEN(filter_sx)==0,TRUE,(filter_sx $ table->str)) DBEDIT(...)[/pre2] Т.е. пока в строку фильтра ничего не попало - видны все записи. Если юзер хочет отфильтровать часть записей по содержимому строки - срабатывает фильтр. Возникает ситуация: если таблица большая (>100 тыс записей), расположена на сервере и юзер желает увидеть какие-то "редкие" записи, процесс фильтрации начинает занимать непозволительно долгое время. Юзер понимает, что лучше набрать в фильтре что-то другое, но как остановить процесс текущей фильтрации ? Делал так: [pre2]filter_sx := "" SELE table SET FILT TO MyFilter() DBEDIT(...) ... FUNC MyFilter() IF LEN(filter_sx) == 0 RETURN TRUE ELSEIF INKEY(0) == K_ESC // юзер устал ждать ? filter_sx := "" // выключаем фильтр RETURN TRUE ELSE RETURN (filter_sx $ table->string) ENDIF RETURN TRUE[/pre2] Но данный метод приводит вообще к чудным результатам: в 90% случаев после нажатия Esc - DBEDIT() начинает бешено прокручивать список вверх и зависает на первом элементе таблицы. Насколько понял по отладчику, что-то непонятное (для меня) происходит в недрах объекта в районе :Stabilize() С какой стороны к этому вопросу подступиться? PS: в Clipper было тоже самое - но когда тормозило всё, это было не так заметно, а сейчас, на фоне быстрой и адекватной работы Harbour... напрягает....

Ответов - 120, стр: 1 2 3 4 5 6 All

ММК: Pasha пишет: есть смысл на него глянуть. отправил

Pasha: Ссылка на исправленный dbfEval: http://files.mail.ru/10FD94F47C824895BC5C8CB1913BC973 По поводу dbFLocate. Также используются файловые операции. Не тестировал, только смотрел сырцы. Поиск выполняется по одному полю, независимо от его типа, поле считывается как строка, поиск выполняется по hb_strMatchWild. Если нужен поиск по одному полю, то dbFLocate будет немного быстрее, чем dbfEval. Но dbfEval более универсален, так как в качестве выражения для поиска можно использовать произвольный блок кода.

Andrey: Pasha пишет: Ссылка на исправленный dbfEval: Не собирается опять проект на хХарборе с этим файлом. Вот такая ошибка: xHarbour 1.2.3 Intl. (SimpLex) (Build 20130903) Copyright 1999-2013, http://www.xharbour.org http://www.harbour-project.org/ Compiling 'DBFEVAL.PRG'... Generating C source output to 'obj\DBFEVAL.c'... Done. Building object module for 'obj\DBFEVAL.c' using C compiler 'BCC32' as defined in 'Z:\xHARBOUR\BIN\harbour.cfg'... Exec: BCC32 -c -D__EXPORT__ -IZ:\xHARBOUR\include -d -LZ:\xHARBOUR\lib -oobj\DBFEVAL.obj obj\DBFEVAL.c Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland obj\DBFEVAL.c: Warning W8075 DBFEVAL.PRG 29: Suspicious pointer conversion in function HB_FUN_DBFEVAL Warning W8075 DBFEVAL.PRG 36: Suspicious pointer conversion in function HB_FUN_DBFEVAL Error E2451 DBFEVAL.PRG 49: Undefined symbol 'hDataFile' in function HB_FUN_DBFEVAL Error E2451 DBFEVAL.PRG 53: Undefined symbol 'hDataFile' in function HB_FUN_DBFEVAL *** 2 errors in Compile *** Done. Deleting: "obj\DBFEVAL.c" Done. Lines 2, Functions/Procedures 0, pCodes 0


ММК: Pasha пишет: Если нужен поиск Понимаете , Паша , идея была в том что бы объеденить эти функции т.к. каждая из них имеет свои достоинства. Скажем по параметру запускать один из вариантов. Поиск по одному полю гораздо быстрее и наличие MatchWild очень вожно. dbfEval хорош для общего поиска. Но поиск это поиск , а фильтр это фильтр :)) Для себя я это представляю ( и делаю ) , как три разные задачи; Поиск. Фильтр, когда он ставится один раз и под заранее оговоренный отчет. Вложенные фильтры-когда пользователь ставит каждый последующий в зависимости от результата предыдущего. Т.е. "творчески" работает с базой :) И варианты могут быть любые, соответственно не очень удобно создавать на все поля индексы ( особенно , если этих полей 100-150 ) и (или) писать обработку массивов для такой ситуации. Для вложенных фильтров использую не index.. for , а index on ... to tsmy_idx for !deleted() CUSTOM ADDITIVE Он создается на локальной машине и дальнейшая работа идет не с базой , а с индексом. И мы его не перестраивааем , а корректируем. Например передается вид операции ( больше, меньше и т.д. ) и необходимое значение. Поэтому любой пользователь может ставить свой филтр вне зависимости от других. А дальще - .... myblock:=&('{||iif('+bloo+alltrim(znak)+'"'+alltrim(wot)+'",ORDKEYADD("TSMY_IDX","tsmy_idx.cdx",'+mykey+'),)}') ... dbeval(myblock) или , соответственно - myblock:=&('{||iif('+bloo+alltrim(znak)+'"'+alltrim(wot)+'",,ORDKEYDEL("TSMY_IDX"))}') Можно использовать и "вилд" фильтр А теперь просто "рефрешь" бровса. По ощущениям "прорисовка экран" идет медленнее , чем работа фильтра. Новое условие на этот филтр - новая корректировка dbeval(myblock)

Dima: Andrey пишет: Error E2451 DBFEVAL.PRG 49: Undefined symbol 'hDataFile' in function HB_FUN_DBFEVAL Error E2451 DBFEVAL.PRG 53: Undefined symbol 'hDataFile' in function HB_FUN_DBFEVAL Не уверен но возможно вместо hDataFile нужно написать pDataFile

Pasha: Наконец-то разобрался со сборкой для xHarbour SVN Оказывается, там размерность типов данных ULONG и HB_ULONG разная Скачать исходник dbfeval: http://zalil.ru/34858902

Andrey: Спасибо БОЛЬШОЕ Pasha ! Компилируется нормально.

Andrey: А почему в dbfEval() если есть условие ".AND.!DELETED()" - все равно показывает удаленные записи ?

Pasha: Проверил - вроде как с этим флагом все нормально, он учитывается.

Andrey: Pasha пишет: Проверил - вроде как с этим флагом все нормально, он учитывается. Вот тестовый пример на хХарборе. http://files.mail.ru/32A93B73CC8F40BE900F5E889C5E7711 При первом запуске программы создаются базы в папке проекта DBF и файл пути к базе DBF_search.path Базы можно перекинуть на сервер и поменяв путь в DBF_search.path - тестировать скорость по сети. Хотя реальные тесты показывают совсем другое время. При работе нескольких программ в сети скорость LOCATE с 3 секунд может увеличиться до 3х минут. SET FILTER тоже не подарок... Условие ".AND.!DELETED()" - не учитывается в SET FILTER, LOCATE, dbfEval() Может строка поиска большая ?

Dima: Andrey [pre2] Subsystem Call ....: DBFCDX System Code .......: 1004 Default Status ....: .T. Description .......: Ошибка создания Operation .........: Arguments .........: Involved File .....: C:\1\555\dd\6\1\DBF\TestDogovor.dbf Dos Error Code ....: 3 Trace Through: ---------------- DBCREATE : 0 in Module: CREATE_TEST_DBF : 235 in Module: OPENDBFDIC.PRG MYOPENDBF : 18 in Module: OPENDBFDIC.PRG MAIN : 31 in Module: DBF_SEARCH.PRG [/pre2]

Andrey: Dima пишет: C:\1\555\dd\6\1\DBF\TestDogovor.dbf Сделай путь покороче, типа D:\DBF-Search Точно вылетает... Буду смотреть...

Dima: Andrey я вообще руками ни чего не делал и просто распаковал в эту папку и запустил EXE Могу понять что могло заглючить если бы папка была кириллицей названа.

Pasha: Andrey пишет: Условие ".AND.!DELETED()" - не учитывается в SET FILTER, LOCATE, dbfEval() Все упомянутые средства работают правильно, это неправильное условие поиска. Сколько будет дважды два .t. .or. .t. .and. .f. ? Подсказка: правильно будет (.t. .or. .t.) .and. .f.

Pasha: Dima пишет: я вообще руками ни чего не делал и просто распаковал в эту папку и запустил EXE там ручками надо создать папку dbf

Andrey: Pasha пишет: Подсказка: правильно будет (.t. .or. .t.) .and. .f. Спасибо БОЛЬШОЕ ! Вечно торопливость мешает правильно делать... А когда сделаешь, уже считаешь что всё правильно ! Исправленный пример - http://files.mail.ru/97F319C31C944A199D7AA97DA0136E7A SET FILTER - при первом запуске хорошо тормозит, 15 сек. поиска на локальной машине.... А что будет с ним на сервере, я даже не представляю. Dima - модуль FindBMDBFCDX.prg тебя ждет !

Dima: Andrey пишет: Вечно торопливость мешает правильно делать... Это точно [pre2] -------------------- Internal Error Handling Information --------------------- Subsystem Call ....: DBFCDX System Code .......: 1004 Default Status ....: .T. Description .......: Ошибка создания Operation .........: Arguments .........: Involved File .....: D:\DBF-Search\DBF\TestDogovor.dbf Dos Error Code ....: 3 Trace Through: ---------------- DBCREATE : 0 in Module: CREATE_TEST_DBF : 235 in Module: OPENDBFDIC.PRG MYOPENDBF : 18 in Module: OPENDBFDIC.PRG MAIN : 31 in Module: DBF_SEARCH.PRG [/pre2] Andrey пишет: Dima - модуль FindBMDBFCDX.prg тебя ждет ! А чего ? Мало примера что я дал ? Принцип тот же , выбираем в массив удовлетворяющие записи. Но поиск происходит по индексам (при чем по каждому такому полю нужно иметь индекс). ЗЫ Сел бы и разобрался без спешки и вопросов бы не было , впрочем их и не было даже после того как я показал самодостаточный пример и полагал что все ясно. В Xharbour в тестах вроде же есть пример skipeval.prg я его просто чуть модифицировал.

Andrey: Dima пишет: Description .......: Ошибка создания Operation .........: Arguments .........: Involved File .....: D:\DBF-Search\DBF\TestDogovor.dbf Dos Error Code ....: 3 А точно пробовал последний пример - DBF-Search2.7z ? У меня теперь в любой папке создает базу... Пробовал так D:\TEMP\1\TEST\DBF Не забыть удалить файл dbf_search.path если папки переименовал.

Dima: Andrey Да я сделал как в прошлый раз распаковал архив в отдельную папку и запустил EXE и выпал на эту ошибку. Искать ошибку лень да и Xharbour у меня нет что бы пересобрать.

Andrey: Dima пишет: Да я сделал как в прошлый раз распаковал архив в отдельную папку и запустил EXE Удали файл dbf_search.path, я его случайно в архив поместил. Andrey пишет: При первом запуске программы создаются базы в папке проекта DBF и файл пути к базе DBF_search.path Базы можно перекинуть на сервер и поменяв путь в DBF_search.path - тестировать скорость по сети.



полная версия страницы