Распечатать страницу

Форма "Виды произведений" в Microsoft VFP

« Назад

Форма (рис. 2.30) имеет имя WtForm; она работает с одной таблицей WorkTypes, включенной в окружение данных формы.

20.1.-Форма-Виды-произведений

Рис. 2.30. Форма "Виды произведений"

Особенностью формы является то, что она функционирует в своей сессии данных (рис. 2.31).

20.2.-Задание-свойства-DataSession-формы-Виды-произведений

Рис. 2.31. Задание свойства DataSession формы "Виды произведений"

Это объясняется тем, что форма может быть открыта в том числе и совместно с формой "Содержание книг", в сетке которой имеется ссылка на таблицу WorkTypes, и если обе формы будут использовать глобальную сессию данных, то обновление WorkTypes в рассматриваемой форме будет приводить к искаженному представлению данных в сетке формы "Содержание книг".

Данные редактируются непосредственно в сетке формы WtForm, поэтому предусмотрена возможность отмены изменений. Она реализуется за счет употребления буферизации редактируемой записи. Режим буферизации устанавливается в обработчике события Init формы:

&& Обработчик события Init формы WtForm

&&

with This

.AutoCenter = .T.

.Grid1.DeleteMark = .F.      &&Устраняем столбец для пометки удаления

.Grid1.ReadOnly = .T.

&&

&& Столбец для дублирования пометки удаления

.Grid1.Column2.ReadOnly = .T.

.Grid1.Column2.ControlSource = "Iif(Deleted( ), '*', '')"

.Grid1.Column2.Width = 10

&&

Command4.Enabled = .F.   && Кнопка "Записать"

.Command5.Enabled = .F.  && Кнопка "Отмена

endWith

&&

&& Задаем режим оптимистической буферизации записи

set multilocks on

CursorSetProp('Buffering', 3)

Первоначально сетка формы и ее кнопки "Записать" и "Отмена" доступны только для чтения. При добавлении или обновлении записи эти объекты становятся доступными для редактирования, зато оказываются недоступными первые три кнопки формы. Отвечают за эти действия обработчики событий Click кнопок "Новый" и "Изменить":

&& Обработчик события Click кнопки "Новый"

&&

&& Запоминаем значение поля WorkType текущей записи

ThisForm.OldValue = WorkType.WorkType

&&

&& Добавляем чистую запись

append blank

&&

&& Управляем доступностью элементов управления формы

This.Enabled = .F.

with ThisForm

Command2.Enabled = .F.

.Command3.Enabled = .F.

.Command5.Enabled = .T.

Grid1.ReadOnly = .F.

Grid1.SetFocus

endWith

Обработчик события Click кнопки "Изменить" содержит тот же код, что и вышеприведенный обработчик, за исключением команды APPEND BLANK.

Кнопка "Записать" станет доступной, если внести в модифицируемую (добавляемую) запись хотя бы одно изменение. Это обеспечит обработчик события KeyPress элемента управления Text1 столбца сетки:

&& Обработчик события KeyPress объекта ThisForm.Grid1.Column1.Text1

&&

lparameters nKeyCode, nShiftAltCtrl

if not ThisForm.Grid1.ReadOnly

ThisForm.Command4.Enabled = not Empty(This.Value)

endif

После ввода данных, если нажать на кнопку "Записать", выполнится обработчик ее события Click:

&& Обработчик события Click кнопки "Записать"

&&

&& Обновляем таблицу на диске

TableUpdate( )

&&

&& Управляем доступностью элементов управления формы

This.Enabled = .F.

with ThisForm

Command1.Enabled = .T.

.Command2.Enabled = .T.

Command3.Enabled = .T.

.Command5.Enabled = .F.

.Grid1.ReadOnly = .T.

endWith

&&

&& Выполняем тривиальный поиск, чтобы обнаружить возможную

&& неуникальность поля WorkType. Проверка уникальности кандидатного

&& индекса WorkType выполняется, когда покидается редактируемая строка

wt = WorkType

seek wt

ThisForm.Grid1.SetFocus

Если уникальность поля WorkType нарушена, то об этой ошибке после нажатия кнопки "Записать" сообщит обработчик ее события Error:

&& Обработчик события Error кнопки "Записать"

&&

lparameters nError, cMethod, nLine

if nError = 1884 then

MessageBox("Вид произведения в таблице уже имеется!", 48)

&& Восстанавливаем данные и возвращаемся на прежнюю запись

TableRevert( )

seek ThisForm.OldValue

else

MessageBox("Ошибка № " + Transform(nError) + " в строке " ;

+ Transform(nLine) + " метода " + cMethod, 48)

endif

Также обработчик восстановит данные и вернет таблицу на ее прежнюю запись, выполнив соответственно TABLEREVERT( ) и SEEK.

Совершенно такой же обработчик имеет событие Error сетки формы. Он будет исполнен, в частности, в следующей ситуации: пользователь вводит неуникальное значение поля WorkType и выполняет попытку переместиться в сетке на другую запись, например оперируя мышью.

Если нажата кнопка "Отмена", то все изменения будут проигнорированы обработчиком ее события Click:

&& Обработчик события Click кнопки "Отмена"

&&

&& Восстанавливаем данные и возвращаемся на прежнюю запись

TableRevert( )

seek ThisForm.OldValue

This.Enabled = .F.

with ThisForm

.Command1.Enabled = .T.

.Command2.Enabled = .T.

.Command3.Enabled = .T.

.Command4.Enabled = .F.

.Grid1.ReadOnly = .T.

.Grid1.SetFocus

.Grid1.Refresh

endWith

Если же в процессе изменения записи в сетке по какой-либо причине пользователь переместится с редактируемой записи, то обработчик события LostFocus уже рассмотренного выше элемента управления Text1 сделает сетку недоступной:

&& Обработчик события LostFocus объекта ThisForm.Grid1.Column1.Text1

&&

if not ThisForm.Grid1.ReadOnly

ThisForm.Grid1.ReadOnly = .T.

endif

Останутся доступными кнопки: "Отмена" и "Выход", а также кнопка "Записать", если пользователь успел внести в редактируемое поле изменения.

Особенностью обработчика события Click кнопки "Удалить" является наличие в нем команды GO Recno( ), инициирующей выполнение заданного для таблицы триггера удаления:

if Deleted( )

recall

else

delete

endif

&& Инициируем срабатывание триггера удаления

go Recno( )

ThisForm.Grid1.SetFocus

Эта особенность порождается используемым режимом буферизации записи таблицы WorkTypes. По этой же причине изменен и обработчик события Error рассматриваемой кнопки.

&& Обработчик события Error кнопки "Удалить"

&&

lparameters nError, cMethod, nLine

if nError = 1539 then

MessageBox("Удалить нельзя. Вид произведения применен в таблице BooksContent!", 48)

&& Восстанавливаем состояние записи и название кнопки

TableRevert( )

ThisForm.Command3.Caption = "Удалить"

else

MessageBox("Ошибка № " + Transform(nError) + " в строке " ;

+ Transform(nLine) + " метода " + cMethod, 32)

endif