Реализация алгоритма обработки данных

Разработка программного обеспечения, ведение базы данных и получение ведомости с частичными суммами.



Реализация алгоритма обработки данных и ведения реляционной базы данных.





Анализ обработки БД для её получения :

а) По какому файлу проводится главный цикл обработки ?

 Главный цикл обработки в подпрограмме 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 with bb->idzap

 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