Форум » Clipper » All In One » Ответить

All In One

SergeyKorotun: В связи с написанием программы по разным частям кода возникают трудности. Чтобы не задавать вопросы в разных темах и не забыть в какой именно, буду спрашивать в этой. Я возможно этим нарушу правила форума, вопросы будут затрагивать разнообразные функции, но пусть оправданием мне будет то, что все они относятся к одной программе. Вопрос №1 В get поле вводится какое то значение и если оно существует в справочнике, переходим в следующее get поле, если же не существует, то выдается предупреждение об этом. Сам оператор не имеет право добавлять это значение в справочник, но, убедившись в том, что он ввел без ошибок, имеет право оставить это значение в get поле и перейти в следующее. Чтобы случайно не проскочило ошибочно введенное значение, выход из get поля должен осуществляться по нестандартной клавише( т.е. K_ENTER, K_DOWN не подходят). Например подошло бы Ctrl+Enter Реализовать самому не удалось Вопрос № 2. В dbedit отобразить базу так, чтобы видеть максимальное число последних записей и чтобы курсор находился на последней записи use base new go bottom base->dbedit() вижу только одну последнюю запись use base new go bottom skip -17 base->dbedit() вижу все последние записи, но курсор находится на первой видимой use base new go bottom skip -17 skip 17 base->dbedit() вижу только одну последнюю запись Вопрос № 3. В dbedit даты отображаются в формате "дд.мм.гг", причем гг первые две цифры из гггг. Как отобразить в формате "дд.мм.гггг", не используя массив из picture для dbedit, чтобы не переделывать программу при изменении структуры базы. Вопрос № 4. в функции из valid изменяются значения других get переменных. Изменения становятся видимыми только тогда, когда курсор попадает в измененное соответствующее get поле, а хочется чтобы обновились сразу после выхода из поля, в котором они изменились. Обновляю так keyboard (replicate(chr(K_DOWN),17)+replicate(chr(K_UP),16)) Можно как то попроще? Вопрос № 5 При входе в get ... read в чужой программе на фоксе все поля пустые. В своей программе get переменные инициализирую командой space(n). Но после выхода из read и сохранения значений в полях базы с типом numeric выдает ошибку несоответствия типа данных. Обхожу так if !Empty() replace namebase->namefield with val(alltrim(namegetfield)) endif Как то попроще можно? Вопрос № 6 Есть строка из символов, которых не должно быть в веденном значении в get поле. Существует ли какая то функция, возвращающая true или false в случае наличия символов из строки 1 в строке 2? Или только посимвольно проверять?

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

Григорьев Владимир: Кстати сказать, хотел бы добавить, что есть различия в способе открытия файлов с помощью FOPEN и USE. USE использует установки путей для поиска файлов, в то время как FOPEN открывает файл без использования установленных путей доступа к файлам баз данных по умолчанию. Так что на мой взгляд вышеприведенная программа вообще некорректная! Может так оказаться, что с помощью вашей функции file_exc и с помощью команды USE будут проверяться два разных файла!:)

petr707: Да, конечно,различия есть, лучше уточнять имена файлов абсолютными путями, или в начале кода провести установки рабочих каталогов (независимо от кого как пользователь сможет запустить приложение): exe_dir = base_dir = current_dos_dir (set path ..., set default .., dirchange(...) ) А какая альтернатива файловым операциям? Отработка исключений BEGIN sequence break END ?

SergeyKorotun: Путь к базам в программе указан полностью. Пример я просто упростил. Обе программы использует один и тот же пользователь. Но программы могут быть установлены на разных компьютерах, соединенных в сеть. На данном этапе программа выдает сообщение, чтобы вышли с чужой программы. Для пользователя это не проблема. Если он не выйдет, тоже ничего страного не произойдет. Программа выдаст ошибку времени выполнения. Никаких потерь записей не произойдет. Просто хотелось бы в случае незанятости базы пропускать это сообщение, т.к. база открыта только в нескольких пунктах меню и не всегда прийдется выходить с программы. Индексные файлы базы, в которую добавляются записи, открывать не надо, так как они фокспрошные. После добавления будет переиндексация базы средствами чужой программы.


Haz: SergeyKorotun пишет: Просто хотелось бы в случае незанятости базы пропускать это сообщение Хочется пропускать - пропускайте, есть же стандартный обработчик ситуации ( хотя может в 5.0 все както иначе ??? ) bSave := ERRORBLOCK( {|x| BREAK(x)} ) BEGIN SEQUENCE use reciver alias reciver new RECOVER ..... END SEQUENCE ERRORBLOCK(bSave)

