При разработке конфигураций на платформе 1С:Предприятие 7.7 разработчики нередко сталкиваются с ситуацией: в модуле формы документа программно вызывается метод Записать() (например, после закрытия модальной обработки или выполнения вспомогательного алгоритма), однако предопределенная процедура ПриЗаписи() не исполняется. При этом в синтакс-помощнике указано, что вызов метода Записать() в контексте формы отрабатывает действия, аналогичные интерактивному нажатию кнопки с формулой #Записать.
Разберем детально механизм работы событийной модели формы в 1С 7.7, выясним причину такого поведения и рассмотрим надежные способы решения задачи.
Проанализируем, как платформа 1С 7.7 обрабатывает сохранение объекта:
ПриЗаписи() в модуле формы документа является чисто интерфейсным событием. Платформа инициирует её вызов только при интерактивных действиях пользователя: нажатии кнопки с формулой #Записать, комбинации клавиш Ctrl + Enter или при подтверждении записи при закрытии измененного документа.Записать(): Указание в документации о схожести с кнопкой #Записать означает лишь то, что перед физической записью объекта в базу данных платформа считывает актуальные значения из элементов диалога экранной формы в реквизиты документа. Однако системный вызов интерфейсного обработчика ПриЗаписи() при этом не происходит, и документ сохраняется напрямую.Данное поведение одинаково проявляется на всех релизах платформы (включая 25 и 27 релизы). Поэтому рассчитывать на автоматический запуск проверки в ПриЗаписи() при программном сохранении нельзя.
В платформе 1С 7.7 предопределенные процедуры модуля формы являются обычными процедурами, доступными для прямого вызова из любого места этого же модуля. Если вам необходимо сохранить документ программно, но при этом выполнить все проверки, заложенные в ПриЗаписи(), вызовем эту процедуру явно перед методом Записать().
Обязательно проконтролируем результат проверок через функцию СтатусВозврата():
// Вызываем предопределенный обработчик вручную
ПриЗаписи();
// Проверяем, не был ли установлен отказ от записи внутри процедуры
Если СтатусВозврата() = 0 Тогда
// Если условия не выполнены, прерываем выполнение и не записываем документ
Возврат;
КонецЕсли;
// Если проверки пройдены успешно, производим запись
Записать();
Если внутри ПриЗаписи() при несоблюдении условий вызывается СтатусВозврата(0), данный код перехватит признак отказа и предотвратит сохранение некорректных данных.
Более универсальным и чистым с точки зрения архитектуры подходом является разделение интерфейсной логики и проверок данных. Создадим собственную процедуру (или функцию-валидатор) и будем обращаться к ней как из интерактивного обработчика, так и при программной записи.
Рассмотрим пример реализации:
// Функция валидации реквизитов документа
Функция ПроверитьЗаполнениеДокумента()
Если ПустоеЗначение(Контрагент) = 1 Тогда
Предупреждение("Не указан контрагент!");
Возврат 0;
КонецЕсли;
Если Итог("Сумма") <= 0 Тогда
Предупреждение("Сумма документа должна быть больше нуля!");
Возврат 0;
КонецЕсли;
Возврат 1;
КонецФункции
// Предопределенная процедура для интерактивной записи
Процедура ПриЗаписи()
Если ПроверитьЗаполнениеДокумента() = 0 Тогда
СтатусВозврата(0);
Возврат;
КонецЕсли;
КонецПроцедуры
// Пользовательская процедура, вызываемая после закрытия обработки
Процедура ЗаписатьПослеОбработки()
// Выполняем проверку
Если ПроверитьЗаполнениеДокумента() = 1 Тогда
Записать();
КонецЕсли;
КонецПроцедуры
Такой подход делает код более читаемым, исключает дублирование проверок и позволяет гибко управлять логикой сохранения документа из различных участков модуля формы.