Как получить макет документа из модуля формы списка в 1С

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

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

Причины ошибки: почему в форме списка нельзя получить макет напрямую

Для понимания архитектуры платформы 1С:Предприятие 8 выделим два ключевых момента:

  1. Форма списка не содержит макетов в метаданных. Макеты подчинены непосредственно объектам конфигурации (документам, справочникам, обработкам) или находятся в ветке общих макетов конфигурации. В самой форме макет храниться не может.
  2. Специфика динамического списка. Функция РеквизитФормыВЗначение преобразует данные формы в прикладной объект базы данных (например, ДокументОбъект). Основной реквизит формы списка имеет тип ДинамическийСписок, который нельзя преобразовать в объект документа, поскольку он предназначен лишь для отображения выборки строк из базы данных.

Способ 1. Получение макета через менеджер документа на сервере

Самый быстрый и ресурсоемкий способ получить макет документа в контексте формы списка — обратиться к менеджеру соответствующего объекта метаданных. Метод ПолучитьМакет у менеджера объекта доступен только на сервере и не требует создания тяжелого экземпляра объекта в оперативной памяти.

Рассмотрим пример серверной функции, получающей макет через менеджер:


&НаСервереБезКонтекста
Функция ПолучитьМакетНакладнойНаСервере()
    // Получаем макет напрямую из менеджера документа
    Макет = Документы.РеализацияТоваровУслуг.ПолучитьМакет("ПФ_MXL_Накладная");
    Возврат Макет;
КонецФункции

Если имя документа определяется динамически, можно использовать обращение через коллекцию Документы:


&НаСервереБезКонтекста
Функция ПолучитьМакетПоИмени(ИмяДокумента, ИмяМакета)
    Возврат Документы[ИмяДокумента].ПолучитьМакет(ИмяМакета);
КонецФункции

Способ 2. Получение макета через ссылку на текущую строку списка

Если требуется сформировать печатную форму для конкретного документа, выделенного пользователем в форме списка, сначала получаем ссылку на клиенте, а затем обрабатываем ее на сервере.

Разберем по шагам реализацию команды печати:

  1. На клиенте определяем ссылку на выделенный документ через Элементы.Список.ТекущиеДанные.Ссылка или свойство Элементы.Список.ТекущаяСтрока. Для множественного выбора используем массив Элементы.Список.ВыделенныеСтроки.
  2. Передаем полученную ссылку в серверную процедуру.
  3. На сервере получаем макет через менеджер или через объект ссылки (метод Ссылка.ПолучитьОбъект().ПолучитьМакет(), хотя обращение через менеджер предпочтительнее).

Посмотрим на пример кода клиентской и серверной части:


&НаКлиенте
Процедура Печать(Команда)
    ТекущиеДанные = Элементы.Список.ТекущиеДанные;
    Если ТекущиеДанные = Неопределено Тогда
        ПоказатьПредупреждение(, "Выберите строку для печати.");
        Возврат;
    КонецЕсли;
    
    ТабДокумент = СформироватьПечатнуюФормуНаСервере(ТекущиеДанные.Ссылка);
    ТабДокумент.Показать("Печать документа");
КонецПроцедуры

&НаСервереБезКонтекста
Функция СформироватьПечатнуюФормуНаСервере(СсылкаНаДокумент)
    ТабличныйДокумент = Новый ТабличныйДокумент;
    
    // Получаем макет через менеджер документа
    Макет = СсылкаНаДокумент.Метаданные().Имя;
    МакетОбъекта = Документы[Макет].ПолучитьМакет("Печать");
    
    // Заполнение областей макета данными документа
    ОбластьШапка = МакетОбъекта.ПолучитьОбласть("Шапка");
    ОбластьШапка.Параметры.Номер = СсылкаНаДокумент.Номер;
    ОбластьШапка.Параметры.Дата = СсылкаНаДокумент.Дата;
    ТабличныйДокумент.Вывести(ОбластьШапка);
    
    Возврат ТабличныйДокумент;
КонецФункции

Способ 3. Использование подсистемы печати БСП

В типовых конфигурациях, построенных на «Библиотеке стандартных подсистем» (БСП), логику формирования печатных форм не принято размещать в модулях форм. Она выносится в экспортную процедуру Печать модуля менеджера объекта.

Для работы с макетами в типовых решениях используется функция УправлениеПечатью.МакетПечатнойФормы(). Она позволяет автоматически учитывать пользовательские макеты, отредактированные в режиме предприятия без изменения конфигурации:


// В модуле менеджера документа
Процедура Печать(МассивОбъектов, ПараметрыПечати, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
    
    Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "Накладная") Тогда
        Макет = УправлениеПечатью.МакетПечатнойФормы("Документ.РеализацияТоваровУслуг.ПФ_MXL_Накладная");
        // Алгоритм заполнения табличного документа
    КонецЕсли;
    
КонецПроцедуры

Важные особенности клиент-серверного взаимодействия

При реализации печати из формы списка важно помнить следующие правила платформы 1С:

  1. Контекст вызова: методы ПолучитьМакет и ПолучитьОбщийМакет недоступны на тонком и веб-клиенте. Все операции с получением макетов и формированием табличных документов должны выполняться с директивами &НаСервере или &НаСервереБезКонтекста.
  2. Общие макеты: если печатная форма является универсальной для нескольких видов документов, макет создается в ветке ОбщиеМакеты и получается на сервере методом ПолучитьОбщийМакет("ИмяОбщегоМакета").
  3. Передача результата: готовый ТабличныйДокумент возвращается с сервера на клиент, где вызывается метод Показать(), либо открывается типовая форма предварительного просмотра печатных форм.
← На главную