Форум » [x]Harbour » Перехожу с Clipper 5.2e на Harbour, список вопросов от "новичка" » Ответить

Перехожу с Clipper 5.2e на Harbour, список вопросов от "новичка"

Sergy: Добрый день, уважаемые коллеги. Большое спасибо за море справочной информации по переходу, но нужно ещё пнуть меня в нужном направлении. Итак, установил Harbour 3.0 + BCC 5.5.1 ==>> 3.2.0 +minGW скомпилировал и запустил традиционный "Hello, world!" Дело перешло к проекту, из-за которого собственно и речь. Компилируется что через hbmk2, что самим харбором - без ошибок, всего с парой предупреждений, что меня немало удивило. Возникли ошибки на этапе линковки: [more]Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland Error: Unresolved external '_HB_FUN_ENVPARAM' referenced from D:\HB\TRADE100.OBJ Error: Unresolved external '_HB_FUN_INKEYTRAP' referenced from D:\HB\TRADE226.OBJ Error: Unresolved external '_HB_FUN_DISKFREE' referenced from D:\HB\TRADE222.OBJ Error: Unresolved external '_HB_FUN_DISKTOTAL' referenced from D:\HB\TRADE222.OBJ Error: Unresolved external '_HB_FUN_BIOSDATE' referenced from D:\HB\TRADE.OBJ Error: Unresolved external '_HB_FUN_FT_ONTICK' referenced from D:\HB\TRADE.OBJ Error: Unresolved external '_HB_FUN_FT_ONIDLE' referenced from D:\HB\TRADE200.OBJ Error: Unresolved external '_HB_FUN_FT_IAMIDLE' referenced from D:\HB\TRADE200.OBJ Error: Unresolved external '_HB_FUN_TRAPANYKEY' referenced from D:\HB\TRADE200.OBJ Error: Unresolved external '_HB_FUN_KEYSEND' referenced from D:\HB\TRADE200.OBJ 1) Так понимаю, это ошибки из-за того, что не находятся некоторые функции из активно используемых CT3/Nanforum Toolkit ? Что делать с ними ? Отказываться ? Или есть заменители ? Error: Unresolved external '_HB_FUN_STACKFREE' referenced from D:\HB\TRADE200.OBJ Error: Unresolved external '_HB_FUN_BLILOCUSE' referenced from D:\HB\TRADE200.OBJ Error: Unresolved external '_HB_FUN_BLILOCAVL' referenced from D:\HB\TRADE200.OBJ Error: Unresolved external '_HB_FUN_BLILOCTOT' referenced from D:\HB\TRADE200.OBJ Error: Unresolved external '_HB_FUN_BLISTCUSE' referenced from D:\HB\TRADE200.OBJ Error: Unresolved external '_HB_FUN_BLISTCAVL' referenced from D:\HB\TRADE200.OBJ Error: Unresolved external '_HB_FUN_BLISTCTOT' referenced from D:\HB\TRADE200.OBJ 2) Это - ошибки из-за вызовов встроенных в Blinker функций, без них легко обойтись в принципе... Error: Unresolved external '_HB_FUN_STRNUM2ARRAY' referenced from D:\HB\TRADE208.OBJ Error: Unresolved external '_HB_FUN_CMJS_EXTRACTPARAMS' referenced from D:\HB\TRADE206.OBJ Error: Unresolved external '_HB_FUN_SELECTSTOCKS' referenced from D:\HB\TRADE220.OBJ Error: Unresolved external '_HB_FUN_APPLYSERTCHAGES' referenced from D:\HB\TRADE221.OBJ Error: Unresolved external '_HB_FUN_APPLYCARGOCHAGES' referenced from D:\HB\TRADE221.OBJ Error: Unresolved external '_HB_FUN_APPLYPRICECHAGES' referenced from D:\HB\TRADE221.OBJ 3) А вот это - самое странное - это мои функции, причем некоторые из них вызываются многократно из других модулей. Например ApplyCargoChanges является STATIC в самом модуле TRADE221 - почему линковщик ее не видит, наряду с парой Apply... других ? SelectStocks активно используется в других модулях - но там линкер почему-то ошибок не видит... [/more] Help, please - что делать и куды бечь ?

Ответов - 285, стр: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 All

Pasha: Sergy пишет: Загвоздка оказалась в команде RUN. Как она может повлиять на SAVESCREEN() - ума не приложу. Харбор-программа разделяет консоль с внешним приложением (cmd.exe), которое изменяет какие-то параметры консоли.

Dima: Sergy Вместо RUN поюзай hb_processrun , WAPI_ShellExecute , EXECANDWAIT

