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

Форма AuthorEdit в Visual FoxPro

« Назад

При нажатии в форме "Авторы" на кнопку "Новый" или "Изменить" открывается форма AuthorEdit (рис. 2.19), в которой можно задать значения полей новой записи или изменить существующую запись таблицы Authors.

13.1.-Форма-для-ввода-или-редактирования-записи

Рис. 2.19. Форма для ввода или редактирования записи

В форму добавлены 2 свойства и 1 метод (рис. 2.20).

13.2.-Новые-свойства-и-метод-формы

Рис. 2.20. Новые свойства и метод формы

Свойство NoError будет иметь значение .T., если при записи не возникнет ошибки. Свойство Op хранит значение параметра, передаваемого форме при ее открытии и равного либо 'new', если форма открыта для ввода новой записи, либо 'edit', если – для редактирования. Значение свойства Op определяется в обработчике события Init формы и далее не изменяется. Потребность в этом свойстве обусловлена тем, что область видимости параметра oPr формы – локальная, а его значение используется в других процедурах формы.

Форма открывается модально (это видно из обработчика события Init формы) – переход в другое окно, пока форма открыта, невозможен.

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

&&

lparameters oPr

&& Предотвращаем вывод сообщений команды CALCULATE

set talk off

This.WindowType = 1        && Открываем форму модально

This.AutoCenter = .T.         && и располагаем ее по центру экрана

if not Used('Authors') then

MessageBox("Таблица Authors должна быть открыта!")

This.Command1.Enabled = .F.        && Кнопка "Сохранить" будет недоступна

This.Caption = "Таблица Authors не открыта"

return

endif

select Authors

if Pcount( ) = 0 then

oPr = 'new'

endif

with This

.Op = oPr                            && Op – новое свойство формы

if oPr = 'new' then               && Новая запись

.Caption = 'Новая запись'  && Заголовок формы

recOld = Recno( )

&& Ищем код нового автора

calculate Max(AuthorId) to .AuthorId.Value

go recOld

AuthorId.Value = .AuthorId.Value + 1

&& Инициализация значений свойства Value полей формы

store "" to .Author.Value, .Information.Value

.InputDate.Value = Date( ) && Текущая дата

else                                      && Редактирование записи

.Caption = 'Редактирование записи'

&& Данные для полей формы берутся из таблицы Authors

AuthorId.Value = AuthorId

Author.Value = Author

InputDate.Value = InputDate

Information.Value = Information

endif

endWith

Если форма открывается автономно, то число переданных параметров равно нулю. В этом случае в oPr устанавливается значение 'new'. Возможность автономного открытия формы предусмотрена для ускорения этапа ее проектирования.

В случае новой записи (oPr = 'new') автоматически определяется код автора (используется команда CALCULATE), значение свойства Value поля ввода InputDate устанавливается равным текущей дате. В дальнейшем и код, и дата могут быть пользователем изменены. При редактировании в форме отображаются значения текущей записи таблицы Authors.

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

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

&&

lparameters nError, cMethod, nLine

do case

case nError = 1583

MessageBox("Нарушено правило проверки записи таблицы Authors!", 48)

case nError = 1884

MessageBox("Код неуникален!", 48)

otherwise

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

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

endcase

ThisForm.NoError = .F.

Ошибка с номером 1583 возникает, когда нарушается заданное для таблицы Authors правило AuthorId >= 0 (см. рис. 2.12). Кроме того, поскольку индекс AuthorId является первичным, VFP самостоятельно проверить его уникальность. Если она нарушена, то возникнет ошибка с номером 1884.

При любой обнаруженной ошибке обработчик события Error выдаст соответствующее предупреждение и свойство формы NoError получит значение .F., которое затем будет использовано обработчиком события Click кнопки "Сохранить".

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

&&

local isDone

isDone = .T.

with ThisForm

NoError = .T.

if .CheckFields( ) then

begin transaction                 && Начинаем транзакцию

іf .Op = 'new' then

insert into Authors ;

values(.AuthorId.Value, ;

Author.Value, ;

InputDate.Value, ;

Information.Value)

else

if IsRlocked( ) or not Rlock( )

MessageBox("Запись недоступна!")

isDone = .F.

else

replace AuthorId with .AuthorId.Value, ;

Author with .Author.Value, ;

InputDate with .InputDate.Value ;

Information with .Information.Value

endif

record Recno && Снимаем блокировку записи

endif

if isDone and .NoError then

end transaction                   && Завершаем транзакцию

Release                                && Освобождаем форму

else

&& Отмена изменений при обнаружении ошибки

rollBack

endif

endif

endWith

Обработчик обеспечивает либо добавление записи в таблицу Authors, либо замену текущей. Однако эти операции будут выполнены, если, во-первых, данные не содержат пустых значений и, во-вторых, не возникло ошибки исполнения и, следовательно, не был вызван обработчик события Error кнопки "Сохранить".

Отвечает за проверку полей добавленный в форму метод CheckFields:

&& Метод CheckFields формы AuthorEdit

&&

with ThisForm

&&

&& Проверяем поля ввода; они не должны быть пустыми

if Empty(.AuthorId.Value) then

MessageBox('Задайте код!')

return .F.

endif

if Empty(.Author.Value) then

MessageBox('Не задан автор!')

return .F.

endif

if Empty(.InputDate.Value) then

MessageBox('Нужно задать дату ввода данных об авторе!')

return .F.

endif

endWith

Замечание. Если бы система не выполняла проверку уникальности кода автора автоматически, то в рассматриваемый метод пришлось бы добавить следующий код:

with ThisForm

&&

&& Проверка уникальности кода

recOld = Recno( )

ordOld = Order( )

set order to AuthorId

flag = .T.

if Seek(.AuthorId.Value) then

if .Op = 'new' then              && Новая запись

MessageBox('Код не уникален!')

flag = .F.

else                                      && Редактирование записи

do while .AuthorId.Value = AuthorId and not Eof( )

if Recno( ) != recOld then

MessageBox('Код не уникален!')

flag = .F.

exit

endif

skip

enddo

endif

endif

  go recOld

set order to (ordOld)

return flag

endWith

В приведенном варианте доступа к таблицам Authors и BooksAuthors буферизация не используется; таблица BooksAuthors задействуется при выполнении триггера __RI_UPDATE_authors( ).

Форма закроется, если данные записаны (транзакция завершена). В этом случае isDone и ThisForm.NoError имеют значение .T.

Значение isDone определяется обработчиком события Click кнопки "Сохранить": если запись заблокирована текущим приложением или если не удается заблокировать запись, то переменная isDone получит значение .F. и команда REPLACE выполнена не будет.

Если же нажать на "Отказ", то выполнится метод

ThisForm.Release

и форма закроется. В принципе, в обработчик события Click кнопки "Отказ" можно встроить вопрос, например такой: "Закрыть форму?", и при отрицательном ответе работа с формой должна быть продолжена.