В разработке на платформе 1С:Предприятие 8.3 часто возникает задача программного вызова печати документов. Когда в конфигурации используется Библиотека стандартных подсистем (БСП), ручной вызов процедур печати напрямую из модулей менеджеров объектов нередко приводит к трудночитаемым ошибкам. В этой статье мы подробно разберем, почему возникают такие проблемы, проанализируем внутреннее устройство подсистемы печати БСП и рассмотрим несколько готовых сценариев для правильного вывода документов на печать как на клиенте, так и на сервере.
Типичная ошибка начинающих разработчиков — попытка собрать коллекцию печатных форм «кустарным» способом, вручную создавая таблицу значений и добавляя в нее произвольные колонки. Рассмотрим исходный некорректный пример кода:
КоллекцияПечатныхФорм = Новый ТаблицаЗначений;
КоллекцияПечатныхФорм.Колонки.Добавить("ИмяВРЕГ");
КоллекцияПечатныхФорм.Колонки.Добавить("ИмяМакета");
Строка = КоллекцияПечатныхФорм.Добавить();
Строка.ИмяВРЕГ = "РАСХОДНАЯНАКЛАДНАЯ";
Строка.ИмяМакета = "РасходнаяНакладная";
При передаче такой таблицы в процедуру Печать() модуля менеджера система выдает ошибку, сообщающую об отсутствии поля ТабличныйДокумент. Дело в том, что подсистема печати БСП ожидает строго определенную структуру таблицы КоллекцияПечатныхФорм. В ней обязательно должны присутствовать следующие колонки:
Чтобы не создавать все эти колонки вручную и гарантировать совместимость с будущими обновлениями БСП, мы должны использовать специальный программный интерфейс БСП для инициализации структуры.
---
Если перед нами стоит задача отправить документ на печать мгновенно, минуя окно предварительного просмотра, мы должны использовать клиентский метод УправлениеПечатьюКлиент.ВыполнитьКомандуПечатиНаПринтер(). Этот подход отлично подходит для автоматизированных рабочих мест (АРМ) кассиров или кладовщиков, где важна скорость работы.
Реализуем этот сценарий правильно, разделив логику на клиентскую и серверную части.
На клиенте мы вызываем команду БСП, передавая ей имя команды, идентификатор макета и массив объектов:
&НаКлиенте
Процедура РаспечататьНаПринтерКоманда()
// Получаем массив ссылок на объекты для печати с сервера
МассивОбъектов = ПолучитьСсылкиНаДокументыНаСервере();
Если МассивОбъектов.Количество() = 0 Тогда
ПоказатьПредупреждение(, "Документы для печати не найдены!");
Возврат;
КонецЕсли;
// Параметры для команды печати
ПараметрыПечати = Новый Структура("Тип", "РасходнаяНакладная");
// Отправляем документы напрямую на принтер по умолчанию
УправлениеПечатьюКлиент.ВыполнитьКомандуПечатиНаПринтер(
"Документ.РеализацияТоваровУслуг",
"РасходнаяНакладная",
МассивОбъектов,
ПараметрыПечати
);
КонецПроцедуры
На сервере мы выполняем выборку нужных документов. Например, найдем документ по его номеру и дате:
&НаСервере
Функция ПолучитьСсылкиНаДокументыНаСервере()
МассивОбъектов = Новый Массив;
СсылкаНаДокумент = Документы.РеализацияТоваровУслуг.НайтиПоНомеру("0000-000033", ТекущаяДата());
Если Не СсылкаНаДокумент.Пустая() Тогда
МассивОбъектов.Добавить(СсылкаНаДокумент);
КонецЕсли;
Возврат МассивОбъектов;
КонецФункции
---
На практике пользователям гораздо чаще требуется сначала увидеть документ на экране, отредактировать его при необходимости, выбрать принтер, указать количество копий или сохранить документ в PDF/Excel. Для этих целей в БСП предусмотрено общее интерактивное окно.
Для открытия формы просмотра мы используем метод УправлениеПечатьюКлиент.ВыполнитьКомандуПечати(). Проанализируем пример кода:
&НаКлиенте
Процедура ВывестиНаЭкранКоманда()
МассивОбъектов = ПолучитьСсылкиНаДокументыНаСервере();
Если МассивОбъектов.Количество() = 0 Тогда
Возврат;
КонецЕсли;
// Открываем стандартную форму просмотра печатных форм БСП
УправлениеПечатьюКлиент.ВыполнитьКомандуПечати(
"Документ.РеализацияТоваровУслуг", // Источник печати
"РасходнаяНакладная", // Идентификатор команды печати
МассивОбъектов, // Ссылка или массив ссылок
ЭтаФорма // Форма-владелец
);
КонецПроцедуры
Этот метод самостоятельно инициализирует фоновое задание формирования печатных форм, выведет прогресс-бар и откроет готовое к работе окно печати со всеми стандартными сервисными функциями.
---
Иногда интерактивный вывод на экран не требуется вовсе — например, если нам нужно автоматически сформировать печатную форму в регламентном задании, сохранить ее в формате PDF во временную папку и отправить клиенту по электронной почте. В этом случае обращаться к клиентскому модулю УправлениеПечатьюКлиент нельзя.
Разберем, как правильно получить готовый ТабличныйДокумент на сервере через программный интерфейс модуля УправлениеПечатью:
&НаСервере
Процедура СформироватьИСохранитьПечатнуюФормуНаСервере(СсылкаНаДокумент, ПутьДляСохранения)
// 1. Подготавливаем массив объектов
МассивОбъектов = Новый Массив;
МассивОбъектов.Добавить(СсылкаНаДокумент);
// 2. Используем правильный метод БСП для инициализации коллекции
КоллекцияПечатныхФорм = УправлениеПечатью.ПодготовитьКоллекциюПечатныхФорм("РасходнаяНакладная");
// 3. Подготавливаем дополнительные параметры вывода и объекты печати
ПараметрыВывода = УправлениеПечатью.ПодготовитьСтруктуруПараметровВывода();
ОбъектыПечати = Новый СписокЗначений;
// 4. Вызываем процедуру Печать из модуля менеджера документа
Документы.РеализацияТоваровУслуг.Печать(
МассивОбъектов,
ДопустимыеТипыСравнения.Равно, // Параметр быстрого отбора (обычно пустой или Ложь)
КоллекцияПечатныхФорм,
ОбъектыПечати,
ПараметрыВывода
);
// 5. Извлекаем сформированный ТабличныйДокумент из заполненной коллекции
СтрокаКоллекции = КоллекцияПечатныхФорм.Найти("РАСХОДНАЯНАКЛАДНАЯ", "ИмяВРЕГ");
Если СтрокаКоллекции <> Неопределено Тогда
ТабДок = СтрокаКоллекции.ТабличныйДокумент;
// Теперь мы можем делать с документом все что угодно, например, сохранить как PDF
ТабДок.Записать(ПутьДляСохранения, ТипФайлаТабличногоДокумента.PDF);
Иначе
ВызватьИсключение "Не удалось сформировать печатную форму для макета РасходнаяНакладная!";
КонецЕсли;
КонецПроцедуры
---
Рассмотрим еще одну частую бизнес-ситуацию. Вы сформировали табличный документ полностью вручную (или заполнили собственный макет) на сервере и хотите показать его пользователю в красивом и привычном интерфейсе БСП. Мы можем сделать это без привязки к стандартным менеджерам печати документов.
Посмотрим на реализацию этого алгоритма:
&НаКлиенте
Процедура ПоказатьСобственныйТабличныйДокумент()
// Получаем вручную заполненный документ с сервера
СформированныйТабДок = ПолучитьСобственныйТабДокНаСервере();
// Создаем пустую коллекцию средствами клиентского модуля БСП
КоллекцияПечатныхФорм = УправлениеПечатьюКлиент.НоваяКоллекцияПечатныхФорм("ПроизвольныйМакет");
// Заполняем обязательные свойства для корректного отображения
СтрокаПечати = КоллекцияПечатныхФорм[0];
СтрокаПечати.ТабличныйДокумент = СформированныйТабДок;
СтрокаПечати.СинонимМакета = "Мой произвольный отчет/документ";
// Открываем стандартное окно просмотра
УправлениеПечатьюКлиент.ПечатьДокументов(КоллекцияПечатныхФорм, , ЭтаФорма);
КонецПроцедуры
&НаСервере
Функция ПолучитьСобственныйТабДокНаСервере()
ТабДок = Новый ТабличныйДокумент;
// Минимальное заполнение для демонстрации
Область = ТабДок.ПолучитьОбласть("R1C1:R3C3");
Область.Текст = "Произвольный текст в ячейке";
ТабДок.Вывести(Область);
Возврат ТабДок;
КонецФункции
Этот простой прием позволяет легко интегрировать любые самописные печатные формы и отчеты в общую эргономику вашей конфигурации 1С.
---
Для успешной интеграции с подсистемой печати БСП достаточно соблюдать ключевые правила:
КоллекцияПечатныхФорм вручную через конструктор Новый ТаблицаЗначений. Всегда используйте методы инициализации структуры — УправлениеПечатью.ПодготовитьКоллекциюПечатныхФорм() на сервере или УправлениеПечатьюКлиент.НоваяКоллекцияПечатныхФорм() на клиенте.УправлениеПечатьюКлиент и его методам ВыполнитьКомандуПечати() или ВыполнитьКомандуПечатиНаПринтер().Печать() модуля менеджера объекта, предварительно инициализировав коллекцию на сервере.Использование штатных механизмов БСП защитит ваш код от поломок при обновлениях конфигурации и обеспечит пользователям стабильный, привычный и удобный интерфейс работы с документами.