Pasha: Делаем тест: #include "hbgtinfo.ch" proc main Local i, j, cc REQUEST HB_CODEPAGE_RU866 REQUEST HB_LANG_RU866 hb_cdpSelect( "RU866" ) cls //hb_gtinfo(HB_GTI_COMPATBUFFER, .f.) for i := 0 to 15 cc := '' for j := 0 to 15 cc += Chr(i*16 + j) next @ i, 0 say cc next cc := SaveScreen(0,0,15,15) RestScreen(0,20,15,35,cc) run('dir >nul') cc := SaveScreen(0,0,15,15) RestScreen(0,40,15,55,cc) wait retu На экране видим бяку на месте кодов меньше 32 А теперь фокус-покус: добавляем вызов hb_gtinfo(HB_GTI_COMPATBUFFER, .f.) и все исправляется. Только при этом буфер для savescreen/restscreen будет в 2 раза больше.


PSP: Ну да: HB_GTI_COMPATBUFFER /* Use DOS CGA/EGA/VGA character/attribute buffer in SAVE/REST SCREEN */

Sergy: Pasha пишет: На экране видим бяку на месте кодов меньше 32 А теперь фокус-покус: добавляем вызов hb_gtinfo(HB_GTI_COMPATBUFFER, .f.) и все исправляется. Только при этом буфер для savescreen/restscreen будет в 2 раза больше. Пока остановился на замене #define RUN(x) HB_ProcessRun(x) - SAVESCREEN заработал нормально. Понятно, что под Windows памяти дофига - но жалко же какой смысл ее транжирить...

Sergy: Sergy пишет: #define RUN(x) HB_ProcessRun(x) Так не пойдет - только что наступил на грабли: не выполняются команды shell - dir, copy, ren и тп... При этом не выдаются никакие сообщения об ошибке. Просто игнор и всё. Нужно вот так: #define RUN(x) HB_ProcessRun("cmd /c "+x) буффер не портится и команды command shell выполняются.

Dima: Sergy пишет: При этом не выдаются никакие сообщения об ошибке. Просто игнор и всё. Оно пишется в 3-й параметр этой функции если его указать Sergy пишет: не выполняются команды shell - dir, copy, ren и тп... А зачем ? Все это можно делать средствами Harbour

nick_mi: А почему нельзя сохранять экран ДО команды RUN ? Так было бы логичнее.

Sergy: nick_mi пишет: А почему нельзя сохранять экран ДО команды RUN ? Так было бы логичнее. Изначально вопрос стоял так: в процессе перехода с Clipper на Harbour были устранены шероховатости и программа была запущена в работу на предприятии. Все возникающие в процессе работы вопросы решались, за исключением непонятки, "портившей" символы с кодом ниже CHR(32) при восстановлении на экран. После детального изучения вопроса (а версии возникали самые разные - они описаны тут, на пред. страницах) выяснилось, что уже SAVESCREEN возвращает "испорченный" буфер экрана. Пошаговое выполнение программы привело к выяснению причины - ею оказалась команда RUN(). Понятно, что анализировать сотни/тысячи строк кода и выяснять, где идет RUN(), а потом SAVESCREEN() вряд-ли имеет смысл и решение с #define кажется мне на сегодня вполне достаточным.

Sergy: Dima пишет: А зачем ? Все это можно делать средствами Harbour Безусловно. Но речь идет о запуске тысяч строк кода Clipper под Harbour, а не его переделке "с учетом возможностей". А в Clipper, к примеру, невозможно было работать нормально с каталогами/файлами, не соответствующими формату 8.3. Да и в Harbour сейчас проще записать RUN("del local\*.dbf >nul") чем городить такой огород: dim:=DIRECTORY(cPath,"*.dbf") ; AEVAL(dim,{|x| cPath+x[F_NAME]...}).

Sergy: Решил поднять старую тему: http://clipper.borda.ru/?1-20-0-00000475-000-0-0-1208757116 Речь в ней идет о DIRTYREAD/TURBOREAD/DBOI_READLOCK Подскажите плиз - к каким все-таки результатам приводит включение этого "ускорителя" ? Общая ситуация такая: есть куча пользователей, которые что-то пишут в таблицу с продажами. Есть пара пользователей, которые на основании таблицы продаж в READONLY режиме хотят построить отчет. Вот тут я немного не понял, чем все кончилось, а тема закрыта: если я у этой пары пользователей ("читателей") включу dbOrderInfo(DBOI_READLOCK,,, .t.) - что, помимо ускорения выборки, произойдет? Если в таблице за время построения отчета появятся какие-то записи - "читателям" по барабану: отчеты обычно строятся за прошлые периоды, изменение которых юзерам запрещено программно. Будут ли ошибки у "читателей" таблицы? Или у "писателей" в неё? Спасибо.

