Автор | Сообщение |
|
| |
Пост N: 17
Зарегистрирован: 30.05.11
|
|
Отправлено: 03.06.11 23:27. Заголовок: All In One
В связи с написанием программы по разным частям кода возникают трудности. Чтобы не задавать вопросы в разных темах и не забыть в какой именно, буду спрашивать в этой. Я возможно этим нарушу правила форума, вопросы будут затрагивать разнообразные функции, но пусть оправданием мне будет то, что все они относятся к одной программе. Вопрос №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
[только новые]
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 04.06.11 07:36. Заголовок: вопрос 2
use base new go bottom skip -17 keyboard CHR(K_CTRL_PGDN) // base->dbedit()
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 04.06.11 08:00. Заголовок: вопрос 4
|
|
|
|
| |
Пост N: 19
Зарегистрирован: 30.05.11
|
|
Отправлено: 04.06.11 12:51. Заголовок: petr707 пишет: Поис..
petr707 пишет: вставил в прогу на клиппер 5.01, обновляет поля, хотя функции display() в NG for clipper 5.01 не нашел.
|
|
|
|
| |
Пост N: 2080
Зарегистрирован: 17.05.05
|
|
Отправлено: 04.06.11 12:54. Заголовок: SergeyKorotun пишет:..
SergeyKorotun пишет: цитата: | хотя функции display() в NG for clipper 5.01 не нашел. |
| Смотри класс GET
|
|
|
|
| |
Пост N: 20
Зарегистрирован: 30.05.11
|
|
Отправлено: 04.06.11 13:30. Заголовок: в стартовое сообщени..
в стартовое сообщения добавил вопрос № 5
|
|
|
|
| |
Пост N: 200
Зарегистрирован: 11.06.10
|
|
Отправлено: 04.06.11 13:48. Заголовок: SergeyKorotun пишет:..
SergeyKorotun пишет: цитата: | Вопрос № 2. В dbedit отобразить базу так, чтобы видеть максимальное число последних записей и чтобы курсор находился на последней записи |
| index ... descend dbedit()
|
|
|
|
| |
Пост N: 201
Зарегистрирован: 11.06.10
|
|
Отправлено: 04.06.11 13:52. Заголовок: SergeyKorotun пишет:..
SergeyKorotun пишет: цитата: | Вопрос № 3. В dbedit даты отображаются в формате "дд.мм.гг", причем гг первые две цифры из гггг. Как отобразить в формате "дд.мм.гггг", не используя массив из picture для dbedit, чтобы не переделывать программу при изменении структуры базы. |
| set century on
|
|
|
|
| |
Пост N: 22
Зарегистрирован: 30.05.11
|
|
Отправлено: 04.06.11 14:18. Заголовок: AlexMyr пишет: inde..
AlexMyr пишет: цитата: | index ... descend dbedit() |
| Возможно я неправильно употребил слово "последних". Я просто хотел чтобы окно dbedit было заполнено полностью записями, а какими (отсотированными в каком то порядке или действительно введенные в базу последними) именно не имеет значения. Подошел ответ petr707: use base new go bottom skip -17 keyboard CHR(K_CTRL_PGDN) // base->dbedit() AlexMyr пишет: а вот это то что надо
|
|
|
|
| постоянный участник
|
Пост N: 533
Зарегистрирован: 27.01.07
|
|
Отправлено: 04.06.11 14:20. Заголовок: SergeyKorotun пишет:..
SergeyKorotun пишет: цитата: | В своей программе get переменные инициализирую командой space(n). Но после выхода из read и сохранения значений в полях базы с типом numeric выдает ошибку несоответствия типа данных. Обхожу так if !Empty() replace namebase->namefield with val(alltrim(namegetfield)) endif Как то попроще можно? |
| А не надо переменной, значение которой в будущем будет записываться в числовое поле, присваивать строковое значение. Почему бы вместо Var := Space( n ) не использовать Var := 0. Get-система разберется сама, что ей подсовывают. Можно и PICTURE в GET указать для числового поля.
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 04.06.11 14:22. Заголовок: вопрос 5
вместо Space(n) лучше x=BLANK(x,.t.) или x=MyBlank(x) Function MyBlank(x) Local ret,tx:=valtype(x) do case case tx="N" ret:=0 case tx="C" ret:=space(len(x)) case tx="D" ret:=ctod('') case tx="L" ret:=.f. otherwise ret:=NIL endcase return ret
|
|
|
|
| постоянный участник
|
Пост N: 534
Зарегистрирован: 27.01.07
|
|
Отправлено: 04.06.11 14:25. Заголовок: petr707, а если знач..
petr707, а если значение x и так NIL? NIL и останется. В GET редактирования не будет.
|
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 04.06.11 14:44. Заголовок: x not NIL
В контексте задачи: x -значение поля записи БД , разве нет? varGet = blank(fieldget)
|
|
|
|
| |
Пост N: 23
Зарегистрирован: 30.05.11
|
|
Отправлено: 04.06.11 14:46. Заголовок: PSP пишет: А не над..
PSP пишет: цитата: | А не надо переменной, значение которой в будущем будет записываться в числовое поле, присваивать строковое значение. Почему бы вместо Var := Space( n ) не использовать Var := 0. Get-система разберется сама, что ей подсовывают. Можно и PICTURE в GET указать для числового поля. |
| Не очень хорошо смотрится например номер телефона или почтовый индекс =0
|
|
|
|
| |
Пост N: 24
Зарегистрирован: 30.05.11
|
|
Отправлено: 04.06.11 14:55. Заголовок: petr707 пишет: вмес..
petr707 пишет: цитата: | вместо Space(n) лучше x=BLANK(x,.t.) или x=MyBlank(x) Function MyBlank(x) Local ret,tx:=valtype(x) do case case tx="N" ret:=0 case tx="C" ret:=space(len(x)) case tx="D" ret:=ctod('') case tx="L" ret:=.f. otherwise ret:=NIL endcase return ret |
| тип значений мне известен и ничто не мешает мне инициализировать get переменную значением нужного типа напрямую(a:=space(10); n:=0 ). Но... Смотри ответ на предыдущее сообщение
|
|
|
|
| постоянный участник
|
Пост N: 535
Зарегистрирован: 27.01.07
|
|
Отправлено: 04.06.11 15:14. Заголовок: SergeyKorotun пишет:..
SergeyKorotun пишет: цитата: | номер телефона или почтовый индекс =0 |
| В базе эти поля числовые? Оригинально... :)
|
|
|
|
| |
Пост N: 25
Зарегистрирован: 30.05.11
|
|
Отправлено: 04.06.11 15:14. Заголовок: petr707 пишет: В ко..
petr707 пишет: цитата: | В контексте задачи: x -значение поля записи БД , разве нет? varGet = blank(fieldget) |
| а вот это запомню. Пригодится. Сейчас у поля телефон тип numeric, понятно что со временем сменят на character и в этом случае программу править не придется. А blank - это функция пользователя? В NG такой не нашел
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 04.06.11 15:22. Заголовок: blank
blank() - из Clipper Tools не хотите цеплять Tools? берите MyBlank() до кучи - ниже - шаблон Picture для get Function get_picture(cfield) Local nf:=fieldnum(UPPER(cfield)),tip,ret:="",nsize,ndec if nf>0 tip :=fieldtype(nf) nsize:=fieldsize(nf) do case case tip="C" ret:=replicate("X",nsize) case tip="N" ndec:=fielddeci(nf) if ndec>0 ret:= replicate("9",nsize-ndec-1)+'.'+replicate("9",ndec) else ret:=replicate("9",nsize) endif endcase endif return ret
|
|
|
|
| |
Пост N: 26
Зарегистрирован: 30.05.11
|
|
Отправлено: 04.06.11 15:24. Заголовок: PSP пишет: В базе э..
PSP пишет: цитата: | В базе эти поля числовые? Оригинально... :) |
| А чем вам не нравится числовой тип поля для почтового индекса? У нас нет индексов начинающихся с нуля. А программе лет 20. Поле телефон только недавно расширили до 10 знаков, а тип еще не сменили, наверно много правок надо будет внести. Ну и я же пример привел не для того чтобы обсудить именно его, а объяснить почему get переменные желательно инициализировать именно space(n)
|
|
|
|
| |
Пост N: 27
Зарегистрирован: 30.05.11
|
|
Отправлено: 04.06.11 15:26. Заголовок: PSP пишет: В базе э..
PSP пишет: цитата: | В базе эти поля числовые? Оригинально... :) |
| А чем вам не нравится числовой тип поля для почтового индекса? У нас нет индексов начинающихся с нуля. А программе лет 20. Поле телефон только недавно расширили до 10 знаков, а тип еще не сменили, наверно много правок надо будет внести. Ну и я же пример привел не для того чтобы обсудить именно его, а объяснить почему get переменные желательно инициализировать именно space(n)
|
|
|
|
| |
Пост N: 28
Зарегистрирован: 30.05.11
|
|
Отправлено: 04.06.11 16:53. Заголовок: flag=.f. setkey(K_F1..
flag=.f. setkey(K_F10, {|p, l, v| ExitOn(p, l, v, flag)}) // по F10 выход из get даже если значения нет в справочнике @1,1 say "Фамилия" get F valid vF(,,,flag) ... read function vF(p,l,v,flg) if v="F" if flg flag:=.f. return .t. endif if F есть в справочнике return .t. else return .f. endif function ExitOn(p,l,v,flg) if v="F" flag:=.t. keyboard chr(K_DOWN) //заставить выполнить функцию из valid endif На самый важный для меня вопрос №1 ответа пока нет. Может наличие хоть какого-то кода ускорит ответ. Правда код писал по памяти, флешку с кодом забыл на работе. Что не так?
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 04.06.11 18:05. Заголовок: вопрос 1 - Enter - успешный ввод, если значение в справочнике, Tab - вся остальная подготовка
//вопрос 1 - Enter - успешный ввод, если значение поля ввода- в справочнике, Tab - вся остальная подготовка // После Tab - еще раз Enter .... @1,1 say "Фамилия" get F valid vld_get(,,,"F",@F) @2,1 say "Имя " get Name valid vld_get(,,,"Name",@Name) ... read ... // united valid Function vld_get(a,b,c,cvar_get,val_get) Local ret:=.t. do while .t. if cvar_get=NIL cvar_get := GETFLDVAR() val_get := &cvar_get endif do case case cvar_get="F" // fam ret:=.f. if lastkey()=K_TAB // get default value, pre-value val_get := space(len(val_get)) // val_get := padr("Иванов",len(val_get)) // val_get := look_internet() ret:=.f. EXIT endif ret := In_Sprav_fio(val_get) if !ret // no valid // need add val_get-> sprav message(val_get +" not in sprav ") ret:=.f. exit endif case cvar_get="Name" // name //.... otherwise endcase exit enddo return ret
|
|
|
|
|
| постоянный участник
|
Пост N: 536
Зарегистрирован: 27.01.07
|
|
Отправлено: 04.06.11 19:51. Заголовок: SergeyKorotun пишет:..
SergeyKorotun пишет: цитата: | А чем вам не нравится числовой тип поля для почтового индекса? |
| Нет проблем.
|
|
|
|
| |
Пост N: 29
Зарегистрирован: 30.05.11
|
|
Отправлено: 06.06.11 00:11. Заголовок: flagExit=.f. setkey..
flagExit=.f. setkey(K_F10, {|p, l, v| ExitOn(p, l, v, flagExit)}) @3,1 say " 2" get gF picture replicate("X",30) valid vgF("GF",flagExit) ... read function vgF(v,flgExit) if v=="GF" if flgExit flagExit=.f. return .t. endif endif select fam seek gF if found() return .t. else alert("Hand enter - F10") return .f. endif return .t. function ExitOn(p,l,v,flgExit) if v="GF" flagExit:=.t. keyboard chr(K_DOWN) endif return А вот это решение первого вопроса. Выход по F10. Хотел сделать по Ctrl+Enter. Не нашел инкей-кода
|
|
|
|
| |
Пост N: 204
Зарегистрирован: 11.06.10
|
|
Отправлено: 06.06.11 00:56. Заголовок: SergeyKorotun пишет:..
SergeyKorotun пишет: цитата: | Хоте сделать по Ctrl+Enter. Не нашел инкей-кода |
| Ctrl-Return 10 K_CTRL_RET
|
|
|
|
| |
Пост N: 53
Зарегистрирован: 20.02.11
|
|
Отправлено: 06.06.11 20:33. Заголовок: Так ответы уже ответенв давно ....
SergeyKorotun, все ответы уже отвечены давно .... в мануале классов Get() и TBrowse[DB]() есть все и даже больше. Сергей, поймите правильно - многие долгожители конфы уже забыли когда использовали Dbedit() и @..GET.. READ. Clipper 5.01 - 5,x - Harbour - дают очень гибкий инструмент в виде классов и вот вопросы из этой тематики привлекли бы больше внимания.
|
|
|
|
| |
Пост N: 30
Зарегистрирован: 30.05.11
|
|
Отправлено: 06.06.11 23:04. Заголовок: Haz пишет: flagExit..
Haz пишет: цитата: | flagExit=.f. setkey(K_F10, {|p, l, v| ExitOn(p, l, v, flagExit)}) @3,1 say " 2" get gF picture replicate("X",30) valid vgF("GF",flagExit) ... read function vgF(v,flgExit) if v=="GF" if flgExit flagExit=.f. return .t. endif endif select fam seek gF if found() return .t. else alert("Hand enter - F10") return .f. endif return .t. function ExitOn(p,l,v,flgExit) if v="GF" flagExit:=.t. keyboard chr(K_DOWN) endif return А вот это решение первого вопроса. |
| К сожалению этот вариант подходит только для первой get переменной. Когда ввел значение, отсутствующее в справочнике, программа предлагает нажать F10 и переходит в следующее поле. Но если позже надо вернуться на предыдущее поле, то это оказывается невозможным. keyboard chr(K_DOWN) все равно переводит вниз. Назначать еще одну функциональную клавишу как то нехорошо, определять по lastkey() нажатую клавишу (стрелка вверх/ вниз или энтер) до F10 тоже будет давать сбои при ошибочном нажатии пользователем какой-то иной клавиши.
|
|
|
|
| |
Пост N: 31
Зарегистрирован: 30.05.11
|
|
Отправлено: 06.06.11 23:33. Заголовок: Haz пишет: Clipper ..
Haz пишет: цитата: | Clipper 5.01 - 5,x - Harbour - дают очень гибкий инструмент в виде классов и вот вопросы из этой тематики привлекли бы больше внимания |
| Я не только получил ответы на все свои вопросы, но и узнал очень много нового о возможностях клиппера. Мне давали ответы не только на форуме, а и присылали письма на почтовый ящик. Большое всем спасибо. Но программа хотя и в стадии завершения, но еще один большой справочник не подключен (улицы), так что тема не закрывается. По фамилиям, именам и отчествам справочники не подключал, так как не очень то они нужны. Нет смысла не добирать несколько букв в фамилии, чтобы потом вызвать справочник, в котором будет сотня продолжений. После ввода фамилии проверил наличие ее в справочнике и если ее нет, выдал сообщение пользователю. А вот справочник улиц подключить надо. Иногда в паспортном столе записывают улицу с неверным окончанием и бывает необходимо выбрать самую подходящую. Попробую создавать временную базу, в которую попадут только улицы, удовлетворяющие условию фильтра и использовать ее в качестве справочника (еще раз повторюсь: переход на харбор будет производится только после написания программы на клиппер 5.01). Вопрос: после использования этой временной базы перед ее закрытием можно как-то запретить запись базы на диск?
|
|
|
|
| |
Пост N: 205
Зарегистрирован: 11.06.10
|
|
Отправлено: 07.06.11 00:04. Заголовок: SergeyKorotun пишет:..
SergeyKorotun пишет: цитата: | Попробую создавать временную базу, в которую попадут только улицы, удовлетворяющие условию фильтра и использовать ее в качестве справочника (еще раз повторюсь: переход на харбор будет производится только после написания программы на клиппер 5.01). Вопрос: после использования этой временной базы перед ее закрытием можно как-то запретить запись базы на диск? |
| А еще в харбор можно создавать базу в памяти (библиотека hbmemio): REQUEST HB_MEMIO PROC Main() LOCAL nI FIELD F1 DBCREATE("mem:test", {{"F1", "N", 9, 0}},, .T., "memarea") FOR nI := 1 TO 1000 DBAPPEND(); F1 := HB_RANDOM() * 1000000 NEXT INDEX ON F1 TAG f1 DBEVAL({|| QOUT(F1)}) DBCLOSEAREA() DBDROP("mem:test") // Free memory resource RETURN SergeyKorotun пишет: цитата: | Я не только получил ответы на все свои вопросы, но и узнал очень много нового о возможностях клиппера. |
| С такими знаниями о клиппере с русской докой, лучше уже начинать изучать харбор, плюс к харбору несколько десятков английских слов выучите и уже не будет так страшно копаться в английской доке .
|
|
|
|
| |
Пост N: 54
Зарегистрирован: 20.02.11
|
|
Отправлено: 07.06.11 06:33. Заголовок: SergeyKorotun пишет:
SergeyKorotun пишет: цитата: | Вопрос: после использования этой временной базы перед ее закрытием можно как-то запретить запись базы на диск? |
| С трудом вериться что вообще такое возможно, учитывая размер базы и используемую память DOS приложения. цитата: | Попробую создавать временную базу, в которую попадут только улицы, удовлетворяющие условию фильтра и использовать ее в качестве справочника |
| Попробуйте перекомпилировать свою программу в Clipper 5.3, скорее всего никаких доработок не потребуется вообще, а освоить SCOPE вам тут помогут
|
|
|
|
| |
Пост N: 48
Зарегистрирован: 18.02.11
|
|
Отправлено: 07.06.11 21:27. Заголовок: SergeyKorotun пишет:..
SergeyKorotun пишет: цитата: | Но если позже надо вернуться на предыдущее поле, то это оказывается невозможным. keyboard chr(K_DOWN) все равно переводит вниз. |
| В С5.2 есть READEXIT(.T.). Добавляет K_UP (5), K_DOWN (24) к переходу по GET полям cMyvar = SPACE(10) lLastExit = READEXIT(.T.) // Result: Turn on exit keys @ 10, 10 SAY "Enter: " GET cMyvar READ READEXIT(lLastExit) // Result: Restore previous setting Если используются функции VALID, то в начало надо вставлять: IF LastKey() == K_UP; RETURN .T. ENDIF
|
|
|
|
| |
Пост N: 32
Зарегистрирован: 30.05.11
|
|
Отправлено: 08.06.11 00:44. Заголовок: SergejKis пишет: Ес..
SergejKis пишет: цитата: | Если используются функции VALID, то в начало надо вставлять: IF LastKey() == K_UP; RETURN .T. ENDIF |
| Выход из get поля должен происходить по клавише, определенной в SET KEY, например по F10. При нажатии F10 вызывается функция, имитирующая нажатие на клавиатуре стрелки вниз, которая автоматически вызывает функцию из валид. Можно было бы все время какой то переменной присваивать код нажатой клавиши и в функции, вызываемой по F10 инициировать или нажатие стрелки вниз или стрелки вверх. Но где гарантия что пользователь случайно не нажмет какую то другую клавишу и нажатие какой клавиши инициировать - неизвестно.
|
|
|
|
|
| |
Пост N: 33
Зарегистрирован: 30.05.11
|
|
Отправлено: 08.06.11 00:46. Заголовок: SergejKis пишет: В ..
SergejKis пишет: цитата: | В С5.2 есть READEXIT(.T.). Добавляет K_UP (5), K_DOWN (24) к переходу по GET полям |
| в клиппер 5.01 по умолчанию переход по полям осуществляется в том числе и перечисленными вами клавишами
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 08.06.11 10:33. Заголовок: гарантия - проверка всех значений формы после READ
гарантия - проверка всех значений формы после READ ( после всех get) перед записью в БД, вывод сообщения оператору при ошибках ввода и возврат к началу формы - первому GET
|
|
|
|
| |
Пост N: 34
Зарегистрирован: 30.05.11
|
|
Отправлено: 08.06.11 14:46. Заголовок: Два часа не могу заг..
Два часа не могу загнать записи из базы send в базу reciver. Структуры баз совпадают. Путя к базам верные. Пытался и так написать: "dbf\\send.dbf" Где ошибка? pth:=alltrim(nastr->path_dbf)+"reciver.dbf" use (pth) alias reciver new select reсiver append from ("dbf\send.dbf") ALL // for ((d_zvirka>=dateBegin) .and. (d_zvirka<=dateEnd)) commit select reciver use
|
|
|
|
| постоянный участник
|
Пост N: 538
Зарегистрирован: 27.01.07
|
|
Отправлено: 08.06.11 15:45. Заголовок: 1. Что получаете? Ош..
1. Что получаете? Ошибку или что? 2. SergeyKorotun пишет: цитата: | append from ("dbf\send.dbf") ALL |
| ALL, по-моему, не нужно.
|
|
|
|
| |
Пост N: 35
Зарегистрирован: 30.05.11
|
|
Отправлено: 08.06.11 17:52. Заголовок: PSP пишет: 1. Что п..
PSP пишет: цитата: | 1. Что получаете? Ошибку или что? |
| Ошибок нет. Ни одной записи не переносится с базы send в базу reciver Без ALL тоже не переносятся. ALL не мешает, оно по умолчанию подразумевается
|
|
|
|
| Администратор
|
Пост N: 1968
Зарегистрирован: 23.05.05
|
|
Отправлено: 08.06.11 18:11. Заголовок: SergeyKorotun пишет:..
SergeyKorotun пишет: цитата: | Ошибок нет. Ни одной записи не переносится с базы send в базу reciver |
| Проверьте, чтобы файл reciver ранее не был открыт монопольно. Если это так, то __dbApp (aka append from) не сможет его открыть
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 08.06.11 18:36. Заголовок: Модифицировал пример
pth:=alltrim(nastr->path_dbf)+"reciver.dbf" cfile_app := ("dbf\send.dbf") do while .t. if !file(pth) // mess( " source file not found") exit endif if !file(cfile_app) // mess( " append file not found") exit endif use (pth) alias reciver new if select("reciver")=0 //mess("error use reciver") exit endif select reсiver append from (cfile_from) ALL // for ((d_zvirka>=dateBegin) .and. (d_zvirka<=dateEnd)) commit select reciver close reciver //use //mess("ok") exit enddo
|
|
|
|
| |
Пост N: 36
Зарегистрирован: 30.05.11
|
|
Отправлено: 08.06.11 19:11. Заголовок: Pasha пишет: Провер..
Pasha пишет: цитата: | Проверьте, чтобы файл reciver ранее не был открыт монопольно. Если это так, то __dbApp (aka append from) не сможет его открыть |
| На протяжении дня в базу send набиваются записи и в конце рабочего дня переносятся в базу reciver из другой программы. Но на время написания программы копия база reciver помещена в отдельную папку, pth настроен именно к ней, и никем занята быть не может. В приведенном выше фрагменте программы она открывается впервые. for petr707 Проверки на наличие баз я в приведенный фрагмент не включил, но они там есть. Кроме того обе базы я перед append from выводил с помощью dbedit на экран.
|
|
|
|
| Администратор
|
Пост N: 1969
Зарегистрирован: 23.05.05
|
|
Отправлено: 08.06.11 19:37. Заголовок: Я был невнимателен. ..
Я был невнимателен. Поскольку записи добавляются из send, и именно send открывается командой append from, проверьте, чтобы до выполнения append from send не была открыта монопольно
|
|
|
|
| |
Пост N: 55
Зарегистрирован: 20.02.11
|
|
Отправлено: 08.06.11 19:39. Заголовок: попробуйте так
Попробуйте открыть в эксклюзиве use (pth) alias reciver excl new
|
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 08.06.11 19:45. Заголовок: сколько программ одновременно работают(могут работать) с одной таблицей SEND?
1.Если при набивке в SEND не делать COMMIT, другая программа, возможно, их не увидит - до завершения работы первой. 2.Если в одной программе не освободить SEND, другая программа не сможет сделать APPEND 3.Для контроля занятости БД(видимости записей) таблицу SEND можно открывать сторонней утилитой DbfNavigator.exe (freeware) 4.Для контроля - лучше посчитать записи командой COUNT TO n в каждой таблице до и после Append ( вывести в лог) 5.Не очень хорошо - используются не абсолютные пути (disk\path\file) к файлам таблиц, при нечетком SET DEFAULT PATH можно случайно взять другой экземпляр SEND
|
|
|
|
| |
Пост N: 37
Зарегистрирован: 30.05.11
|
|
Отправлено: 09.06.11 18:48. Заголовок: Pasha пишет: Я был ..
Pasha пишет: цитата: | Я был невнимателен. Поскольку записи добавляются из send, и именно send открывается командой append from, проверьте, чтобы до выполнения append from send не была открыта монопольно |
| send была открыта именно этой программой, отображалась dbedit с функцией, и в зависимости от нажатой клавиши производились какие-то действия, и в частности экспорт записей в базу reciver. Закрыв базу send перед append from, экспорт заработал. После append from сразу же открыл send и хотя dbedit этого не заметил, все равно как то не хорошо получается.
|
|
|
|
| |
Пост N: 38
Зарегистрирован: 30.05.11
|
|
Отправлено: 09.06.11 18:59. Заголовок: В стартовый топик до..
В стартовый топик добавил вопрос № 6
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 09.06.11 19:13. Заголовок: Закрыть-открыть таблицу не внутри Dbedit
Можно по другому - используйте флаг для временного выхода из Dbedit затем автоматически повторный вход. все действия по - копированию БД, выделению записей - вне тела польз. функции Dbedit Userf ... private lrepeat:=.t. private lcopy :=.f. do while lrepeat lrepeat :=.f. if lcopy lcopy:=.f. copy file(dbf) to (dbf2) endif use (dbf) alias tmp new dbedit(,,,'userf',,) close tmp if !lrepeat; exit; endif enddo ... return Function userf() ... case lastkey()=K_ESC lrepeat := .f. // out return 0 case lastkey()=K_F10 // need close-open lrepeat:=.t. lcopy :=.t. return 0 // ..
|
|
|
|
| |
Пост N: 39
Зарегистрирован: 30.05.11
|
|
Отправлено: 09.06.11 19:24. Заголовок: petr707 пишет: copy..
petr707 пишет: Эта строка натолкнула на другой алгоритм: командой copy to из базы send создать временную базу и к ней применить append from
|
|
|
|
| |
Пост N: 40
Зарегистрирован: 30.05.11
|
|
Отправлено: 13.06.11 19:36. Заголовок: При входе в get read..
При входе в get read по умолчанию стоит режим замены. Какой командой установить режим вставки?
|
|
|
|
| постоянный участник
|
Пост N: 540
Зарегистрирован: 27.01.07
|
|
Отправлено: 13.06.11 19:43. Заголовок: SergeyKorotun пишет:..
|
|
|
|
| |
Пост N: 41
Зарегистрирован: 30.05.11
|
|
Отправлено: 13.06.11 21:33. Заголовок: Программой создается..
Программой создается база и из программы в одно из полей заносятся "запрещенные" символы. В валид функции будет проверяться, не встречается ли среди введенных символов запрещенные. Вопрос: как присвоить полю строку из запрещенных символов, в которой есть и ограничители строк (кавычки, апостроф)? Примеры запрещенных символов для некоторых get полей: `=!@#$%^&*()_+\|]}[{"?>,<' `=!@#$%^&*_+\|]}[{?><ЪЫЭ' `=!@#$%^&*_+\|]}[{?><QWERTYUIOPASDFGHJKLZXCVBNM'
|
|
|
|
| постоянный участник
|
Пост N: 541
Зарегистрирован: 27.01.07
|
|
Отправлено: 14.06.11 08:45. Заголовок: SergeyKorotun пишет:..
SergeyKorotun пишет: цитата: | как присвоить полю строку из запрещенных символов, в которой есть и ограничители строк (кавычки, апостроф)? |
| BASE->FieldName := Chr( 34 ) // кавычки BASE->FieldName := Chr( 39 ) // апостроф
|
|
|
|
| |
Пост N: 42
Зарегистрирован: 30.05.11
|
|
Отправлено: 14.06.11 13:52. Заголовок: PSP пишет: BASE-..
PSP пишет: цитата: | BASE->FieldName := Chr( 34 ) // кавычки BASE->FieldName := Chr( 39 ) // апостроф |
| Чтобы занести в базу строку `=!@#$%^&*()_+\|]}[{ "?>,< ' надо написать команду: replace base->fieldName with "`=!@#$%^&*()_+\|]}[{"+ chr(34)+"?>,<"+ chr(39) в других языках есть специальный символ, обозначающий, что следующий за ним символ не часть синтаксиса языка, а просто символ. В клиппере такого нет?
|
|
|
|
| Администратор
|
Пост N: 1974
Зарегистрирован: 23.05.05
|
|
Отправлено: 14.06.11 14:21. Заголовок: SergeyKorotun пишет:..
SergeyKorotun пишет: цитата: | в других языках есть специальный символ, обозначающий, что следующий за ним символ не часть синтаксиса языка, а просто символ. В клиппере такого нет? |
| В клиппере такого нет. Зато в клиппере символьная строка-константа может ограничиваться символами "" '' [] Если внутри строки есть какой-либо символ-ограничитель, то в качестве ограничителя для строки можно использовать альтернативный. Скажем, я привык использовать паскалевский ограничитель: '' Но в украинском языке апостроф присутствует в алфавите, и в тех случаях, когда надо использовать такой литерал, я использую ограничитель ""
|
|
|
|
| |
Пост N: 43
Зарегистрирован: 30.05.11
|
|
Отправлено: 14.06.11 16:37. Заголовок: Pasha пишет: Если в..
Pasha пишет: цитата: | Если внутри строки есть какой-либо символ-ограничитель, то в качестве ограничителя для строки можно использовать альтернативный. |
| У меня все три типа ограничителей присутствуют в строке, поэтому придется делать через chr() Строки с запрещенными символами хранятся у меня в текстовом файле. Через буфер обмена я вставил их в prg файл и командой replace занес в базу. Некоторые символы в базе отображены неверно, например вместо какого-то символа вижу желтый квадрат. Хотя в prg файле все символы соответствуют тем, что вставил из буфера.
|
|
|
|
| |
Пост N: 56
Зарегистрирован: 20.02.11
|
|
Отправлено: 14.06.11 22:06. Заголовок: можно держать не в базе
можно держать не в базе, а в том же текстовике, или INI файле. Проблем 0, рисуйте в INI все что удасться вбить с клавы. библиотек и примеров работы с INI на том же http://www.the-oasis.net/ уверен до дури.
|
|
|
|
| |
Пост N: 44
Зарегистрирован: 30.05.11
|
|
Отправлено: 15.06.11 13:44. Заголовок: можно ли в get ... r..
можно ли в get ... read перемещать фокус в указанное в валид функции get поле, зависящее от значения, введенного в текущее поле. Запрещать у when функции нельзя, так как пользователь имеет право например стрелкой вверх переместиться в пропущенное поле и изменить его. Использую для этого keyboard replicate(chr(K_DOWN),n). Может для этого есть какая то специальная команда
|
|
|
|
| |
Пост N: 57
Зарегистрирован: 20.02.11
|
|
Отправлено: 15.06.11 21:54. Заголовок: разумеется
Разумеется есть ::aGetList[ ::nPos ]:setFocus() класс oGet
|
|
|
|
| |
Пост N: 45
Зарегистрирован: 30.05.11
|
|
Отправлено: 20.06.11 23:47. Заголовок: use reciver alias re..
use reciver alias reciver new append from ("dbf\send.dbf") Требуется со своей базы send добавить записи в чужую базу reciver. Последняя база занята только в некоторых пунктах меню чужой программы. Чужая программа не сетевая, на фокспро. Как перед добавлением записей проверить занята чужая база(reciver) или нет, чтобы не заставлять пользователя полностью выходить из программы, а если он все же не вышел, не получать ошибки времени выполнения BASE/1002 АЛИАС ОТСУТСТВУЕТ
|
|
|
|
| |
Пост N: 123
Зарегистрирован: 05.06.07
|
|
Отправлено: 21.06.11 02:57. Заголовок: FLOCK() returns true..
FLOCK() returns true (.T.) if an attempt to lock a database file in USE in the current work area succeeds; otherwise, it returns false (.F.). И не забыть UNLOCK
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 21.06.11 07:04. Заголовок: test exclusive
.... f_name := "reciver.dbf" do while .t. if !file_exc(f_name) exit endif use (f_name) alias reciver new if select("reciver")=0 exit endif append from (...) .... close reciver exit enddo ... #include "fileio.ch Function file_exc(f_name,nerr_ex) Local handle:=0,ret:=.f. handle=fopen(f_name,FO_EXCLUSIVE) if ( nerr_ex:=FERROR())#0.or.handle=-1 ret:=.f. else fclose(handle) ret:=.t. endif return ret
|
|
|
|
| постоянный участник
|
Пост N: 388
Зарегистрирован: 17.05.05
|
|
Отправлено: 21.06.11 18:20. Заголовок: petr707 пишет: #inc..
petr707 пишет: цитата: | #include "fileio.ch Function file_exc(f_name,nerr_ex) Local handle:=0,ret:=.f. handle=fopen(f_name,FO_EXCLUSIVE) if ( nerr_ex:=FERROR())#0.or.handle=-1 ret:=.f. else fclose(handle) ret:=.t. endif return ret |
| У меня такой вопрос к автору этого кода: "Может ли так быть, что FERROR() равна 0, но тем не менее значение, возвращаемое FOPEN равно -1?! И второй вопрос: "Вы не предполагаете, что сам файл базы данных может открыться, но тем не менее его индексные файлы не будут иметь доступа?!" Эти вопросы у меня возникли в связи с тем, что на мой взгляд проще сразу же использовать команду USE, которая и возвратит все ошибки об открытии! Зачем несколько раз делать одно и тоже: сначала в вашей функции file_exc, а затем в команде USE?
|
|
|
|
| постоянный участник
|
Пост N: 389
Зарегистрирован: 17.05.05
|
|
Отправлено: 21.06.11 18:50. Заголовок: Кстати сказать, хоте..
Кстати сказать, хотел бы добавить, что есть различия в способе открытия файлов с помощью FOPEN и USE. USE использует установки путей для поиска файлов, в то время как FOPEN открывает файл без использования установленных путей доступа к файлам баз данных по умолчанию. Так что на мой взгляд вышеприведенная программа вообще некорректная! Может так оказаться, что с помощью вашей функции file_exc и с помощью команды USE будут проверяться два разных файла!:)
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 21.06.11 19:51. Заголовок: если забраться на шкаф...
Да, конечно,различия есть, лучше уточнять имена файлов абсолютными путями, или в начале кода провести установки рабочих каталогов (независимо от кого как пользователь сможет запустить приложение): exe_dir = base_dir = current_dos_dir (set path ..., set default .., dirchange(...) ) А какая альтернатива файловым операциям? Отработка исключений BEGIN sequence break END ?
|
|
|
|
| |
Пост N: 46
Зарегистрирован: 30.05.11
|
|
Отправлено: 21.06.11 20:51. Заголовок: Путь к базам в прогр..
Путь к базам в программе указан полностью. Пример я просто упростил. Обе программы использует один и тот же пользователь. Но программы могут быть установлены на разных компьютерах, соединенных в сеть. На данном этапе программа выдает сообщение, чтобы вышли с чужой программы. Для пользователя это не проблема. Если он не выйдет, тоже ничего страного не произойдет. Программа выдаст ошибку времени выполнения. Никаких потерь записей не произойдет. Просто хотелось бы в случае незанятости базы пропускать это сообщение, т.к. база открыта только в нескольких пунктах меню и не всегда прийдется выходить с программы. Индексные файлы базы, в которую добавляются записи, открывать не надо, так как они фокспрошные. После добавления будет переиндексация базы средствами чужой программы.
|
|
|
|
| |
Пост N: 58
Зарегистрирован: 20.02.11
|
|
Отправлено: 21.06.11 21:46. Заголовок: Хочется пропускать - пропускайте ...
SergeyKorotun пишет: цитата: | Просто хотелось бы в случае незанятости базы пропускать это сообщение |
| Хочется пропускать - пропускайте, есть же стандартный обработчик ситуации ( хотя может в 5.0 все както иначе ??? ) bSave := ERRORBLOCK( {|x| BREAK(x)} ) BEGIN SEQUENCE use reciver alias reciver new RECOVER ..... END SEQUENCE ERRORBLOCK(bSave)
|
|
|
|
| |
Пост N: 47
Зарегистрирован: 30.05.11
|
|
Отправлено: 23.06.11 01:46. Заголовок: в последнем get поле..
в последнем get поле добавил when функцию, которая проверяет значения в предыдущих полях и если что-то не так, пользователю alert-ом выдается предупреждение и функция возвращает .f. Так вот после нажатия энтера или пробела на сообщении завершается get...read, а мне еще надо ошибки поисправлять и в последнее поле значение ввести. Перенести функцию у valid предпоследнего get не предлагать (возникнут проблемы с выходом в вышележащие поля для исправления ошибок да и функция там уже есть и к тому же объемная)
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 23.06.11 13:06. Заголовок: when and valid - перемена мест слагаемых
Пусть исходный код имеет вид: .. 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()
|
|
|
|
| постоянный участник
|
Пост N: 546
Зарегистрирован: 27.01.07
|
|
Отправлено: 23.06.11 13:31. Заголовок: Не знаю, есть ли это..
Можно так: 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
|
|
|
|
| |
Пост N: 48
Зарегистрирован: 30.05.11
|
|
Отправлено: 23.06.11 22:26. Заголовок: petr707 пишет: Пуст..
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 просто бы не пустило в последнее поле, а выпускать в предыдущие поле (в отличие от валид) будет.
|
|
|
|
| |
Пост N: 49
Зарегистрирован: 30.05.11
|
|
Отправлено: 23.06.11 22:32. Заголовок: PSP пишет: Можно та..
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
|
|
|
|
| |
Пост N: 50
Зарегистрирован: 30.05.11
|
|
Отправлено: 23.06.11 22:36. Заголовок: При выполнении валид..
При выполнении валид функции и возвращении .f. курсор устанавливается в начало поля. Можно как то определить в какой позиции он находился, чтобы после возврата из валид установить его в ту позицию, где он был.
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 23.06.11 23:23. Заголовок: when and valid
Как-то сложновато выстраиватся у Вас система переходов по полям ввода и запретов перехода - можно даже сделать ловушку, из которой не выбраться.. Поймет ли User - в чем был неправ и как ему пройти лабиринт формы до конца? Предложение: 1) после завершения всех GET проверять все поля формы и либо разрешать запись данных либо сообщать, какие значения полей некорректны. 2) Для того чтобы не выбирать - в какой GET перевыставить ввод - нужно дать возможность User'ам клавишей K_UP (стрелка вверх) проходить к любому предыдущему полю любой Valid без проверки значений, поскольку видимо у Вас есть зависимость:следущее поле от предыдущих. 3) Не всегда запрещать выход из поля по некорректному значению , а только давать замечание ввода и разрешать ввод следующего поля, все равно User не сможет записать форму в конечной проверке всех полей при наличии каких-либо некорректных значений.
|
|
|
|
| |
Пост N: 51
Зарегистрирован: 30.05.11
|
|
Отправлено: 23.06.11 23:55. Заголовок: petr707 пишет: мож..
petr707 пишет: цитата: | можно даже сделать ловушку, из которой не выбраться.. |
| Их и делать то не надо, они в реале получаются. Поэтому на данный момент разрешаю покидать любое пустое поле. Если же поле не пустое, выполняются все проверки в валид функции и в случае наличия ошибок запрещается выход из поля. Перед входом в последнее поле (проверкой у when последнего поля) выдаю предупреждение о незаполненных обязательных полях и в случае их наличия хотел запретить вход в последнее поле. Пока ограничился только предупреждениям без запрета входа, иначе завершается get...read
|
|
|
|
| |
Пост N: 52
Зарегистрирован: 30.05.11
|
|
Отправлено: 24.06.11 00:06. Заголовок: можно ли средствами ..
Можно ли средствами клиппера считать ключ индексного файла cdx(создан foxpro) и пересоздать этот индекс? Или хотя бы зная ключ, создать cdx индекс? Как распечатать доку из NG?
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 24.06.11 07:35. Заголовок: можно..
|
|
|
|
| постоянный участник
|
Пост N: 547
Зарегистрирован: 27.01.07
|
|
Отправлено: 24.06.11 08:40. Заголовок: CDX встроен в RDD Кл..
CDX встроен в RDD Клиппер, начиная с 5.2e (если не ошибаюсь), а также Harbour.
|
|
|
|
| постоянный участник
|
Пост N: 548
Зарегистрирован: 27.01.07
|
|
Отправлено: 24.06.11 09:32. Заголовок: SergeyKorotun пишет:..
SergeyKorotun пишет: цитата: | А при переносе фокуса например из пятого поля в третье в четвертом поле будут выполняться when и valid функции? |
| В такой реализации редактирование Get-объекта полностью завершается, потом проверяется корректность данных и, если найдено поле с некоректными данными, то редактирование возобновляется, начиная с этого поля. Перед LOOP можно выдать какое-нибудь сообщение на экран. В данном случае проверка происходит вне Get-объекта. WHEN и VALID функции здесь не участвуют.
|
|
|
|
| |
Пост N: 53
Зарегистрирован: 30.05.11
|
|
Отправлено: 26.06.11 12:23. Заголовок: К файлу prg1 операто..
К файлу 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() // будет ли доступна здесь эта функция ...
|
|
|
|
| постоянный участник
|
Пост N: 549
Зарегистрирован: 27.01.07
|
|
Отправлено: 26.06.11 20:28. Заголовок: Функция видна во все..
Функция видна во всей программе, если она не объявлена STATIC.
|
|
|
|
| |
Пост N: 54
Зарегистрирован: 30.05.11
|
|
Отправлено: 27.06.11 19:36. Заголовок: Haz пишет: Попробуй..
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?
|
|
|
|
| |
Пост N: 61
Зарегистрирован: 20.02.11
|
|
Отправлено: 27.06.11 19:56. Заголовок: Или он глючит с клиппер 5.01?
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
|
|
|
|
| |
Пост N: 55
Зарегистрирован: 30.05.11
|
|
Отправлено: 14.07.11 12:50. Заголовок: 1) После запуска про..
1) После запуска программы на экран выводится сообщение "Расширенная ошибка 183". Но все работает. Что это за ошибка? 2) Как поочередно выводить сообщения то на экран, то в файл. При переключении с экрана на файл последний перезаписывается, а надо чтобы добавлялось в файл.
|
|
|
|
| |
Пост N: 2088
Зарегистрирован: 17.05.05
|
|
Отправлено: 14.07.11 13:03. Заголовок: SergeyKorotun пишет:..
SergeyKorotun пишет: Возможно Вы пытаетесь создать каталог который уже существует SergeyKorotun пишет: цитата: | а надо чтобы добавлялось в файл. |
| Про alternate речь ? Вероятно упустили ADDITIVE Синтаксис SET ALTERNATE TO [<имя файла>] [ADDITIVE] SET ALTERNATE on | OFF | <лог. выражение> Аргументы TO <имя файла> открывает стандартный ASCII файл для вывода информации (расширение по умолчанию - (.txt)). Имя файла может содержать расширение, обозначение дисковода и (или) путь доступа. Значение аргумента <имя файла> может быть определено либо как литеральное имя, либо как символьное выражение, заключенное в кавычки. Следует отметить, что если файл с таким именем уже существует, то он перезаписывается. ADDITIVE определяет, что информация, выводимая на экран, будет добавляться в файл, а не перезаписываться. Если предложение отсутствует, то заданный файл обрезается до нулевой длины перед тем, как в него будет записываться новая информация. ON вызывает дублирование выдачи информации на экран записью ее в открытый текстовый файл. OFF прерывает дублирование выдаваемой на экран информации в текстовый файл, не закрывая его. <лог. выражение> - логическое выражение, заключенное в скобки. Его значение "истина" (.T.) аналогично условию ON, значение "ложь"(.F.) - условию OFF.
|
|
|
|
| |
Пост N: 56
Зарегистрирован: 30.05.11
|
|
Отправлено: 15.07.11 15:49. Заголовок: Dima пишет: Возможн..
Dima пишет: цитата: | Возможно Вы пытаетесь создать каталог который уже существует |
| угадали Dima пишет: цитата: | Про alternate речь ? Вероятно упустили ADDITIVE |
| пробовал через set device to printer set printer on set console off set printer to txt\report.txt после вашей подсказки использовал alternate. все получилось, но хотелось бы узнать как реализовать через set device, set printer
|
|
|
|
| |
Пост N: 57
Зарегистрирован: 30.05.11
|
|
Отправлено: 15.07.11 16:00. Заголовок: база имеет индекс с ..
база имеет индекс с ключом t+str(f,7)+str(i,7)+str(o,7) t c 10 (всегда 10-ти значное значение) f n 7 i n 7 o n 7 Ищу в базе запись "9999999999"+str(ff,7)+str(ii,7)+str(oo,7), ff, ii, oo - переменніе с кодами FIO Если нахожу, устаналиваю фильтр чтобы отобразилось только это: "9999999999"+str(ff,7)+str(ii,7)+str(oo,7) и открываю базу browse() отображается одна или несколько записей, удовлетворяющих условию фильтра. изменяю 9999999999 например на 1234567890 запись исчезает, так как уже не удовлетворяет условию фильтра, а программа зависает. Почему? И не важно одна запись была изначально отображена или несколько.
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 15.07.11 16:34. Заголовок: set printer
set printer to ("a.txt") set device to print npos:=prow() SETPRC(npos,0) ... @npos++,1 say " to printer= 111111" ... set device to screen @5,5 say "to screen" ... set device to print ... @npos++,1 say " to printer= 22222" set printer to ...
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 15.07.11 16:40. Заголовок: зависает обзор таблицы
1)при изменении реквизита фильтра (а также при удалении записей) желательно применять что-нить типа SKIP 0 Browse() , Dbedit() - виснут, если удалить текущую запись обзора и не сместить указатель ( в режиме set deleted on) 2) возможно, программа не зависла, а просто browse()долго перестраивает фильтр
|
|
|
|
| |
Пост N: 58
Зарегистрирован: 30.05.11
|
|
Отправлено: 15.07.11 16:55. Заголовок: petr707 пишет: 2) в..
petr707 пишет: цитата: | 2) возможно, программа не зависла, а просто browse()долго перестраивает фильтр |
| там записей мало, ждал с пол-часа petr707 пишет: цитата: | 1)при изменении реквизита фильтра (а также при удалении записей) желательно применять что-нить типа SKIP 0 Browse() , Dbedit() - виснут, если удалить текущую запись обзора и не сместить указатель ( в режиме set deleted on) |
| а как у browse() выполнить skip?
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 15.07.11 17:49. Заголовок: browse - фильтр
Можно попробовать разные варианты, зависит от условий задачи 1) значение(функцию) фильтра содержать(заполнять) в отдельном служебном поле поле таблицы, фильтр ставить на служебное поле replace all indfileld with t+str(f,7)+str(i,7)+str(o,7) .. set filter to is_flt2(tt,ff,ii,oo) тогда изменение любого реквизита(поля БД) не приведет к изменению обзора и перестроению индекса 2) добавить фильтр в индексное выражение, индекс пересоздавать каждый раз для новых параметров tt,ff,ii,oo index on iif( is_flt(tt,ff,ii,oo), str(recno(),7),space(7)) to (...) UNIQUE set filter to is_flt(tt,ff,ii,oo) go top browse(..) ... Function is_flt(tt,ff,ii,oo) Local ret :=.f. ret:= (t=tt).and.(f=ff).and.(i=ii).and.(o=oo) return ret Function is_flt2(tt,ff,ii,oo) Local ret :=.f. ret:= (indfileld == tt+str(ff,7)+str(ii,7)+str(oo,7)) return ret
|
|
|
|
| |
Пост N: 59
Зарегистрирован: 30.05.11
|
|
Отправлено: 15.07.11 23:48. Заголовок: petr707 пишет: ...з..
petr707 пишет: цитата: | ...зависит от условий задачи... |
| подзадача такая: с базы YYY значение поля t(код клиента) (в примере переменная tt) ищу в базе GGG и если нахожу, удаляю запись в YYY, если же не нахожу, то ищу в базе GGG, но уже не tt, а по другому ключу "9999999999"+str(ff,7)+str(ii,7)+str(oo,7), где 9999999999 - это по каким то причинам неприсвоенное когда-то настоящее значение t (код клиента), ff. ii, oo - сответсвенно коды фамилии, имени та отчества с базы YYY (поля f. i. o) и если нахожу (по seek). то устанавливаю фильтр на базу GGG (t="9999999999" .and. yyy->f=ff .and. yyy->i=ii .and. yyy->o=oo) и browse() отображаю найденные записи. Их может быть несколько. Далее визуально просматривая все поля, определяю, есть ли такая запись, которая соответствует значению поля t из базы YYY и если есть, то заменяю 9999999999 на t. petr707 пишет: цитата: | 2) добавить фильтр в индексное выражение, индекс пересоздавать каждый раз для новых параметров tt,ff,ii,oo |
| tt я то знаю наперед, но сначала отобразятся записи базы командой browse() те, у которых t="9999999999", и только после этого возможно в одной из записей 9999999999 изменятся на t. Так что пересоздать индекс до открытия базы функцией browse() не получится. Первый вариант тоже не подходит, структуру базы изменять нельзя
|
|
|
|
| Администратор
|
Пост N: 2006
Зарегистрирован: 23.05.05
|
|
Отправлено: 16.07.11 08:35. Заголовок: SergeyKorotun пишет:..
SergeyKorotun пишет: цитата: | Ищу в базе запись "9999999999"+str(ff,7)+str(ii,7)+str(oo,7), ff, ii, oo - переменніе с кодами FIO Если нахожу, устаналиваю фильтр чтобы отобразилось только это: "9999999999"+str(ff,7)+str(ii,7)+str(oo,7) и открываю базу browse() отображается одна или несколько записей, удовлетворяющих условию фильтра. изменяю 9999999999 например на 1234567890 запись исчезает, так как уже не удовлетворяет условию фильтра, а программа зависает. Почему? И не важно одна запись была изначально отображена или несколько. |
| Вы scope так и не используете ? Если бы использовали, то никакой задержки (которая выглядит как зависание) не возникло бы. Но даже при этом вопрос решается элементарно просто. Изменение ключевого значения записи и перестройка фильтра: nr1 := recno() skip 1 // переходим на запись (причем быстро), которая должна стать текущей после изменения nr2 := recno() dbgoto(nr1) // возвращаемся field->key := newval // изменяем dbgoto(nr2) // переходим на новую текущую запись
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 16.07.11 09:03. Заголовок: Вариант "разделяй и властвуй"
1) для второй ветки процедуры ( поиск по 99999) для работы с отфильтрованными записями можно ставить фильтр не на основную таблицу GGG, а на рабочую производную таблицу TTT: только записи фильтра с полем ссылки(номер записи таблицы GGG).По ссылке можно править таблицу GGG. То есть смотрим на одну таблицу(с близкой структурой), правим другую. select ggg arr:=dbstruct() aadd(arr,{"recno","N",7,0}) dbcreate("ttt.dbf",arr) use (''ttt.dbf") alias ttt new exclusive select ggg .. if ggg->(dbseek(ckey,.f.)) do ggg->(!eof().and.ckey=...) ttt->(dbappend()) for i=1 to len(arr)-1 ttt->(fielput(i,ggg->(fieldget(i)))) next i ttt->recno:=ggg->(recno()) ggg->(dbskip()) enddo endif ... 2) Возможно, проще изменить основной алгоритм? Проход по базе YYY c двумя вариантами обработки для каждой записи YYY - меняем на Два прохода по YYY - первый проход -обработка1(без установки фильтров и визуальной правки) , при втором проходе - обработка2
|
|
|
|
| |
Пост N: 60
Зарегистрирован: 30.05.11
|
|
Отправлено: 16.07.11 14:38. Заголовок: для данной задачи пе..
для данной задачи перед использованием browse() отключил индекс, а после включил. После правки ключевых полей зависаний нет. Записей только несколько тысяч, отсутствие индексов тормозов не вызывает. А для больших индексированных баз использовать browse() наверно не получиться. В этой программе вместо browse() лучше было бы использовать dbedit (можно было бы по нажатию гарячей клавиши изменить значения полей в визуально выбранной записи), но программа для одноразового использование (навести порядок в базах, которые используются где то на протяжении 15 лет) и не хотелось лишний код писать.
|
|
|
|
| |
Пост N: 61
Зарегистрирован: 30.05.11
|
|
Отправлено: 16.07.11 14:40. Заголовок: Pasha пишет: Вы sco..
Pasha пишет: цитата: | Вы scope так и не используете ? Если бы использовали, то никакой задержки (которая выглядит как зависание) не возникло бы. |
| Пока даже не приступал к изучению. Не хватает времени. Я писал не про задержку, а про зависание программы при правке хотя бы одного ключевого поля в browse()
|
|
|
|
| |
Пост N: 62
Зарегистрирован: 30.05.11
|
|
Отправлено: 16.07.11 14:44. Заголовок: Pasha пишет: Измене..
Pasha пишет: цитата: | Изменение ключевого значения записи и перестройка фильтра: nr1 := recno() skip 1 // переходим на запись (причем быстро), которая должна стать текущей после изменения nr2 := recno() dbgoto(nr1) // возвращаемся field->key := newval // изменяем dbgoto(nr2) // переходим на новую текущую запись |
| И как все это выполнить из browse()
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 16.07.11 19:31. Заголовок: browse - dbedit
1) browse - dbedit - различие невелико, правка кода минимальна. Можно заменить в коде BROWSE() на BROWSE2() (см. ниже , код не проверял) Function browse2(w1,w2,w3,w4,harr,ctitle,arrf_) local oldshd,arr_str if w1=NIL w1:=1;w2:=0;w3:=maxrow();w4:=maxcol() endif private arrf:=arrf_ if arrf=NIL arrf:={} arr_str:=DBSTRUCT() aeval(arr_str,{|x| aadd(arrf,x[1])}) endif oldshd=wsetshadow(-1) wopen(w1,w2,w3,w4) wbox(1) if (ctitle=NIL) ctitle:="["+alias()+"]" endif private ctitlef:=ctitle private y1:= 0 private x1:= 0 private y2:=(w3-w1-2) private x2:=(w4-w2-2) @-1,1 say ctitle color c_pict dbedit(,,,,arrf,"f_browse2",,harr) wsetshadow(oldshd) wclose() return Function f_browse2(mode,col) Local arr_str:={},arrm:={} private cur_field := arrf[col] private var do case case mode<4 return 1 case lastkey()=K_ESC return 0 case lastkey()=K_ENTER //изменение значения в поле БД r1:=row();c1:=col() cVar_get:=FIELDBLOCK(cur_field) @ r ,c get cVar_get read if lastkey()#K_ESC &cur_field := cVar_get endif return 2 case lastkey()=K_DOWN // dbappend // можно дописать добавление записи return 2 otherwise return 2 endcase return 1 2) цитата: "для данной задачи перед использованием browse() отключил индекс, а после включил." переиндексация была ? или на время правки индекса не было ? set index to ..set index to ("index.ntx") лучше: nind :=indexord(); set order to 0 ;.... set order to nind
|
|
|
|
| |
Пост N: 63
Зарегистрирован: 30.05.11
|
|
Отправлено: 16.07.11 19:59. Заголовок: petr707 пишет: 2) ц..
petr707 пишет: цитата: | 2) цитата: "для данной задачи перед использованием browse() отключил индекс, а после включил." переиндексация была ? |
| Спасибо, как то упустил, что надо переиндексировать. Почитал ng, оказалось ничего не надо править, при set order to 0 индексы все равно корректируются
|
|
|
|
| |
Пост N: 64
Зарегистрирован: 30.05.11
|
|
Отправлено: 13.09.11 20:20. Заголовок: Как бы попроще реали..
Как бы попроще реализовать средствами clipper 5.01 поиск в базе снизу вверх(без сортировки)? Descend() не подойдет, так как для просмотра базы в обратном порядке надо было бы проиндексировать ее по одному ключу(например "номер заказа"), о поиск вести по второму ключу (например "код клиента").
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 13.09.11 22:49. Заголовок: индекс
В условии не вполне задано определение для "обратного порядка" 1) index on (kod_client)+(str(1000000-recno(),7) to tmp можно делать ретроспективу записей клиента - по факту добавления записей в таблицу 2) index on (kod_client)+(str(100000-nomer_zakaz,7) to tmp можно делать ретроспективу записей клиента - по убыванию номера заказа этого клиента .. seek cod0 do while !eof().and. kod_client==cod0 ... // обработка в порядке убывания - номера записи или номера заказа skip enddo
|
|
|
|
| |
Пост N: 65
Зарегистрирован: 30.05.11
|
|
Отправлено: 13.09.11 23:44. Заголовок: petr707 пишет: seek..
petr707 пишет: Как я понял, у вас cod0=(kod_client)+(str(100000-nomer_zakaz,7) Проблема в том, что нужно искать только по ключу kod_client, а не по ключу (kod_client+что-то еще) Или seek ищет подстроку в ключе(а не точное совпадение)? Если да, то тогда наверно вместо do while !eof().and. kod_client==cod0 надо do while !eof().and. kod_client=cod0, т.е. вместо == писать = Чтобы было понятней, что мне надо, напишу пример не оптимальной реализации задачи. Можно было бы сделать так: создать временную базу и занести в нее записи в обратном порядке (последняя запись в исходной базе становиться первой во временной базе, предпоследняя - второй и т.д.) Потом проиндексировать временную базу по kod_client и затем поиск по seek. Но хотелось бы обойтись без временной базы.
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 14.09.11 07:45. Заголовок: индекс - поиск по левой части
Вариант 1 - соответствует условию seek ищет не подстроку, а совпадение слева, поэтому и можно искать левую часть индексного выражения Лучше вместо seek применить dbseek( padr(cod0,len(kod_klient),.f.) "==" - нужно, иначе неверный результат отбора записей, например для cod0="12" при наличии в базе клиентов "12" "123" "1234".. сравнивается не индексное выражение, и именно значение поля.
|
|
|
|
| |
Пост N: 74
Зарегистрирован: 30.05.11
|
|
Отправлено: 29.01.13 01:29. Заголовок: Как в dbedit изменит..
Как в dbedit изменить размер колонок динамически? Нижеприведенный фрагмент программы не изменят ширину колонок (на самом деле колонок много, есть что подтягивать из за пределов монитора) apict дублировал и в процедуре - не помогает. С функции f1 с возвратом return 2 - ширина неизменна SET KEY K_F9 TO PictureSwich() pictFlg:=.t. pictSum:=13 apict:={replicate("9",pictSum)+".99"} acol:={"Summa"} aname:={"Сумма"} dbedit(2,1,21,78,acol,"f1",apict,aname) ... procedure PictureSwich() if pictFlg pictSum:=5 else pictSum:=13 endif pictFlg:=!pictFlg
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 29.01.13 05:51. Заголовок: Выход из Dbedit, переопределение колонок и заход снова
pictFlg:=.t. pictSum:=13 private lexit:=.f. private lwas_f9:=.f. do while !lexit if lwas_f9 lwas_f9:=.f. if pictFlg pictSum:=5 else pictSum:=13 endif pictFlg:=!pictFlg endif apict:={replicate("9",pictSum)+".99"} acol:={"Summa"} aname:={"Сумма"} dbedit(2,1,21,78,acol,"f1",apict,aname) if lexit; EXITl endif enddo .... Function f1(..) do case .. case lastkey()=K_F9 lexit:=.f. lwas_f9 :=.t. return 0 // exit from dbedit .. case lastkey()=K_ESC lexit:=.t. return 0 // exit from dbedit ....
|
|
|
|
| постоянный участник
|
Пост N: 2597
Зарегистрирован: 12.09.06
|
|
Отправлено: 29.01.13 12:38. Заголовок: SergeyKorotun пишет:..
SergeyKorotun пишет: Смиотри функцию AT()
|
|
|
|
| |
Пост N: 75
Зарегистрирован: 30.05.11
|
|
Отправлено: 29.01.13 23:55. Заголовок: ReadExit(.f.) @1,1 s..
sum:=0 ReadExit(.f.) @1,1 say 'Сумма' get sum picture("9999999999999.99") read Почему выходит с read после набора двух цифр после запятой? Как разрешить выход только по Enter?
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 30.01.13 06:00. Заголовок: SET CONFIRM ON
conf:=SET(_SET_CONFIRM) ... SET(_SET_CONFIRM,.t.) read ... SET(_SET_CONFIRM,conf) SET CONFIRM определяет, требуется ли ввод подтверждения для окончания ввода текущего GET. Если задано SET CONFIRM OFF, то после ввода пользователем последнего символа текущего GET, курсор перемещается на следующий GET, если он есть. Если следующего GET нет, выполнение команды READ прекращается. Если задано SET CONFIRM ON, ввод данных в переменную очередного GET должен завершаться нажатием клавиши выхода (<Enter> или <Esc>). Во всех случаях, если ввод в переменную текущего GET не был прерван нажатием клавиши <Esc>, выполняется предложение RANGE или VALID. За дополнительной информацией о команде GET следует обратиться к описанию команды @...GET.
|
|
|
Ответов - 105
, стр:
1
2
3
4
5
6
All
[только новые]
|
|