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