petr707: Если технология - файл-серверная и данные за прошлые периоды не изменяются, зачем нагружать доступ ко всей базе "грязным" чтением ? Можно сверить текущую базу с предыдущей локальной выборкой( копией ) и строить отчеты по локальной копии продаж, не нагружая рабочую базу. Создание файла локальной копии происходит гораздо быстрее и менее напряжно, чем подготовка отчетов по общей базе, и в общем случае, затраты ресурсов и времени на создание локальной копии окупаются. Заодно - получается точная фиксация "точки отсечения" - на какой момент фиксировано состояние продаж. if local_file_not_exist or local_file_is_old ;use .. shared readonly; copy to (local_file) for ..; close ..

Pasha: Sergy пишет: Вот тут я немного не понял, чем все кончилось, а тема закрыта: если я у этой пары пользователей ("читателей") включу dbOrderInfo(DBOI_READLOCK,,, .t.) - что, помимо ускорения выборки, произойдет? Если в таблице за время построения отчета появятся какие-то записи - "читателям" по барабану: отчеты обычно строятся за прошлые периоды, изменение которых юзерам запрещено программно. Будут ли ошибки у "читателей" таблицы? Или у "писателей" в неё? DBOI_READLOCK касается только выборки по управляющему индексу. Если этот параметр включен, то на время включения другие клиенты не смогут ничего ни прочитать, ни записать в рабочую область, т.к. индекс блокируется для чтения. Внешне это будет выглядеть как "зависание" клиента. Поэтому использовать эту опцию надо аккуратно, и на очень непродолжительное время. Можно сделать тест: dbOrderInfo(DBOI_READLOCK,,, .t.) wait и попробовать с другого клиента выдась go top/skip, и посмотреть, что получится. Ничего хорошего, естественно. Это все проблемы файл-сервера. Для клиент-сервера вроде ads/letodb такой проблемы нет в принципе.

Sergy: petr707, Pasha Мысли понятны. С letodb скоро разберусь. И загрузку локально для справочников я провожу всегда, практически с первого дня написания программы. Для большой кучи отчетов (в начале месяца, например) есть функция "работать локально" - через 5-7 минут ожидания (пока вся база скопом копируется в локальную папку) - программа работает с ней, как ни в чем не бывало, но в READONLY - чтобы никто не навыписывал по забывчивости накладных. А вот если юзеру нужно всего один-два отчета, не окажется ли процесс "копирование всей таблицы продаж + локальная индексация" длительнее, чем просто чтение нужного периода по индексу ? Т.е. овчинка не будет стоить выделки... Думал, что DBOI_READLOCK поможет ускорить чтение по индексу. Спасибо.

Andrey: Уже перешел на Харбор ! Поздравляю ! Sergy пишет: А вот если юзеру нужно всего один-два отчета, не окажется ли процесс "копирование всей таблицы продаж + локальная индексация" длительнее, чем просто чтение нужного периода по индексу ? Для различных выборов из баз, делай условную индексацию по уже сформированным индексам. Отчеты будут строиться влет, даже не успеешь заметить... Здесь на форуме обсуждалось это, и не раз.

petr707: для каждой задачи можно проверить и выбрать подходящую схему.. set order to 0; copy to () for...; index on ... может оказаться быстрее чем index on ...; copy to () for...;

Pasha: Sergy пишет: Думал, что DBOI_READLOCK поможет ускорить чтение по индексу. Сергей, я подзабыл эти вещи, и неправильно написал: DBOI_READLOCK блокирует выборку на запись с других клиентов, а не на чтение. А так да, когда я использовал DBFCDX, установка DBOI_READLOCK меня реально выручала. В сетевом окружении скорость выборки возрастала многократно. Что же касается остальных вариантов, то надо иметь в виду: все эти приемы: динамическое построение индекса, или индекса с условием, или копирование таблицы с set order to 0 для больших таблиц неприемлемы, поскольку предполагают цикл по всем записям, что быстрым быть не может. Надо применять обычное решение: иметь правильный набор индексов для возможных выборок, и использовать их. Для файл-сервера DBOI_READLOCK реально помогает. Проблем из-за его использования у меня не было. Только, как я отмечал, его надо использовать аккуратно.

Sergy: Pasha пишет: DBOI_READLOCK блокирует выборку на запись с других клиентов, а не на чтение. Требуется уточнение: блокирует именно те записи, по которым идет чтение или целиком запись в индексный файл ? Тк первый вариант для меня подходит, а второй - нет.

Sergy: Andrey пишет: Для различных выборов из баз, делай условную индексацию по уже сформированным индексам. Не очень знаком с условной индексацией, если честно... Направьте плиз на путь истинный. Вот допустим, у меня есть таблица продаж: date D8 // дата продажи stk1 N5 // продавец stk2 N5 // покупатель code C10 // код товара num N10 // кол-во price N10.2 // цена И два индекса: 1) по CODE (чтобы быстро находить нужный товар в куче продаж) 2) по DATE (чтобы быстро найти нужный период для отчета) Для построения отчета использую таблицу продаж только со вторым индексом в режиме READONLY Как условная индексация может тут помочь ?

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



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