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