Как вызвать процедуру печати документа из формы обработки в 1С 8.3

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

Разработка печатных форм — одна из самых частых задач для начинающего программиста 1С. Часто возникает ситуация, когда логика печати уже реализована в модуле менеджера документа, и нам нужно вызвать её из внешней обработки. Однако при первых попытках новички часто сталкиваются с тем, что «ничего не происходит». Рассмотрим подробнее, почему так бывает, и разберем по шагам, как правильно организовать вызов печати.

Анализ типичных ошибок

Проанализируем ситуацию, описанную в исходном сообщении. Автор пытается вызвать процедуру на сервере, заполнить табличный документ и... на этом всё заканчивается. Разберем основные «подводные камни», которые мешают коду работать:

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

Выясним причину, по которой код автора не выдавал ошибок, но и не работал: формально синтаксис верен, но логическая цепочка обрывалась на сервере.

Шаг 1. Подготовка формы обработки

Для начала нам нужно, чтобы пользователь мог выбрать конкретный документ, который он хочет распечатать. Для этого в обработке создадим реквизит ДокументДляПечати с типом ДокументСсылка.ПоступлениеТоваров и вынесем его на форму.

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


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

&НаСервере
Функция СформироватьПечатнуюФормуНаСервере()
    
    // 1. Создаем именно ТабличныйДокумент, а не Макет
    ТабДок = Новый ТабличныйДокумент;
    
    // 2. Проверяем, выбрал ли пользователь документ
    Если Объект.ДокументДляПечати.Пустая() Тогда
        Сообщить("Не выбран документ для печати!");
        Возврат Неопределено;
    КонецЕсли;
    
    // 3. Подготавливаем массив ссылок (процедура печати обычно ждет массив)
    МассивСсылок = Новый Массив;
    МассивСсылок.Добавить(Объект.ДокументДляПечати);
    
    // 4. Вызываем процедуру из модуля менеджера документа
    // Важно: процедура в модуле менеджера должна иметь признак Экспорт
    Документы.ПоступлениеТоваров.Печать(ТабДок, МассивСсылок);
    
    // Дополнительные настройки для удобства пользователя
    ТабДок.ТолькоПросмотр = Истина;
    ТабДок.АвтоМасштаб    = Истина;
    
    Возврат ТабДок;
    
КонецФункции

Шаг 2. Особенности кода в модуле менеджера

Посмотрим на пример кода в модуле менеджера. Чтобы внешняя обработка могла обратиться к этой процедуре, она обязательно должна быть объявлена как Экспорт. Рассмотрим ключевые моменты внутри этой процедуры:


Процедура Печать(ТабДок, МассивСсылок) Экспорт
    
    Макет = Документы.ПоступлениеТоваров.ПолучитьМакет("Печать");
    
    // Очищаем ТабДок перед заполнением, чтобы не дублировать данные 
    // при повторных вызовах
    ТабДок.Очистить();
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
    "ВЫБРАТЬ
    |	ПоступлениеТоваров.Ссылка КАК Ссылка,
    |	ПоступлениеТоваров.Номер КАК Номер,
    |	ПоступлениеТоваров.Дата КАК Дата,
    |	ПоступлениеТоваров.Поставщик КАК Поставщик
    |ИЗ
    |	Документ.ПоступлениеТоваров КАК ПоступлениеТоваров
    |ГДЕ
    |	ПоступлениеТоваров.Ссылка В(&МассивСсылок)";
    
    Запрос.УстановитьПараметр("МассивСсылок", МассивСсылок);
    
    РезультатЗапроса = Запрос.Выполнить();
    Выборка = РезультатЗапроса.Выбрать();
    
    ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
    
    Пока Выборка.Следующий() Цикл
        ОбластьШапка.Параметры.Заполнить(Выборка);
        ТабДок.Вывести(ОбластьШапка);
        // Здесь продолжается вывод остальных секций (Товары, Подвал)
    КонецЦикла;
    
КонецПроцедуры

Разберем важные детали реализации

Передача параметров в запрос: Всегда используйте В(&МассивСсылок), даже если печатаете один документ. Это делает ваш код универсальным. Если завтра потребуется напечатать 10 документов сразу из списка, вам не придется переписывать логику модуля менеджера.

Метод Показать(): Обратите внимание, что метод Показать() вызывается на клиенте. Табличный документ — это один из немногих объектов 1С, который может «мигрировать» с сервера на клиент, сохраняя свое содержимое. Мы создали его на сервере, наполнили данными из базы, вернули на клиент и только там отрисовали в окне.

Оформление результата: Профессиональный подход подразумевает установку свойств ТолькоПросмотр и АвтоМасштаб. Свойство ТолькоПросмотр предотвращает случайное редактирование данных пользователем в сформированной форме, а АвтоМасштаб гарантирует, что документ впишется в ширину листа при печати на принтере.

Использование Библиотеки Стандартных Подсистем (БСП)

Если вы работаете в современной типовой конфигурации (например, Управление торговлей 11 или Бухгалтерия предприятия 3.0), ручной вызов процедуры модуля менеджера считается «устаревшим» стилем. В таких системах используется подсистема Печать.

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


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

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

Заключение

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

← На главную