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



Пост 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? Или только посимвольно проверять?

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





Пост N: 55
Зарегистрирован: 30.05.11
ссылка на сообщение  Отправлено: 14.07.11 12:50. Заголовок: 1) После запуска про..


1) После запуска программы на экран выводится сообщение "Расширенная ошибка 183". Но все работает. Что это за ошибка?

2) Как поочередно выводить сообщения то на экран, то в файл. При переключении с экрана на файл последний перезаписывается, а надо чтобы добавлялось в файл.

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




Пост N: 2088
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 14.07.11 13:03. Заголовок: SergeyKorotun пишет:..


SergeyKorotun пишет:

 цитата:
"Расширенная ошибка 183"


Возможно Вы пытаетесь создать каталог который уже существует

SergeyKorotun пишет:

 цитата:
а надо чтобы добавлялось в файл.


Про alternate речь ?

Вероятно упустили ADDITIVE

 
Синтаксис

SET ALTERNATE TO [<имя файла>] [ADDITIVE]
SET ALTERNATE on | OFF | <лог. выражение>

Аргументы

TO <имя файла> открывает стандартный ASCII файл для вывода информации
(расширение по умолчанию - (.txt)). Имя файла может содержать
расширение, обозначение дисковода и (или) путь доступа. Значение
аргумента <имя файла> может быть определено либо как литеральное имя,
либо как символьное выражение, заключенное в кавычки. Следует
отметить, что если файл с таким именем уже существует, то он
перезаписывается.

ADDITIVE определяет, что информация, выводимая на экран, будет
добавляться в файл, а не перезаписываться. Если предложение
отсутствует, то заданный файл обрезается до нулевой длины перед тем,
как в него будет записываться новая информация.

ON вызывает дублирование выдачи информации на экран записью ее в
открытый текстовый файл.

OFF прерывает дублирование выдаваемой на экран информации в текстовый
файл, не закрывая его.

<лог. выражение> - логическое выражение, заключенное в скобки. Его
значение "истина" (.T.) аналогично условию ON, значение "ложь"(.F.) -
условию OFF.



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



Пост 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


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



Пост 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
запись исчезает, так как уже не удовлетворяет условию фильтра, а программа зависает. Почему? И не важно одна запись была изначально отображена или несколько.

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



Не зарегистрирован
Зарегистрирован: 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
...

Спасибо: 0 
Цитата Ответить



Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 15.07.11 16:40. Заголовок: зависает обзор таблицы


1)при изменении реквизита фильтра (а также при удалении записей)
желательно применять что-нить типа SKIP 0
Browse() , Dbedit() - виснут, если удалить текущую запись обзора и не сместить указатель ( в режиме set deleted on)
2) возможно, программа не зависла, а просто browse()долго перестраивает фильтр

Спасибо: 0 
Цитата Ответить



Пост 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?


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



Не зарегистрирован
Зарегистрирован: 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


Спасибо: 0 
Цитата Ответить



Пост 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() не получится.
Первый вариант тоже не подходит, структуру базы изменять нельзя

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




Пост 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) // переходим на новую текущую запись


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



Не зарегистрирован
Зарегистрирован: 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



Спасибо: 0 
Цитата Ответить



Пост N: 60
Зарегистрирован: 30.05.11
ссылка на сообщение  Отправлено: 16.07.11 14:38. Заголовок: для данной задачи пе..


для данной задачи перед использованием browse() отключил индекс, а после включил. После правки ключевых полей зависаний нет. Записей только несколько тысяч, отсутствие индексов тормозов не вызывает. А для больших индексированных баз использовать browse() наверно не получиться.
В этой программе вместо browse() лучше было бы использовать dbedit (можно было бы по нажатию гарячей клавиши изменить значения полей в визуально выбранной записи), но программа для одноразового использование (навести порядок в базах, которые используются где то на протяжении 15 лет) и не хотелось лишний код писать.

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



Пост N: 61
Зарегистрирован: 30.05.11
ссылка на сообщение  Отправлено: 16.07.11 14:40. Заголовок: Pasha пишет: Вы sco..


Pasha пишет:

 цитата:
Вы scope так и не используете ? Если бы использовали, то никакой задержки (которая выглядит как зависание) не возникло бы.


Пока даже не приступал к изучению. Не хватает времени. Я писал не про задержку, а про зависание программы при правке хотя бы одного ключевого поля в browse()

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



Пост 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()

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



Не зарегистрирован
Зарегистрирован: 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


Спасибо: 0 
Цитата Ответить



Пост N: 63
Зарегистрирован: 30.05.11
ссылка на сообщение  Отправлено: 16.07.11 19:59. Заголовок: petr707 пишет: 2) ц..


petr707 пишет:

 цитата:
2) цитата: "для данной задачи перед использованием browse() отключил индекс, а после включил."
переиндексация была ?


Спасибо, как то упустил, что надо переиндексировать.

Почитал ng, оказалось ничего не надо править, при set order to 0 индексы все равно корректируются

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



Пост N: 64
Зарегистрирован: 30.05.11
ссылка на сообщение  Отправлено: 13.09.11 20:20. Заголовок: Как бы попроще реали..


Как бы попроще реализовать средствами clipper 5.01 поиск в базе снизу вверх(без сортировки)? Descend() не подойдет, так как для просмотра базы в обратном порядке надо было бы проиндексировать ее по одному ключу(например "номер заказа"), о поиск вести по второму ключу (например "код клиента").

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



Не зарегистрирован
Зарегистрирован: 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


Спасибо: 0 
Цитата Ответить



Пост N: 65
Зарегистрирован: 30.05.11
ссылка на сообщение  Отправлено: 13.09.11 23:44. Заголовок: petr707 пишет: seek..


petr707 пишет:

 цитата:
seek cod0


Как я понял, у вас 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. Но хотелось бы обойтись без временной базы.

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



Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 14.09.11 07:45. Заголовок: индекс - поиск по левой части


Вариант 1 - соответствует условию
seek ищет не подстроку, а совпадение слева, поэтому и можно искать левую часть индексного выражения
Лучше вместо seek применить dbseek( padr(cod0,len(kod_klient),.f.)
"==" - нужно, иначе неверный результат отбора записей, например для cod0="12" при наличии в базе клиентов "12" "123" "1234"..
сравнивается не индексное выражение, и именно значение поля.


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

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