Как автоматически создать несколько документов на основании другого документа в 1С?

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

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

Решение задачи с передачей ссылки на документ-основание

Рассмотрим случай, когда подчиненные документы создаются программно на основании ведущего объекта. Для того чтобы в структуре подчиненности и в самом создаваемом документе сохранялась корректная связь с родительским документом, необходимо правильно передать его ссылку.

Для связывания объектов на стороне создаваемого документа передается параметр основания, а в обработке заполнения подчиненного документа заполняется соответствующий реквизит. Посмотрим на пример кода передачи ссылки при создании документа:


// Программное создание и передача ссылки на документ-основание
НовыйДокумент = Документы.ИмяСоздаваемогоДокумента.СоздатьДокумент();
НовыйДокумент.Заполнить(ЭтотОбъект.Ссылка);
НовыйДокумент.ДокументОснование = ЭтотОбъект.Ссылка;
НовыйДокумент.Записать(РежимЗаписиДокумента.Проведение);

На стороне самого создаваемого документа в модуле объекта в процедуре ОбработкаЗаполнения выполняется получение данных из основания:


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

Благодаря этому созданный документ получает ссылку на ПлатежноеПоручениеИсходящее, а в структуре подчиненности формируется корректная цепочка связей.

Риски реализации создания документов в процедуре «ОбработкаПроведения»

Несмотря на то, что размещение кода создания документов внутри модуля объекта в процедуре ОбработкаПроведения кажется простым решением, этот подход считается архитектурной ошибкой. Проанализируем основные риски:

  1. Длительные транзакции и блокировки: Создание, запись и проведение сторонних объектов внутри процедуры проведения сильно увеличивают время транзакции. В многопользовательской базе это ведет к блокировкам таблиц базы данных и взаимным блокировкам (deadlocks).
  2. Нарушение стандартов разработки 1С: Главное назначение процедуры ОбработкаПроведения — формирование движений по регистрам. Создавать или изменять ссылочные объекты (документы, справочники) внутри транзакции проведения не рекомендуется.
  3. Откат транзакции при ошибках: Если при проведении хотя бы одного из трех создаваемых документов произойдет ошибка (нехватка остатков, незаполненные реквизиты), произойдет откат всей транзакции. Основной документ также не проведется.
  4. Проблемы при повторном проведении и отмене проведения: При перепроведении документа без дополнительных проверок будут плодиться дубли подчиненных документов. При отмене проведения ведущего документа подчиненные останутся проведенными, что нарушит целостность учета.

Правильные архитектурные альтернативы

Чтобы избежать проблем с блокировками и дублированием данных, разберем рекомендуемые способы решения этой задачи.

Вариант 1. Интерактивное создание через команду формы

Создание пакета документов выносится в специальную команду на форме или обрабатывается при нажатии кнопки «Провести и закрыть» на стороне клиента.

  1. Пользователь нажимает кнопку на форме.
  2. На сервере выполняется поиск уже созданных документов-оснований.
  3. Если документы отсутствуют, они создаются, заполняются и проводятся.
  4. Пользователь получает явное уведомление о результатах создания.

Вариант 2. Использование подписки на событие «ПослеЗаписи»

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


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

Вариант 3. Асинхронная обработка (очередь и фоновые задания)

Для высоконагруженных систем оптимальным является использование регламентных и фоновых заданий:

  1. При проведении документа в специальный регистр сведений записывается задача на формирование комплектных документов.
  2. Фоновое задание по расписанию считывает записи из регистра, создает, связывает и проводит документы в отдельном потоке, не замедляя работу пользователя.

Обработка жизненного цикла связанных документов

При любом выбранном способе необходимо корректно обрабатывать отмену проведения и перепроведение:

  1. Контроль дублей: Перед созданием подчиненных объектов всегда выполняем запрос к базе данных или критерию отбора. Если документы уже существуют, их необходимо переформировать или обновить, а не создавать новые экземпляры.
  2. Отмена проведения и удаление: В подписке на событие ОбработкаУдаленияПроведения родительского документа следует либо запрещать отмену проведения при наличии проведенных подчиненных документов, либо автоматически распроводить связанную цепочку объектов.
← На главную