Разработка программного обеспечения, ведение базы данных и получение ведомости с частичными суммами.
Реализация алгоритма обработки данныхи ведения реляционной базы данных.
Анализ обработки БД для её получения :
а) По какому файлу проводится главный цикл обработки ?
Главный цикл обработки в подпрограмме vedom
- (п.п., которая осуществляет выявление всех случаев превышения нормативных интервалов между профилактиками, вывод их в выводной файл “DD”, а также осуществляет выдачу ведомости на принтер) проводится по файлу bb.dbf
.
б) Как он должен быть упорядочен ?
Он должен быть упорядочен в хронологическом порядке.
Пример:
index on bb->invnom + dtoc(bb->dateprof) to bb0001
Справка:
Синтаксис:
INDEX ON <ключевое выражение> TO <имя индексного файла>
INDEX - команда обработки базы данных, которая создает файлы, содержащие индексы базы данных на основе значения аргумента <ключевое выражение>. При использовании индексного файла записи базы данных обрабатываются в последовательности, заданной ключевым выражением, однако физический порядок следования записей базы данных остается неизменным. INDEX обеспечивает последовательность записей, упорядоченную по значениям ключевого выражения. Для ключей типа CHARACTER - в соответствии со значением ASCII кода каждого символа внутри строки, для ключей типа NUMERIC - в соответствии с числовым порядком, для ключей типа дата - в хронологическом порядке и длялогических - считается, что истина (.Т.) - более высокого порядка.
Memo-поля не могут быть индексированы.
в) Применяются ли фильтры ?
Хотя команда SET FILTER делает так, что файл в рабочей области выглядит состоящим из подмножества записей, на самом деле последовательно обрабатываются все его записи.
Фильтры не применяются, т.к время работы с фильтрованной и нефильтрованной рабочей областью оказывается одним и тем же.
г) Имеются ли связи ”хозяин-слуга” и по каким полям ?
В подпрограмме vedom
имеются связи.
Пример:
а) set relat to bb->invnom into cc Связь по полю “invnom”.
б) set relat to cc->idst into aa additive Связь по полю “idst”.
в) set relat to dd->invnom into cc additive Связь по полю “invnom”.
Принципы подготовки данных для тестового примера и заполнения исходных данных.
Эти данные были выбраны произвольно - “из головы”:
1) Идентификатор типа станка
2) Инвентарный номер станка
3) Вид профилактики
4) Наименование типа станка
Идентификатор записи в файле bb.dbf
заполнялся по убыванию (от 1 до 18), где 1- первая запись, а 18- последняя.
Норма кол-ва дней между профилактиками была выбрана произвольна.
Дата профилактики выбиралась так, чтобы норма кол-ва дней между профилактиками была превышена для всех видов профилактик.
б) Пункты меню, что в них делается ?
Меню № 1:
1) Сразу приступить к работе с Базой Данных
2) Заново построить все индексы Базы Данных
3) Провести компрессию Базы Данных
4) Выход из Базы Данных
При выборе п.1, если индексы уже имеются мы попадаем в меню № 2.
При выборе п.2 заново происходит построение всех индексов Б.Д .
При выборе п.3 производится компрессия (уплотнение) Б.Д .
При выборе п.4 появляется горизонтальное подменю:
а) Сохранить и продолжить б) Завершить работу
П.а) Сохранить все внесенные изменения и продолжить
П.б) Завершить работу с базой данных с сохранением всех изменений
Меню № 2:
1) Ведение файла "Нормативы профилактики оборудования"
2) Ведение файла "Профилактика"
3) Получение ведомости нарушение норм техобслуживания
4) Выход из Базы Данных
При выборе п.1 мы попадаем в редактор файла aa.dbf - (“Нормативы профилактики оборудования”), где мы можем его просматривать и редактировать.
При выборе п.2 мы попадаем в редактор файла bb.dbf - (“Профилактика”), где мы можем его просматривать и редактировать.
При выборе п.3 происходит выявление всех случаев превышения нормативных интервалов между профилактиками, вывод их в выводной файл “DD”, а также выдача ведомости на принтер.
При выборе п.4 выполняются действия аналогичные п.4 в меню № 1.
Ведение БД .
Какими табл. представлено ведение БД, по какой табл. указывается текущая рабочая область, её слуги, колонки таблицы, набор клавиш на которые предусмотрена реакция системы.
Клавиши на которые реагирует система:
/ ¯ / ® / ¬ /; PgUp / PgDn; Home / End - Перемещение курсора
Enter - Выбор задачи в меню и редактирование полей в редакторе
Esc - Возврат на шаг назад. Отмена редактирования (без сохранения изменненого значения)
F8 - Удалить строку
F3 - Вставить строку
F10 - Выход из задачи с сохранением всей информации или выход без сохранения информации
Структура программы :
а) Содержимое rmk-файла “kursv.rmk”:
objs = main2,aa,util,bb
.prg.obj:
CLIPPER $< /a/m/n
.obj.exe:
RTLINK OUTPUT $* FI $(objs) /PLL:base52
main2.obj : main2.prg
aa.obj : aa.prg
util.obj : util.prg
bb.obj : bb.prg
kurs_ok.exe : main2.obj aa.obj util.obj bb.obj
б) Имена и содержание prg-файлов. По каждой функции: имя, назначение, параметры, тип данных и смысл, возвращенное значение, рабочие перемен-ные и их назначение.
Программные файлы:
1) aa.prg
В этой программе реализовано:
1. Создание TBrowse-объекта для просмотра-редактирования файла aa.dbf в окне.
2) bb.prg
В этой программе реализовано:
1. Создание TBrowse-объекта для просмотра-редактирования файла bb.dbf в окне.
3) main2.prg
В этой программе реализовано:
1.Организация меню.
2. Индексирование файлов.
3. Уплотнение файла .
4. Выявление всех случаев превышения нормативных интервалов между профилактиками, вывод их в выводной файл “DD”, а также выдача ведомости на принтер.
5. Вывод на экран информации о “горячих” клавишах.
4) util.prg
Эта программа содержит набор стандартных утилит:
1. Сохранение экрана, восстановление экрана.
2. Перевод в верхний регистр как латиницы, так и кириллицы.
3. Координаты, сообщение, цвет.
4. Выход из задачи с сохранением всей информации - реакция на клавишу F10.
5. Подача звукового сигнала для сигнализации успешного выполнения
поставленной задачи:
Описание основных подпрограмм:
1) п.п. постоения индексов:
func db_index(prm)
s_scr(24,0,25,79)
CLOSE ALL
SETCOLOR ("w/n")
@ 24,0 CLEAR TO 25,79
@ 24,6 SAY "Ждите идет индексирование! " COLOR "w+*/n"
use bb
index on bb->invnom + dtoc(bb->dateprof) to bb0001
use aa
index on aa->idst to aa0002
use cc
index on cc->invnom to cc0003
use dd
index on dd->(norma-fkdn) to dd0004
close all
r_scr()
return nil
2) п.п. открытия индексов:
func db_open
close all
use aa index aa0002
use bb index bb0001 new
use cc index cc0003 new
use dd index dd0004 new
return nil
3) п.п. уплотнения Б.Д. :
FUNCTION db_compress()
s_scr(24,0,25,79)
CLOSE ALL
SETCOLOR("w/n")
@ 24,0 CLEAR TO 25,79
@ 24,6 SAY "Ждите идет уплотнение !" COLOR ("w+*/n")
USE aa // уплотнение файла aa.dbf
COPY TO work
IF ERRORLEVEL() = 0
USE
DELETE FILE aa.dbf
RENAME work.dbf TO aa.dbf
ENDIF
USE bb // уплотнение файла bb.dbf
COPY TO work
IF ERRORLEVEL() = 0
USE
DELETE FILE bb.dbf
RENAME work.dbf TO bb.dbf
ENDIF
USE cc // уплотнение файла cc.dbf
COPY TO work
IF ERRORLEVEL() = 0
USE
DELETE FILE cc.dbf
RENAME work.dbf TO cc.dbf
ENDIF
USE dd // уплотнение файла dd.dbf
COPY TO work
IF ERRORLEVEL() = 0
USE
DELETE FILE dd.dbf
RENAME work.dbf TO dd.dbf
ENDIF
CLOSE ALL
r_scr()
RETURN NIL
4) п.п. выдачи информации о клавишах, на которые реагирует система ”Help”:
PROCEDURE hlp(callpnt,prm)
LOCAL retcol,crow,ccol
IF prm = NIL
prm := .F.
ENDIF
crow = ROW()
ccol = COL()
retcol = SETCOLOR("w/n")
@ 22,0 CLEAR TO 24,79
IF callpnt = "GET"
// исправленный HLP для GET 26.09.96
@ 22,0 SAY "Enter/" + CHR(24) + '/' + CHR(25) + '/PgUp/PgDn' ;
+ " -Завершить редактирование с сохранением измененного значения"
@ 22,0 SAY "Enter/"+ CHR(24) + '/' + CHR(25) + '/PgUp/PgDn' COLOR "r+/n"
@ 23,1 SAY CHR(26) + ' / ' + CHR(27) + ' / ^' + CHR(26) ;
+ ' / ^' + CHR(27) + ' / Home / End - Перемещение курсора'
@ 23,1 SAY CHR(26) + ' / ' + CHR(27) + ' / ^' + CHR(26) ;
+ ' / ^' + CHR(27) + ' / Home / End' COLOR "r+/n"
@ 24,1 SAY 'Esc - Отменить редактирование ' ;
+ '( без сохранения измененного значения )'
@ 24,1 SAY "Esc" COLOR "r+/n"
ENDIF
IF callpnt="AAED" .OR. callpnt="BBED"
SET COLOR TO ("w/n")
@ 22,1 SAY chr(24) + " / " + chr(25) + " / " + CHR(26) + ' / ' ;
+ CHR(27) + ' / ^' + CHR(26) + " PgUp / PgDn " ;
+ ' / ^' + CHR(27) + '/ Home / End - Перемещение курсора'
@ 24,0 SAY 'Enter - Редактирование '
@ 23,23 TO 24,23 DOUBLE
@ 23,25 SAY 'Esc - Возврат на шаг назад ' COLOR "w/n"
@ 23,25 SAY 'Esc' COLOR "r+/n"
@ 23,54 TO 24,54 DOUBLE
@ 23,55 SAY 'F8 - Удалить строку '
@ 24,55 SAY 'F3 - Вставить строку '
SET COLOR TO ("r+/n")
@ 22,1 SAY chr(24) + " / " + chr(25) + " / " + CHR(26) + ' / ' ;
+ CHR(27) + ' / ^' + CHR(26) + " PgUp / PgDn " ;
+ ' / ^' + CHR(27) + '/ Home / End '
@ 24,0 SAY 'Enter'
@ 23,55 SAY 'F8'
@ 24,55 SAY 'F3'
ENDIF
IF callpnt="CCED" .OR. callpnt="DDED"
SET COLOR TO ("w/n")
@ 22,1 SAY chr(24) + " / " + chr(25) + " / " + CHR(26) + ' / ' ;
+ CHR(27) + ' / ^' + CHR(26) + " PgUp / PgDn " ;
+ ' / ^' + CHR(27) + '/ Home / End - Перемещение курсора'
@ 24,0 SAY 'Enter - Редактирование '
@ 23,23 TO 24,23 DOUBLE
@ 23,25 SAY 'Esc - Возврат на шаг назад ' COLOR "w/n"
@ 23,25 SAY 'Esc' COLOR "r+/n"
@ 24,25 SAY '^Enter - Выбор значения ' COLOR "w/n"
@ 24,25 SAY '^Enter' COLOR "r+/n"
@ 23,54 TO 24,54 DOUBLE
@ 23,55 SAY 'F8 - Удалить строку '
@ 24,55 SAY 'F3 - Вставить строку '
SET COLOR TO ("r+/n")
@ 22,1 SAY chr(24) + " / " + chr(25) + " / " + CHR(26) + ' / ' ;
+ CHR(27) + ' / ^' + CHR(26) + " PgUp / PgDn " ;
+ ' / ^' + CHR(27) + '/ Home / End '
@ 24,0 SAY 'Enter'
@ 23,55 SAY 'F8'
@ 24,55 SAY 'F3'
ENDIF
SET COLOR TO (retcol)
SETPOS(crow,ccol)
RETURN
5) п.п. выявления всех случаев превышения нормативных интервалов между профилактиками, вывода их в выводной файл “DD”, а также выдачи ведомости на принтер:
func vedom
local tinvnom,sitog,tdata,tidzap,tidst,idpop
set printer on
select dd
zap
lin:=space(17)+"Таблица нарушение норм техобслуживания:"
? lin
select bb
set relat to bb->invnom into cc
set relat to cc->idst into aa additive
go top
sitog:=0
do while .not. eof()
tinvnom:=bb->invnom
tdata:=bb->dateprof
tidzap:=bb->idzap
tidst:=cc->idst
skip
if(bb->invnom=tinvnom).and.(bb->dateprof-tdata>aa->norma)
select dd
append blank
replace dd->invnom with tinvnom
replace dd->fkdn with bb->dateprof-tdata
replace dd->norma with aa->norma
replace dd->idzappp with tidzap
replace dd->idzapsp
sitog:=sitog+(dd->fkdn-dd->norma)
select bb
endif
enddo
lin:="+-----------------------------------------------------------------------------+"
? lin
lin:="¦ Инв.¦ Наименование ¦ Дата ¦ Вид предвор. ¦ Дата ¦ вид след. ¦Просроч.¦"
? lin
lin:="¦номер¦ типа станка ¦ ¦ профилактики ¦ ¦ профилактики ¦ дней ¦"
? lin
lin:="¦-----+--------------+--------+--------------+--------+--------------+--------¦"
? lin
select dd
set relat to dd->invnom into cc additive
go top
do while .not. eof()
tinvnom:=dd->invnom
idpop:=dd->idzappp
lin:="¦ "+dd->invnom+" ¦ "
select bb
go top
do while .not. eof()
if(tinvnom=bb->invnom).and.(idpop=bb->idzap)
lin:=lin+aa->namest+" ¦"+dtoc(bb->dateprof)+"¦ "+bb->vidprof
endif
skip
enddo
select dd
idpop:=dd->idzapsp
select bb
go top
do while .not. eof()
if(tinvnom=bb->invnom).and.(idpop=bb->idzap)
lin:=lin+" ¦"+dtoc(bb->dateprof)+"¦ "+bb->vidprof+"¦ "
endif
skip
enddo
select dd
lin:=lin+str(dd->fkdn-dd->norma,4)+" ¦"
? lin
skip
enddo
lin:="+-----------------------------------------------------------------------------+"
? lin
set color to w+/b
lin:=" Всего просроченно дней -"+str(sitog,5)
? lin
set printer off
sound()
inkey(0)
return nil
6) п.п. подачи звукового сигнала для сигнализации успешного выполнения
поставленной задачи:
func sound
tone(300,1)
tone(100,1)
tone(300,1)
tone(100,1)
return nil
7) п.п. сохранения зкрана:
FUNC s_scr(t,l,b,r)
IF t = NIL
t := 0
ENDIF
IF l = NIL
l := 0
ENDIF
IF b = NIL
b := MAXROW()
ENDIF
IF r = NIL
r := MAXCOL()
ENDIF
AADD( wind[1], t )
AADD( wind[2], l )
AADD( wind[3], b )
AADD( wind[4], r )
AADD( wind[5], SAVESCREEN(t,l,b,r) )
AADD( pos[1], ROW() )
AADD( pos[2], COL() )
AADD( colr, SETCOLOR() )
AADD( curs, SETCURSOR() )
RETURN .T.
8) п.п. восстановления зкрана:
FUNC r_scr()
LOCAL ln
ln := LEN(wind[1])
IF ln == 0
@ 24,0 SAY ' Ошибка - стек для восстановления параметров пуст '
INKEY(0)
@ 24,0
ENDIF
RESTSCREEN(wind[1,ln], wind[2,ln], wind[3,ln], wind[4,ln], wind[5,ln] )
ASIZE(wind[1],ln-1)
ASIZE(wind[2],ln-1)
ASIZE(wind[3],ln-1)
ASIZE(wind[4],ln-1)
ASIZE(wind[5],ln-1)
SETPOS( pos[1,ln], pos[2,ln] )
ASIZE(pos[1],ln-1)
ASIZE(pos[2],ln-1)
SETCOLOR(colr[ln])
ASIZE(colr,ln-1)
SETCURSOR(curs[ln])
ASIZE(curs,ln-1)
RETURN .T.
9) п.п. определения - нажата ли клавиша типового метода, если да - то возвращает блок кода с соответствующим методом, если нет - то возвращает NIL. Параметр функции - INKEY-код нажатой клавиши.
FUNC basemet(cod)
LOCAL ret , ei , i
LOCAL crsm:={ ;
{K_DOWN , {|o| o:down() } } ;
, {K_UP , {|o| o:up() } } ;
, {K_PGDN , {|o| o:pagedown() } } ;
, {K_PGUP , {|o| o:pageup() } } ;
, {K_CTRL_PGDN , {|o| o:gobottom() } } ;
, {K_CTRL_PGUP , {|o| o:gotop() } } ;
, {K_RIGHT , {|o| o:right() } } ;
, {K_LEFT , {|o| o:left() } } ;
, {K_CTRL_RIGHT , {|o| o:panright() } } ;
, {K_CTRL_LEFT , {|o| o:panleft() } } ;
, {K_END , {|o| o:end() } } ;
, {K_HOME , {|o| o:home() } } ;
, {K_CTRL_END , {|o| o:panend() } } ;
, {K_CTRL_HOME , {|o| o:panhome() } } }
i := ASCAN( crsm, {|ei| cod = ei[1] } )
IF i <> 0
ret := crsm[i,2]
ELSE
ret := NIL
ENDIF
RETURN ret
10) п.п. переключения режима вставка/замена и вида курсора:
PROCEDURE Repl_Ins()
IF READINSERT()
READINSERT(.F.)
SETCURSOR(SC_INSERT)
ELSE
READINSERT(.T.)
SETCURSOR(SC_NORMAL)
ENDIF
RETURN
11) п.п. перевода в верхний регистр латиницы и кириллицы:
FUNC UpperC(prm)
LOCAL n , i , smb , cs
n := LEN( prm )
FOR i = 1 TO n
smb := SUBSTR( prm , i , 1 )
cs := ASC( smb )
DO CASE
CASE cs >= 97 .AND. cs <= 122
cs := cs - 32
prm := STUFF( prm , i , 1 , CHR( cs ) )
CASE cs >= 160 .AND. cs <= 175
cs := cs - 32
prm := STUFF( prm , i , 1 , CHR( cs ) )
CASE cs >= 224 .AND. cs <= 239
cs := cs - 80
prm := STUFF( prm , i , 1 , CHR( cs ) )
ENDCASE
NEXT
RETURN prm
12) п.п. выхода из задачи с сохранением всей информации - реакция на клавишу F10:
PROCEDURE fquit()
LOCAL reply
reply := ALERT("Сохранить все внесенные изменения и продолжить;" ;
+ "работу с Базой данных - т.е. сделать промежуточный SAVE или;" ;
+ " Завершить работу с базой данных с сохранением всех изменений ;";
, {" Сохранить и продолжить " , " Завершить работу " } )
IF ( reply = 1 ) .OR. ( reply = 0 )
DBCOMMITALL()
ELSE
QUIT
ENDIF
RETURN
13) п.п. вывода сообщения на экран с заданными координатами и цветом:
PROCEDURE msgs(x,y,m,color)
LOCAL ml,c
IF m = NIL
RETURN
ENDIF
ml=LEN(m)
IF ml=0 && .OR. ml > 80
RETURN
ENDIF
IF x=NIL // Центр по X
x := (80-ml)/2
ENDIF
IF y=NIL // Центр по Y
y := 24/2 - 1
ENDIF
IF color <> NIL
c := SETCOLOR(color)
@ y,x SAY m
SETCOLOR(c)
ELSE
@ y,x SAY m
ENDIF
RETURN
14) п.п. создания TBrowse-объекта для просмотра-редактирования
файла aa.dbf в окне t,l,b,r :
FUNCTION aaCr(t,l,b,r)
LOCAL brws,coln,cblk,chdr
brws := TBrowseDb(t,l,b,r)
cblk := {|| " " + aa->idst }
chdr := "Идент. типа станка"
coln := TBColumnNew(chdr,cblk)
coln:width := 19
brws:AddColumn(coln)
cblk := {|| " " + aa->namest}
chdr := " Наименование типа станка"
coln := TBColumnNew(chdr,cblk)
coln:width := 35
brws:AddColumn(coln)
cblk := {|| STR( aa->norma,7) }
chdr := " Норма,дней"
coln := TBColumnNew(chdr,cblk)
coln:width := 12
brws:AddColumn(coln)
brws:colsep := CHR(186)
brws:headsep := CHR(205)
brws:colorspec := "w+/b,gr+/rb"
RETURN brws
15) п.п. просмотра файла aa.dbf с обработкой нажимаемых клавиш и вызовом соответствующих методов или пользовательских функций:
FUNCTION aaEd(brws)
LOCAL ret_fl,sel,otb , w
LOCAL cc,rr,nrc:=0,i
LOCAL ret:=NIL
LOCAL t := brws:nTop , l := brws:nLeft , b := brws:nBottom , r := brws:nRight
LOCAL t_ := 5 , l_ := 6 , b_ := 15 , r_ := 74
s_scr()
s_r_s()
SETCOLOR( "N/W" )
CLS
SETCOLOR( "gr+/b,w+/gr")
hlp("AAED")
SELECT aa
SET ORDER TO 2
@ t-2 , l-1 CLEAR TO b+2 , r+1
@ b+1, l TO b+1, r
ret_fl := .F.
DO WHILE .NOT. ret_fl
** оптимизированная с использованием буфера клавиатуры стабилизация
DO WHILE ( NEXTKEY() == 0 ) .AND. ( .NOT. brws:stabilize() )
ENDDO
IF ( NEXTKEY() == 0 ) .AND. ( RECNO() <> nrc)
nrc := RECNO()
rr := ROW()
cc := COL()
SETCOLOR("bg+/b")
@ t-2 , l+1 SAY " Нормативы профилактики оборудования:"
@ b+2 , l+1 SAY " Тип станка: "
@ b+2 , COL()+1 SAY aa->namest COLOR "w+/b"
SETPOS(rr,cc)
ENDIF
SETCOLOR("gr+/rb")
** ожидаем нажатия клавиши
nkey := Inkey(0)
// если нажата клавиша типового метода - вызовем его
blk := basemet( nKey )
IF blk <> NIL
EVAL( blk , brws )
ELSE
DO CASE
CASE ( bHotkey := SETKEY( nKey ) ) <> NIL
EVAL( bHotkey , PROCNAME() , PROCLINE() , READVAR() )
CASE ( nKey = K_F8 )
DELETE
// потрогаем файловый указатель, если
// возвращаетя EOF() - .T. после Down-Up,
// значит файл пуст
SKIP
SKIP -1
IF RECNO() = RECCOUNT()+1
ret_fl := .T. // завершение просмотра
ENDIF
brws:RefreshAll()
nrc := 0
CASE nKey = K_ESC
ret_fl := .T. // завершение просмотра
CASE ( nKey = K_ENTER )
// Редактирование текущего элемента данных
aaGet(brws ;
, " Редактирование файла aa.dbf" )
nrc := 0 // обновить верхнюю строку
CASE nKey == K_F3
APPEND BLANK
brws:RefreshAll()
ENDCASE
ENDIF
ENDDO
SET RELAT TO
s_r_s(.T.)
r_scr()
RETURN ret
16) п.п. выполнения GET в текущей колонке файла aa.dbf:
PROCEDURE aaGet( brws , z0 )
LOCAL r , c , w , w2 , otb
LOCAL retcurs,retexit // форма курсора и режим выхода из READ
LOCAL retins, retcol // режим вставка-замена в READ
LOCAL indch := .F. // флаг изменений значений полей, входящих в
// индекснове выражение (тогда нужно REFRESHALL(),
// а не REFRESHCURRENT() )
LOCAL col
r := ROW()
c := COL()
// Проверка обновления экрана, корректности базы и т.д.
ForceStable(brws)
// Установка клавиш Up-Arrow и Down-Arrow как клавиш выхода из
// команды READ
retexit := READEXIT(.T.)
// Установка клавиши INS для переключения
// режима вставка/замена
// и соответствующего изменения вида курсора
retins := SetKey( K_INS, {|| Repl_Ins()} )
// эквивалентно Set Key K_INS To Procedure Repl_Ins
// Установка вида курсора по текущему состоянию режима
retcurs := SetCursor( IF(ReadInsert(), SC_NORMAL, SC_INSERT ) )
s_scr()
retcol := SETCOLOR("w+/g")
@ brws:nTop-3,0
@ brws:nTop-3,0 SAY z0
hlp("GET")
SETCOLOR("gr+/n,w+/g")
indch := .F.
DO CASE
CASE brws:colpos = 1
w := aa->idst
@ r,c+2 GET w
READ
IF .NOT.( LASTKEY() = K_ESC ).OR.( aa->idst == w )
REPLACE aa->idst WITH w
indch := .T.
ENDIF
CASE brws:colpos = 2
n := aa->namest
@ r,c+2 GET n
READ
IF .NOT.( LASTKEY() = K_ESC ).OR.( aa->namest == n )
REPLACE aa->namest WITH n
ENDIF
CASE brws:colpos = 3
w := aa->norma
@ r,c+1 GET w
READ
IF .NOT.( ( LASTKEY() = K_ESC ) .OR. ( aa->norma = w ) )
REPLACE aa->norma WITH w
ENDIF
ENDCASE
SETCOLOR(retcol)
r_scr()
SETPOS(r,c)
IF indch
brws:RefreshAll()
ELSE
brws:RefreshCurrent() // Обеспечить перерисовку текущей строки,
ENDIF // поскольку изменялся элемент данных
// Восстановление формы курсора и режима выхода из READ по стрелкам
// и процедуры по клавише K_INS
SetCursor(retcurs)
READEXIT(retexit)
SetKey(K_INS, retIns)
// Проверка требования ухода с текущей записи после GET
nKey := LASTKEY()
IF nKey == K_UP .OR. nKey == K_DOWN .OR. ;
nKey == K_PGUP .OR. nKey == K_PGDN
// управление курсором -- переход к другой записи
KEYBOARD( CHR(nKey) )
ENDIF
RETURN