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

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

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

Способ 1. Вызов штатной команды печати БСП (на клиенте)

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

Разберем пример кода на клиенте:


МассивОбъектов = Новый Массив;
// В массив необходимо добавить ССЫЛКУ на тот документ, который мы печатаем!
МассивОбъектов.Добавить(СсылкаНаЦелевойДокумент); 

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

Важнейший нюанс и частая ошибка:

Разберем причину ошибки Значение не является значением объектного типа (Выбрать) в строке ВыборкаСтрокЗапасы = Шапка.Запасы.Выбрать;. Эта ошибка происходит в том случае, когда в МассивОбъектов передают ссылку на исходный документ вместо целевого. В модуле менеджера целевого документа выполняется запрос к базе данных с условием по ссылке. Если передать ссылку не того типа или незаписанный документ, запрос вернет пустой результат, и попытка обратиться к несуществующей выборке вызовет сбой.

Ключевые правила:

  1. В массиве объектов передается ссылка именно на тот документ, печатная форма которого формируется.
  2. Целевой документ обязательно должен быть записан в базу данных (передача пустой ссылки или объекта из оперативной памяти приведет к ошибке выполнения запроса).

Способ 2. Ручное формирование табличного документа на сервере

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

Проанализируем пример получения макета чужого документа:


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

Обратите внимание: Метод ПолучитьМакет() следует вызывать на сервере через менеджер документа (Документы[ИмяДокумента].ПолучитьМакет()). Вызов устаревшей конструкции Ссылка.ПолучитьОбъект().ПолучитьМакет() не рекомендуется, так как передача объекта с сервера на клиент не поддерживается на тонком клиенте и приводит к лишней нагрузке на систему.

Способ 3. Вынос макета в Общие макеты

Если один и тот же макет и алгоритм его заполнения регулярно используются в разных документах системах (например, универсальная печатная форма или спецификация), наилучшим решением будет:

  1. Вынести макет в ветку метаданных Общие макеты.
  2. Логику формирования табличного документа вынести в отдельную функцию серверного общего модуля.

Посмотрим, как вызывать общий макет из кода:

Макет = ПолучитьОбщийМакет("ОбщийМакетНакладной");

Такой подход избавляет конфигурацию от жесткой связи между модулями менеджеров разных документов и упрощает поддержку кода.

← На главную