Как программно создать несколько документов на основании одного и связать их в структуре подчиненности

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

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

Разберем подробно, как реализовать пакетное создание документов в коде и как правильно настроить метаданные конфигурации, чтобы связь корректно отображалась как в родительском, так и в дочерних объектах.

Принцип работы механизма связанных документов

Платформа 1С:Предприятие и типовые конфигурации (1С:ERP, 1С:Комплексная автоматизация, 1С:Управление торговлей) определяют связи между объектами с помощью объекта метаданных КритерийОтбора (в типовых решениях он называется СвязанныеДокументы) и механизмов БСП (Библиотеки Стандартных Подсистем).

Для того чтобы документ отображался в подчиненных у другого документа, платформа не требует вызова интерактивного механизма «Ввод на основании». Достаточно соблюдения двух условий:

  1. В подчиненном документе реквизит связи (например, ДокументОснование) должен содержать ссылку на исходный проведенный или записанный документ.
  2. В метаданных критерия отбора СвязанныеДокументы должны быть корректно настроены состав и тип данных.

Программное создание нескольких документов в цикле

Рассмотрим пример, когда из модуля формы или модуля объекта документа-основания требуется создать по одному документу ЗаказНаряд_st на каждую строку табличной части ОС.

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

Посмотрим на пример серверной процедуры создания документов:


&НаСервере
Процедура СоздатьЗаказНарядыПострочноНаСервере()
	
	// Проверяем, записан ли текущий документ-основание
	Если Объект.Ссылка.Пустая() Тогда
		ВызватьИсключение "Перед формированием подчиненных документов необходимо записать текущий документ!";
	КонецЕсли;
	
	НачатьТранзакцию();
	Попытка
		
		Для Каждого СтрокаОС Из Объект.ОС Цикл
			
			ДокументОбъект = Документы.ЗаказНаряд_st.СоздатьДокумент();
			
			// Заполнение шапки документа
			ДокументОбъект.Дата = Объект.Дата;
			ДокументОбъект.Организация = Объект.Организация;
			ДокументОбъект.Клиент = Объект.Партнер;
			ДокументОбъект.Контрагент = Объект.Арендатор;
			ДокументОбъект.Подразделение = Объект.Подразделение;
			ДокументОбъект.Менеджер = Объект.Менеджер;
			ДокументОбъект.Договор = Объект.Договор;
			ДокументОбъект.АдресМестонахождения = Объект.АдресМестонахождения;
			ДокументОбъект.АдресМестонахожденияЗначенияПолей = Объект.АдресМестонахожденияЗначенияПолей;
			
			ДокументОбъект.Статус = Перечисления.СтатусыЗаказНарядов.Ожидание;
			ДокументОбъект.МестоСервиса = Перечисления.МестаСервиса.ВМастерской;
			
			// Установка ссылки на документ-основание для дерева подчиненности
			ДокументОбъект.ДокументОснование = Объект.Ссылка;
			
			// Заполнение табличной части подчиненного документа
			НоваяСтрока = ДокументОбъект.ОС.Добавить();
			ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаОС);
			
			// Запись и проведение созданного документа
			ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
			
		КонецЦикла;
		
		ЗафиксироватьТранзакцию();
		
	Исключение
		ОтменитьТранзакцию();
		ИнформацияОбОшибке = КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
		ВызватьИсключение "Ошибка при пакетном создании документов: " + ИнформацияОбОшибке;
	КонецПопытки;

КонецПроцедуры

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

Настройка критерия отбора «СвязанныеДокументы»

Проанализируем распространенную проблему: подчиненные документы созданы, реквизит ДокументОснование заполнен, но в документе-основании дерево связей остается пустым, хотя в самом подчиненном документе основание отображается.

Причина такого поведения кроется в односторонней или неполной настройке критерия отбора метаданных. Разберем по шагам, как проверить настройки критерия отбора СвязанныеДокументы в конфигураторе:

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

Особенности работы в типовых конфигурациях и БСП

В современных конфигурациях вывод связанных объектов контролируется подсистемой БСП «Структура подчиненности». Если после правки критерия отбора типовой отчет все еще не видит документы, обратим внимание на следующие моменты:

  1. Тип параметров общей команды: в общей команде открытия структуры подчиненности (или СвязанныеДокументы) в свойстве «Тип параметров команды» должен быть отмечен тип нового документа.
  2. Права доступа (RLS): если у текущего пользователя нет прав на чтение нового вида документа или наложены ограничения на уровне записей, платформа автоматически исключает такие строки из выборки критерия отбора без генерации системных ошибок.
  3. Разработка в расширениях: если новые объекты добавляются в расширении конфигурации, напрямую изменить состав заимствованного критерия отбора нельзя. В этом случае создают собственный критерий отбора в расширении либо переопределяют логику сбора связей в общем модуле СтруктураПодчиненностиСлужебный.

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

← На главную