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