Можно ли использовать метод Записать() в событии ПриОткрытии() формы документа 1С?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

В процессе разработки конфигураций 1С часто возникает задача подстановки или корректировки реквизитов документа при его открытии. Например, требуется проверить совпадение договора с документом-основанием и при расхождении подставить верное значение. Разберем, можно ли вызвать метод Записать() прямо в событии ПриОткрытии() модуля формы документа и к каким последствиям это может привести.

Почему не следует вызывать метод Записать() при открытии формы

Технически платформа 1С позволяет вызвать метод Записать() из модуля формы в момент открытия. Однако с точки зрения архитектуры и безопасности данных делать это категорически не рекомендуется. Проанализируем основные риски и проблемы, с которыми можно столкнуться при таком подходе:

  1. Ошибка прав доступа и запрета редактирования: Если пользователь открывает документ в режиме просмотра, либо в системе установлена дата запрета изменения данных, либо действуют ограничения RLS, вызов метода Записать() приведет к критической ошибке платформы. В результате пользователь даже не сможет просмотреть документ.
  2. Неконтролируемое проведение и формирование движений: Если документ уже был проведен, вызов метода записи из формы может запустить повторное проведение или отмену проведения (в зависимости от настроек и режима записи). Это спровоцирует пересчет остатков и записей в регистрах без осознанного действия со стороны пользователя.
  3. Ошибки проверки заполнения: Если в документе не заполнены другие обязательные реквизиты, процедура записи вызовет стандартную проверку заполнения и завершится ошибкой, заблокировав открытие формы.
  4. Блокировка данных в транзакции: Вызов записи при открытии устанавливает транзакционные блокировки в базе данных. При высокой интенсивности работы пользователей это создает риски возникновения конфликтов блокировок.
  5. Нарушение интерактивности и аудита: При автоматическом вызове Записать() сбрасывается признак Модифицированность формы, а событие сразу фиксируется в журнале регистрации. Если пользователь решит просто закрыть форму без сохранения, данные в базе уже окажутся измененными.
  6. Пропуск групповой и программной обработки: Логика, зашитая исключительно в событие формы ПриОткрытии(), сработает только при интерактивном открытии документа пользователем. Если документ проводится или изменяется программно (в обработках, фоновых заданиях или при обмене данными), несоответствие реквизитов не будет исправлено.

Правильные способы решения задачи

Рассмотрим альтернативные и архитектурно верные подходы к изменению и синхронизации реквизитов документа.

Вариант 1. Интерактивное изменение реквизита на форме без автоматической записи

Если необходимо скорректировать данные при открытии формы, мы можем изменить значение реквизита и сообщить платформе, что форма была изменена. При этом выбор — сохранять документ или нет — остается за пользователем.

Рассмотрим пример кода в модуле формы:


Процедура ПриОткрытии()
    Если ЗначениеЗаполнено(ДокументОснование) И ДоговорКонтрагента <> ДокументОснование.ДоговорКонтрагента Тогда
        ДоговорКонтрагента = ДокументОснование.ДоговорКонтрагента;
        ЭтаФорма.Модифицированность = Истина;
        Предупреждение("Договор контрагента был автоматически скорректирован по документу-основанию. Сохраните документ.");
    КонецЕсли;
КонецПроцедуры

Вариант 2. Проверка и перезаполнение в модуле объекта (ПередЗаписью)

Для того чтобы бизнес-логика отрабатывала гарантированно — как при интерактивном сохранении из формы, так и при программной записи документа — переносят валидацию в событие ПередЗаписью() модуля объекта.

Рассмотрим пример реализации в модуле объекта документа:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    Если ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    
    Если ЗначениеЗаполнено(ДокументОснование) И ДоговорКонтрагента <> ДокументОснование.ДоговорКонтрагента Тогда
        ДоговорКонтрагента = ДокументОснование.ДоговорКонтрагента;
    КонецЕсли;
КонецПроцедуры

Вариант 3. Заполнение при создании на основании (ОбработкаЗаполнения)

Если реквизиты должны совпадать с документом-основанием в момент создания нового документа, следует использовать стандартную процедуру ОбработкаЗаполнения() в модуле объекта:


Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
    Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ЗаказПокупателя") Тогда
        ДокументОснование = ДанныеЗаполнения;
        ДоговорКонтрагента = ДанныеЗаполнения.ДоговорКонтрагента;
    КонецЕсли;
КонецПроцедуры

Вариант 4. Обработка изменения реквизитов на форме

При изменении документа-основания пользователем вручную пересчет зависимых реквизитов (например, договора) необходимо выполнять в событии ПриИзменении соответствующего элемента управления формы.

Подводя итог: менять значение реквизита в ПриОткрытии() допустимо, но вызывать метод Записать() в этом событии не следует. Все критичные проверки и автоматические исправления должны располагаться в модуле объекта или выполняться интерактивно с подтверждением пользователя.

← На главную