9. Состояние формы

Форма может быть в трех состояниях: состоянии просмотра записей, вставки записи и изменения записи. Исходным состоянием формы является просмотр. Узнать о текущем состоянии можно из свойства State, тип которого TDataSetState. Свойство может иметь следующие значения:

  • dsBrowse – состояние просмотра записей,
  • dsInsert – состояние вставки записи,
  • dsEdit – состояние изменения записи.

Состояние формы может изменить пользователь или скрипт, вызвав соответствующий метод формы.

Изменение, сохранение записей и отмена изменений

Нельзя просто взять и присвоить полю какое-то значение. В состоянии просмотра вы можете только читать данные полей. Если попытаться изменить поле в состоянии просмотра, то программа выдаст ошибку. Для изменения поля сначала нужно перевести форму в состояние изменения записи. Пример:

Self.Edit;
Self['Сумма'] := 2000; 
Self['В резерве'] := 1; 
Self.Post;

Метод Edit переводит форму в состояние изменения записи (State = dsEdit). После этого можно изменять поля текущей записи. Метод Post сохраняет изменения записи в базу.

OldValues

У формы есть свойство OldValues [Name: String]: Variant, которое возвращает старое значение поля до изменения.

Метод Edit вызывает следующие события:

OnBeforeEdit – возникает перед переводом формы в состояние изменения записи.

OnAfterEdit – возникает после перевода формы в состояние изменения записи.

Метод Post вызывает события:

OnBeforePost – возникает перед сохранением записи.

OnAfterPost – возникает после сохранения записи.

Метод ''Cancel''

отменяет сделанные изменения в записи. При этом возникают следующие события:

OnBeforeCancel – возникает перед отменой изменений.

OnAfterCancel – возникает после отмены изменений.

Проверка ввода (OnValidate)

Перед сохранением изменений в окне редактирования (о нем будет рассказано далее) возникает событие OnValidate. Тип события TValidateEvent. Вот краткий пример обработчика этого события:

procedure ValidateChanges(Sender: TObject; var Ok: Boolean);
begin
  Ok := False;
  if Self['Дата'] = Null then
    MsgBox('Ошибка ввода', 'Дата должна быть заполнена')
  else if Self['Деталь'] = Null then
    MsgBox('Ошибка ввода', 'Деталь не выбрана')
  else
  Ok := True;
end;
 
procedure Form_Create;
begin
  Self.OnValidate := @ValidateChanges;
end;

В случае успешной проверки параметру Ok присваивается значение True. Если Ok = False, то запись не сохраняется и форма остается в том же состоянии (вставки или изменения).

Если запись изменяется в скрипте и сохраняется методом Post, то проверка ввода не осуществляется. Для выполнения проверки перед сохранением вызовите метод Validate. При вызове этого метода возникает событие OnValidate.

Добавление записей (Append)

Метод Append добавляет новую запись. Форма переводится в состояние вставки записи (State = dsInsert). Пример:

Self.Append; Self['Дата'] := Date;
Self['Статус'] := 'Новая'; 
Self.Post;

Тут все почти также как с Edit: после присваивания значений полям сохраняем изменения в базу. Метод Append вызывает события OnBeforeInsert – событие до вставки записи, и OnAfterInsert – событие после вставки записи. (Кроме этих событий вызываются еще два, о которых пойдет речь ниже: OnBeforeScroll и OnAfterScroll.) Если Append вызывается в то время, когда форма в состоянии вставки/изменения, то перед вставкой текущая запись сохраняется (неявно вызывается метод Post). Обратите внимание, что проверка ввода при явном и неявном вызове метода Post выполнена не будет.

Удаление записей (Delete)

Метод Delete удаляет текущую запись из базы вместе с подчиненными данными в подчиненных формах. Вызывает следующие события:

OnBeforeDelete – событие до удаления,

OnAfterDelete – событие после удаления.

Удаление может быть выполнено независимо от состояния формы.

Права доступа и блокировка записей

Не всегда есть возможность изменить или удалить запись. Например, запись может редактироваться или быть удалена другим пользователем, или действие ограничено правами доступа. Форма имеет методы, позволяющие определить доступность записей: CanAppend, CanDelete и CanEdit, которые возвращают значение типа TAccessStatus. Ниже приведены возможные значения, возвращаемые методами:

Значение Методы Описание
asOk CanAppend, CanEdit, CanDelete Действие (добавление, изменение, удаление) разрешено и возможно.
asCantAppend CanAppend Действие запрещено правами доступа или родительская форма не находится в состоянии изменения или вставки.
asCantEdit CanEdit Действие запрещено правами доступа или родительская форма не находится в состоянии изменения или вставки.
asCantDelete CanDelete Действие запрещено правами доступа или родительская форма не находится в состоянии изменения или вставки.
asModified CanEdit, CanDelete Запись была изменена другим пользователем. Программа бы в этом случае сообщила об этом пользователю и предложила обновить данные. В скрипте же решение за вами. Желательно обновить данные, потому что изменения могут повлиять на право изменения или удаления записи.
asDeleted CanEdit, CanDelete Запись была удалена другим пользователем.
asLocked CanEdit, CanDelete Запись редактируется другим пользователем. Изменение записи невозможно.
asHasRef CanDelete На запись есть ссылки в других формах, удалить нельзя.

Вышеуказанные методы необязательно вызывать перед изменением или удалением записи. Методы Append, Edit и Delete сами вызывают методы CanAppend, CanEdit и CanDelete, чтобы определить возможность добавления, изменения или удаления записи. В случае успеха возвращается asOk.

Надо заметить, что Append, Edit и Delete выполнятся успешно, даже если изменение и удаление ограничено правами доступа. Если данные действия нельзя выполнять по условию доступа, то вызовите CanAppend, CanEdit или CanDelete перед операцией.

Методы могут вернуть asCantAppend, asCantEdit и asCantDelete и в том случае, когда действие разрешено правами доступа. Такой результат получится, если попытаться совершить операцию в подчиненной форме в то время, когда родительская форма не находится в состоянии редактирования/вставки. Метод Edit блокирует запись для остальных пользователей при многопользовательском доступе к базе. Методы Post и Cancel снимают блокировку. Ошибки в коде могут привести к зависшим блокировкам, если ошибка возникла между Edit и Post/Cancel. Однако блокировка автоматически снимается простым перезапуском программы.