Почему не вызывается ПриСозданииНаСервере при загрузке данных и как программно заполнить документ в 1С?

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

Многие разработчики сталкиваются с ситуацией: при создании документа пользователем вручную нужные реквизиты корректно подставляются по умолчанию. Однако, если тот же документ загружается из внешней системы (например, из сервиса Контур) или создается программным кодом, эти реквизиты остаются пустыми. Давайте разберем причину такого поведения и выясним, как правильно реализовать логику инициализации объекта.

Проанализируем архитектурную проблему "Форма vs Объект"

Основная ошибка кроется в нарушении стандартов разработки, заложенных в Библиотеку стандартных подсистем (БСП). Событие ПриСозданииНаСервере относится исключительно к отрисовке пользовательского интерфейса. Оно срабатывает в модуле формы только тогда, когда эта форма генерируется для показа пользователю.

Когда вызов идет через внешний код интеграции (например, загрузка документов), форма не создается вообще. Код просто выполняет метод СоздатьДокумент(), присваивает значения реквизитам и вызывает Записать(). Именно поэтому обработчик формы игнорируется платформой. Рассмотрим по шагам, куда следует переносить такую бизнес-логику.

Вариант 1: Использование события ОбработкаЗаполнения

Наиболее правильным и архитектурно верным решением является перенос логики заполнения в модуль объекта, а именно в обработчик ОбработкаЗаполнения. Это событие универсально и может отрабатывать как при интерактивном вводе, так и программно.

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


ДокОбъект = Документы.ЗаказКлиента.СоздатьДокумент();
ДокОбъект.Заполнить(Неопределено); // Вот здесь сработает ОбработкаЗаполнения
ДокОбъект.Записать();

Если код интеграции просто создает и записывает документ без вызова метода заполнения, это событие будет проигнорировано платформой.

Вариант 2: Использование события ПередЗаписью

Если изменить внешнюю загрузку невозможно и метод заполнения там не вызывается, рассмотрим другой вариант: обработчик ПередЗаписью в модуле самого документа. Событие ПриЗаписи для этого не подходит, так как в этот момент объект уже сохранен в базу данных, и его модификация вызовет ошибки или потребует повторной записи.

В событии ПередЗаписью нам необходимо обязательно проверить, что документ создается впервые, чтобы не перезаписать данные пользователя при перепроведении существующих документов. Разберем пример реализации:


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    // Проверяем, что это создание нового документа
    Если ЭтотОбъект.ЭтоНовый() Тогда
        // Заполняем реквизиты по умолчанию
        ЭтотОбъект.НужныйРеквизит = ЗначениеПоУмолчанию;
    КонецЕсли;
    
КонецПроцедуры

Важный нюанс: обращайте внимание на флаг ОбменДанными.Загрузка. Внешние интеграции и типовые обмены часто устанавливают Объект.ОбменДанными.Загрузка = Истина перед сохранением. Если в вашем обработчике стоит проверка, прерывающая выполнение бизнес-логики при этом флаге, ваша инициализация не сработает. Убедитесь, что логика заполнения находится в правильном месте или учитывает этот режим.

Вариант 3: Использование Расширений и Подписок на события

По современным стандартам 1С конфигурацию поставщика рекомендуется оставлять на замке. Поэтому дорабатывать модуль типового документа напрямую не стоит. Посмотрим, как это обойти:

  1. Расширения конфигурации. Вы можете перехватить методы ПередЗаписью или ОбработкаЗаполнения нужного документа с помощью аннотаций &Перед или &После и написать логику там.
  2. Подписки на события. Если расширения использовать нельзя, создайте подписку на событие ПередЗаписью конкретного документа и вынесите логику заполнения нового объекта в отдельный общий модуль.

Нестандартный метод: ПриУстановкеНовогоНомера

В платформе 1С действительно нет специализированного события «При программном создании объекта». Однако есть одно событие, которое гарантированно срабатывает только для новых документов в момент генерации номера (обычно перед самой записью) — ПриУстановкеНовогоНомера.

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

Подводя итоги, проанализируем ситуацию: если ваш реквизит заполняется только в форме, вынесите эту логику в модуль объекта. Лучшим выбором будет ОбработкаЗаполнения при условии правильного вызова, или ПередЗаписью через механизм Расширений с проверкой на ЭтоНовый().

← На главную