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