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