При разработке внешних печатных форм в среде 1С:Предприятие 8.3 (особенно в конфигурациях на базе БСП, таких как УНФ, УТ 11, ERP или КА), начинающие разработчики часто сталкиваются с вопросом: как «дотянуться» до данных конкретного документа, из которого запущена печать? В этой статье мы подробно разберем механизм передачи ссылки на документ в функции обработки, проанализируем структуру стандартных процедур печати и научимся эффективно извлекать данные, включая дополнительные реквизиты.
Для начала проанализируем, как платформа 1С и Библиотека стандартных подсистем (БСП) взаимодействуют с нашей внешней обработкой. Когда пользователь нажимает кнопку «Печать», система обращается к экспортной процедуре Печать, которая находится в модуле объекта внешней обработки. Именно здесь начинается «жизнь» нашей печатной формы, и именно здесь мы получаем доступ к документам.
Рассмотрим стандартное объявление этой процедуры:
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
// Здесь МассивОбъектов содержит ссылки на выбранные пользователем документы
КонецПроцедуры
МассивОбъектов — это ключевой параметр. Он содержит массив ссылок на документы (например, ДокументСсылка.ЗаказПокупателя). Даже если пользователь печатает один документ, система все равно передает массив из одного элемента. Это сделано для реализации групповой печати.
Допустим, у нас есть функция ПолучитьУсловияОплаты(Заказ), которая должна вытащить данные из дополнительных реквизитов документа. Чтобы она заработала, мы должны передать в неё элемент из МассивОбъектов. Разберем ситуацию на примере кода, предоставленного в теме.
Проанализируем процедуру печати и функцию формирования табличного документа. Вместо того чтобы обращаться к МассивОбъектов[0], что ограничивает нас только одним документом, мы пройдемся по массиву циклом:
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
// Определяем имя нашей печатной формы (из сведений о внешней обработке)
ИмяМакета = "ЗаказПокупателя";
// Получаем структуру для формирования формы
ПечатнаяФорма = УправлениеПечатью.СведенияОПечатнойФорме(КоллекцияПечатныхФорм, ИмяМакета);
Если ПечатнаяФорма <> Неопределено Тогда
// Передаем весь массив объектов в функцию формирования
ПечатнаяФорма.ТабличныйДокумент = СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати);
КонецЕсли;
КонецПроцедуры
Теперь перейдем к функции СформироватьПечатнуюФорму. Здесь нам нужно извлечь конкретную ссылку и передать её дальше. Рассмотрим, как это сделать правильно, чтобы заполнить параметры макета данными из дополнительных реквизитов.
Функция СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати)
ТабличныйДокумент = Новый ТабличныйДокумент;
МакетОбработки = ПолучитьМакет("Макет");
// Перебираем все документы, отправленные на печать
Для Каждого СсылкаНаДокумент Из МассивОбъектов Цикл
// Выводим разделитель страниц, если документов несколько
Если ТабличныйДокумент.ВысотаТаблицы > 0 Тогда
ТабличныйДокумент.ВывестиГоризонтальныйРазделительСтраниц();
КонецЕсли;
ОбластьШапка = МакетОбработки.ПолучитьОбласть("Шапка");
// Заполняем основные параметры напрямую из ссылки
ОбластьШапка.Параметры.НомЗаказ = СсылкаНаДокумент.Номер;
ОбластьШапка.Параметры.ДатаДок = СсылкаНаДокумент.Дата;
ТабличныйДокумент.Вывести(ОбластьШапка);
// Работаем с табличной частью
Для каждого Стр из СсылкаНаДокумент.Запасы Цикл
ОбластьСтр = МакетОбработки.ПолучитьОбласть("Строка");
ЗаполнитьЗначенияСвойств(ОбластьСтр.Параметры, Стр);
ТабличныйДокумент.Вывести(ОбластьСтр);
КонецЦикла;
ОбластьПодвал = МакетОбработки.ПолучитьОбласть("Подвал");
// ВОТ ЗДЕСЬ мы передаем нашу СсылкуНаДокумент в дополнительные функции
ОбластьПодвал.Параметры.УсловияОплаты = ПолучитьУсловияОплаты(СсылкаНаДокумент);
ОбластьПодвал.Параметры.УсловияОтгрузки = ПолучитьУсловияОтгрузки(СсылкаНаДокумент);
ТабличныйДокумент.Вывести(ОбластьПодвал);
// Указываем системе, к какому объекту относится эта область (для отладки и расшифровки)
УправлениеПечатью.ЗадатьОбластьПечатиОбъекта(ТабличныйДокумент, 1, ОбъектыПечати, СсылкаНаДокумент);
КонецЦикла;
Возврат ТабличныйДокумент;
КонецФункции
Выясним причину, по которой у автора возникли сложности с функцией ПолучитьУсловияОплаты. В коде автора используется перебор коллекции ДополнительныеРеквизиты. Это рабочий, но требующий аккуратности способ. Посмотрим на реализацию функции, в которую мы передали параметр Заказ (который по сути является нашей ссылкой СсылкаНаДокумент):
Функция ПолучитьУсловияОплаты(Заказ)
Результат = "";
// Заказ — это ссылка, которую мы передали из СформироватьПечатнуюФорму
Для каждого СтрДР из Заказ.ДополнительныеРеквизиты Цикл
// Сравниваем имя свойства. Внимание: Имя должно совпадать с внутренним именем в метаданных
Если СтрДР.Свойство.Имя = "УсловияОплаты_5c34859355a04de38ae807db93964400" Тогда
Результат = СтрДР.Значение;
Прервать; // Нашли — выходим из цикла
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
Важный совет: Обращение «через точку» (Заказ.ДополнительныеРеквизиты) в цикле внутри печатной формы может замедлять работу, если документов много. В профессиональной разработке рекомендуется получать все данные одним запросом. Однако для простой внешней формы способ с передачей ссылки является наиболее понятным и быстрым в реализации.
Проанализируем ситуацию: если мы работаем в типовой конфигурации, у нас уже есть мощные инструменты для работы со свойствами. Вместо того чтобы писать свой цикл перебора реквизитов, мы можем воспользоваться функциями БСП. Это сделает код более надежным.
Например, можно использовать функцию УправлениеСвойствами.ЗначенияСвойствОбъекта(). Она вернет структуру всех дополнительных реквизитов объекта, и нам останется только обратиться к нужной колонке. Это избавляет от необходимости вручную обходить табличную часть дополнительных реквизитов в поисках нужного GUID.
Печать найдите, где вызывается ваша основная функция формирования документа.МассивОбъектов. Если вы печатаете по одному, это будет МассивОбъектов[0], но лучше использовать цикл Для каждого.Используя этот подход, мы обеспечиваем корректную работу внешней печатной формы и получаем возможность гибко настраивать вывод данных из любых реквизитов Заказа покупателя.