SergeyKorotun: в последнем get поле добавил when функцию, которая проверяет значения в предыдущих полях и если что-то не так, пользователю alert-ом выдается предупреждение и функция возвращает .f. Так вот после нажатия энтера или пробела на сообщении завершается get...read, а мне еще надо ошибки поисправлять и в последнее поле значение ввести. Перенести функцию у valid предпоследнего get не предлагать (возникнут проблемы с выходом в вышележащие поля для исправления ошибок да и функция там уже есть и к тому же объемная)

petr707: Пусть исходный код имеет вид: .. get befLastVar valid vld_befLastVar() ...get LastVar when whe_LastVar() valid vld_LastVar() ---- READ завершается, потому что нет ввода в последнее поле ( из-за whe_LastVar()=.f.) Чтобы открывалось для ввода последнее поле: 1 вариант изменения - перестановка вызовов функций в другой Get: .. get befLastVar valid vld_befLastVar().and.whe_Lastvar() ...get LastVar() valid vld_LastVar() 2 вариант - When LastVar - всегда возвращать .t., а проверку - в Valid последнего поля .. get befLastVar valid vld_befLastVar() ...get LastVar when eval({|| whe_LastVar(),.t.}) valid whe_LastVar().and.vld_LastVar()

PSP: Можно так: LOCAL GetList := {} @ 1, 1 GET cVar @ 2, 1 GET nVar @ 3, 1 GET dVar nGet := 1 WHILE .T. ReadModal( GetList, nGet ) IF LastKey() <> K_ESC // здесь проверяем корректность ввода данных IF Empty( cVar ) nGet := 1 // вернуться на 1-й GET LOOP ELSEIF nVar == 0 nGet := 2 // вернуться на 2-й GET LOOP ELSEIF Empty( dVar ) nGet := 3 // вернуться на 3-й GET LOOP END // IF // если все поля заполнены корректно, делаем сохранение BASE->cVar := cVar BASE->nVar := nVar BASE->dVar := dVar END // IF EXIT END // WHILE

SergeyKorotun: petr707 пишет: Пусть исходный код имеет вид: .. get befLastVar valid vld_befLastVar() ...get LastVar when whe_LastVar() valid vld_LastVar() ---- READ завершается, потому что нет ввода в последнее поле ( из-за whe_LastVar()=.f.) Чтобы открывалось для ввода последнее поле: 1 вариант изменения - перестановка вызовов функций в другой Get: .. get befLastVar valid vld_befLastVar().and.whe_Lastvar() ...get LastVar() valid vld_LastVar() 2 вариант - When LastVar - всегда возвращать .t., а проверку - в Valid последнего поля .. get befLastVar valid vld_befLastVar() ...get LastVar when eval({|| whe_LastVar(),.t.}) valid whe_LastVar().and.vld_LastVar() 1. вариант. Если vld_befLastVar().and.whe_Lastvar() обнаружит ошибку в предпоследнем поле, порожденную неверным значением в каком то предыдущем поле(назовем его varx), то чтобы перейти в varx, придется в предпоследнем поле ввести значение, соответствующее varx, иначе не выпустит из vld_befLastVar, потом перейти в varx, ввести значение, и после этого придется снова править vld_befLastVar 2. вариант. может возникнуть та же ситуация с ненужной правкой последнего поля. when просто бы не пустило в последнее поле, а выпускать в предыдущие поле (в отличие от валид) будет.

SergeyKorotun: PSP пишет: Можно так: LOCAL GetList := {} @ 1, 1 GET cVar @ 2, 1 GET nVar @ 3, 1 GET dVar nGet := 1 WHILE .T. ReadModal( GetList, nGet ) IF LastKey() <> K_ESC // здесь проверяем корректность ввода данных IF Empty( cVar ) nGet := 1 // вернуться на 1-й GET LOOP ELSEIF nVar == 0 nGet := 2 // вернуться на 2-й GET LOOP ELSEIF Empty( dVar ) nGet := 3 // вернуться на 3-й GET LOOP END // IF // если все поля заполнены корректно, делаем сохранение BASE->cVar := cVar BASE->nVar := nVar BASE->dVar := dVar END // IF EXIT END // WHILE такой конструкцией get не пользовался, но если здесь можно переносить фокус ввода в какое то предыдущее поле, то это то-что надо. А при переносе фокуса например из пятого поля в третье в четвертом поле будут выполняться when и valid функции? Но к сожалению в этой программе не воспользуюсь. Слишком много переделывать придется. Но идеей с переносом фокуса в одно из вышележащих полей с ошибками воспользуюсь, если получится. В when функции последнего поля сделаю проверку и если есть ошибка, все равно верну .t. и перенесу фокус в вышележащее поле, используя подсказку Haz: Разумеется есть ::aGetList[ ::nPos ]:setFocus() класс oGet

