В практике разработки 1С часто возникает задача: при проведении или выполнении действия над одним документом (например, ПлатежноеПоручениеИсходящее) автоматически сформировать и провести несколько других связанных документов. Рассмотрим, как передать ссылку на родительский документ, проанализируем риски выполнения этой операции в обработке проведения и изучим правильные архитектурные альтернативы.
Рассмотрим случай, когда подчиненные документы создаются программно на основании ведущего объекта. Для того чтобы в структуре подчиненности и в самом создаваемом документе сохранялась корректная связь с родительским документом, необходимо правильно передать его ссылку.
Для связывания объектов на стороне создаваемого документа передается параметр основания, а в обработке заполнения подчиненного документа заполняется соответствующий реквизит. Посмотрим на пример кода передачи ссылки при создании документа:
// Программное создание и передача ссылки на документ-основание
НовыйДокумент = Документы.ИмяСоздаваемогоДокумента.СоздатьДокумент();
НовыйДокумент.Заполнить(ЭтотОбъект.Ссылка);
НовыйДокумент.ДокументОснование = ЭтотОбъект.Ссылка;
НовыйДокумент.Записать(РежимЗаписиДокумента.Проведение);
На стороне самого создаваемого документа в модуле объекта в процедуре ОбработкаЗаполнения выполняется получение данных из основания:
Процедура ОбработкаЗаполнения(ДанныеЗаполнения, СтандартнаяОбработка)
Если ТипЗнч(ДанныеЗаполнения) = Тип("ДокументСсылка.ПлатежноеПоручениеИсходящее") Тогда
ЭтотОбъект.ПлатежноеПоручениеИсходящее = ДанныеЗаполнения;
КонецЕсли;
КонецПроцедуры
Благодаря этому созданный документ получает ссылку на ПлатежноеПоручениеИсходящее, а в структуре подчиненности формируется корректная цепочка связей.
Несмотря на то, что размещение кода создания документов внутри модуля объекта в процедуре ОбработкаПроведения кажется простым решением, этот подход считается архитектурной ошибкой. Проанализируем основные риски:
ОбработкаПроведения — формирование движений по регистрам. Создавать или изменять ссылочные объекты (документы, справочники) внутри транзакции проведения не рекомендуется.Чтобы избежать проблем с блокировками и дублированием данных, разберем рекомендуемые способы решения этой задачи.
Создание пакета документов выносится в специальную команду на форме или обрабатывается при нажатии кнопки «Провести и закрыть» на стороне клиента.
Если создание должно происходить автоматически без участия пользователя, вынесем логику в подписку на событие ПослеЗаписи. Это позволяет убедиться, что основной документ уже записан и проверен, а транзакция его проведения завершена.
// В подписке на событие ПослеЗаписи с проверкой режима записи
Если Источник.РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
// Выполняем поиск уже созданных подчиненных документов,
// чтобы не создавать дубли при перепроведении
СформироватьПодчиненныеДокументы(Источник.Ссылка);
КонецЕсли;
Для высоконагруженных систем оптимальным является использование регламентных и фоновых заданий:
При любом выбранном способе необходимо корректно обрабатывать отмену проведения и перепроведение:
ОбработкаУдаленияПроведения родительского документа следует либо запрещать отмену проведения при наличии проведенных подчиненных документов, либо автоматически распроводить связанную цепочку объектов.