SergeyKorotun: При выполнении валид функции и возвращении .f. курсор устанавливается в начало поля. Можно как то определить в какой позиции он находился, чтобы после возврата из валид установить его в ту позицию, где он был.

petr707: Как-то сложновато выстраиватся у Вас система переходов по полям ввода и запретов перехода - можно даже сделать ловушку, из которой не выбраться.. Поймет ли User - в чем был неправ и как ему пройти лабиринт формы до конца? Предложение: 1) после завершения всех GET проверять все поля формы и либо разрешать запись данных либо сообщать, какие значения полей некорректны. 2) Для того чтобы не выбирать - в какой GET перевыставить ввод - нужно дать возможность User'ам клавишей K_UP (стрелка вверх) проходить к любому предыдущему полю любой Valid без проверки значений, поскольку видимо у Вас есть зависимость:следущее поле от предыдущих. 3) Не всегда запрещать выход из поля по некорректному значению , а только давать замечание ввода и разрешать ввод следующего поля, все равно User не сможет записать форму в конечной проверке всех полей при наличии каких-либо некорректных значений.

SergeyKorotun: petr707 пишет: можно даже сделать ловушку, из которой не выбраться.. Их и делать то не надо, они в реале получаются. Поэтому на данный момент разрешаю покидать любое пустое поле. Если же поле не пустое, выполняются все проверки в валид функции и в случае наличия ошибок запрещается выход из поля. Перед входом в последнее поле (проверкой у when последнего поля) выдаю предупреждение о незаполненных обязательных полях и в случае их наличия хотел запретить вход в последнее поле. Пока ограничился только предупреждениям без запрета входа, иначе завершается get...read

SergeyKorotun: Можно ли средствами клиппера считать ключ индексного файла cdx(создан foxpro) и пересоздать этот индекс? Или хотя бы зная ключ, создать cdx индекс? Как распечатать доку из NG?

petr707: 1) Индексы CDX создавать можно, см. поиск в конфе - SIX 2) Средство для просмотра , печати и тд. NG файлов - Expert Guide for Windows http://www.davep.org/norton-guides/

PSP: CDX встроен в RDD Клиппер, начиная с 5.2e (если не ошибаюсь), а также Harbour.

PSP: SergeyKorotun пишет: А при переносе фокуса например из пятого поля в третье в четвертом поле будут выполняться when и valid функции? В такой реализации редактирование Get-объекта полностью завершается, потом проверяется корректность данных и, если найдено поле с некоректными данными, то редактирование возобновляется, начиная с этого поля. Перед LOOP можно выдать какое-нибудь сообщение на экран. В данном случае проверка происходит вне Get-объекта. WHEN и VALID функции здесь не участвуют.

SergeyKorotun: К файлу prg1 оператором do подсоединяются файлы prg1_1 prg1_2 К файлу prg1_1 оператором do подсоединяются файл prg1_1_1 Будут ли видимыми в prg1_2 функции из prg1_1_1? Тот же самый вопрос более наглядно: file prg1.prg ... do prg1_1 ... do prg1_2 ... file prg1_1.prg ... do prg1_1_1 // здесь есть функция function f1_1_1() ... file prg1_2.prg ... f1_1_1() // будет ли доступна здесь эта функция ...

PSP: Функция видна во всей программе, если она не объявлена STATIC.

SergeyKorotun: Haz пишет: Попробуйте перекомпилировать свою программу в Clipper 5.3, скорее всего никаких доработок не потребуется вообще, а освоить SCOPE вам тут помогут Из NG по SIx Driver RDD: Индексный Драйвер фирмы SuccessWare (SIx Драйвер) - это замещаемый драйвер баз данных (RDD) для Clipper'а 5.0x. В качестве RDD он присоединяется к низкоуровневой подсистеме СУБД, имеющейся в архитектуре Clipper'а 5.0. Это означает, что Вы можете буквально заменить умалчиваемый RDD (DBFNTX) на SIx Драйвер и использовать индексы FoxPro без перекомпиляции или переработки исходного кода. Откуда следует что и Scope и cdx индексы можно использовать и в клиппер 5.01? Или он глючит с клиппер 5.01?

Haz: SergeyKorotun пишет: Откуда следует что и Scope и cdx индексы можно использовать и в клиппер 5.01? Или он глючит с клиппер 5.01? можно, и тут уже предлагали SIX2 для 5.0 ... глюков серьезных не помню, хотя больше приходилось на сикс3 и клиппер 5.2 работать ( вот эта связка показывала очень высокую скорость ) SergeyKorotun пишет: без перекомпиляции а вот тут приврали - перекомпелить придется. PS все же советую попробовать harbour c cdx, 5.3 c cdx или 5.2е с Six3



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