Как программно запустить команду печати из таблицы команд в 1С:Комплексная автоматизация 2.5?

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

При разработке собственных обработок или расширений (удобно через конструктор печатных форм без программирования) в конфигурациях на базе Библиотеки стандартных подсистем (БСП), таких как 1С:Комплексная автоматизация 2.5, часто возникает необходимость программно вызывать печатные формы. Особенно актуальна эта задача, когда у нас есть ссылка на объект (например, документ) и таблица доступных команд печати для этого объекта, а мы хотим запустить печать одной из этих команд. Мы подробно разберем, как это сделать, как для стандартных печатных форм, так и для внешних.

Получение таблицы команд печати

Прежде всего, давайте выясним, как получить ту самую таблицу команд, о которой идет речь. Если у вас есть ссылка на документ или другой объект, для которого нужно получить список печатных форм, вы можете использовать метод общего модуля УправлениеПечатью.


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

ИсточникКоманд = Объект.НайденнаяСсылка;
ТаблицаКоманд = УправлениеПечатью.КомандыПечатиОбъекта(ИсточникКоманд);

В результате выполнения этой строки кода мы получим ТаблицаКоманд – это таблица значений, содержащая информацию обо всех доступных печатных формах для данного объекта (поможет инструмент автоматического добавления факсимиле в 1С:КА 2.5). Эта таблица включает такие колонки, как Идентификатор, Представление, МенеджерПечати и другие, которые будут нам полезны для дальнейших действий.

Запуск стандартной команды печати

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

Давайте рассмотрим, какие параметры требуются для этой процедуры и как их использовать:

  1. ИмяМенеджераПечати: Это строковый идентификатор менеджера печати, который отвечает за формирование данной печатной формы. Мы получаем его из колонки МенеджерПечати нашей ТаблицыКоманд.
  2. ИменаМакетов: Идентификатор команды, который определяет, какой именно макет должен быть напечатан. Этот параметр берется из колонки Идентификатор нашей ТаблицыКоманд.
  3. МассивОбъектов: Массив ссылок на объекты, для которых нужно сформировать печатную форму. В нашем случае это будет массив, содержащий одну ссылку – нашу НайденнаяСсылка.
  4. ВладелецФормы: Ссылка на форму, из которой производится вызов печати. Это нужно для корректного отображения служебных окон (например, предварительного просмотра или выбора принтера). В контексте обработки это обычно ЭтаФорма.
  5. ПараметрыПечати: Необязательный параметр, представляющий собой структуру, которую можно использовать для передачи дополнительных данных в менеджер печати. Обычно используется для специфических настроек или условий печати.

Вот пример кода, который демонстрирует, как запустить печать первой команды из полученной ТаблицыКоманд:


// &НаКлиенте
Процедура ЗапуститьПечатьСтандартнойФормы(ТаблицаКоманд, СсылкаНаОбъектДляПечати)

    // Проверим, есть ли команды в таблице
    Если ТаблицаКоманд.Количество() = 0 Тогда
        Сообщить("Для выбранного объекта нет команд печати.", СтатусСообщения.Внимание);
        Возврат;
    КонецЕсли;

    // Возьмем, например, первую команду из таблицы
    СтрокаКоманды = ТаблицаКоманд[0];

    // Подготовим массив объектов для печати
    МассивДляПечати = Новый Массив;
    МассивДляПечати.Добавить(СсылкаНаОбъектДляПечати);

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

КонецПроцедуры

// Пример использования (вызов из обработчика кнопки на форме обработки)
// &НаКлиенте
Процедура КомандаЗапуститьПечать(Команда)

    Если Объект.НайденнаяСсылка = Неопределено Тогда
        Сообщить("Не выбрана ссылка на объект для печати.", СтатусСообщения.Внимание);
        Возврат;
    КонецЕсли;

    // Получаем таблицу команд для найденной ссылки
    ТаблицаКоманд = УправлениеПечатью.КомандыПечатиОбъекта(Объект.НайденнаяСсылка);

    // Запускаем печать (например, первой найденной команды)
    ЗапуститьПечатьСтандартнойФормы(ТаблицаКоманд, Объект.НайденнаяСсылка);

КонецПроцедуры

Этот подход отлично работает для большинства типовых печатных форм, которые являются частью самой конфигурации — их модификацию упрощает расширение для автоматической подстановки печатей и подписей.

Программный запуск внешних печатных форм (ВПФ)

Ситуация становится немного сложнее, когда мы имеем дело с внешними печатными формами (ВПФ) — для этой задачи есть готовое решение для программного запуска ВПФ. Как справедливо было отмечено в исходном обсуждении, прямой вызов УправлениеПечатьюКлиент.ВыполнитьКомандуПечати для ВПФ может не сработать или вызвать некорректное поведение. Это связано с тем, что ВПФ подключаются через подсистему "Дополнительные отчеты и обработки" и имеют свой специфический механизм инициализации и выполнения.

Для программного формирования ВПФ рекомендуется использовать специализированные функции общего модуля ДополнительныеОтчетыИОбработки. Процесс формирования ВПФ обычно состоит из двух шагов:

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

Давайте рассмотрим пример реализации:


// &НаКлиенте
Процедура ПечатьВыбраннойВПФ(СтрокаКоманды, СсылкаНаОбъектДляПечати)

    // СтрокаКоманды - это строка из ТаблицыКоманд, соответствующая ВПФ
    // Предполагаем, что в СтрокаКоманды.МенеджерПечати содержится ссылка на элемент справочника
    // "ДополнительныеОтчетыИОбработки", которая соответствует нашей ВПФ.
    // Если в таблице команд нет прямой ссылки, то нам потребуется дополнительная логика
    // для получения СсылкиНаВПФПоИдентификатору.
    // В большинстве случаев для ВПФ поле МенеджерПечати содержит ссылку на ДополнительныйОтчет.

    СсылкаНаВПФ = СтрокаКоманды.МенеджерПечати; // Это ссылка на элемент справочника ДополнительныеОтчетыИОбработки

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

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

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

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

КонецПроцедуры

// &НаСервереБезКонтекста
Функция СформироватьВнешнююФормуНаСервере(СсылкаНаДокумент, СсылкаНаВПФ, ИдентификаторКоманды) Экспорт

    МассивОбъектов = Новый Массив;
    МассивОбъектов.Добавить(СсылкаНаДокумент);

    ПараметрыПечати = Новый Структура;
    ПараметрыПечати.Вставить("ИдентификаторКоманды", ИдентификаторКоманды); // Передаем идентификатор команды, если нужно ВПФ

    // В БСП есть несколько методов для формирования ВПФ.
    // Один из наиболее универсальных - СформироватьПечатнуюФорму.
    // Он загружает внешнюю обработку и вызывает в ней функцию печати.
    ТабДок = ДополнительныеОтчетыИОбработки.СформироватьПечатнуюФорму(СсылкаНаВПФ, МассивОбъектов, ПараметрыПечати);

    Возврат ТабДок;

КонецФункции

// Пример вызова из обработчика кнопки на форме обработки (для ВПФ)
// &НаКлиенте
Процедура КомандаЗапуститьПечатьВПФ(Команда)

    Если Объект.НайденнаяСсылка = Неопределено Тогда
        Сообщить("Не выбрана ссылка на объект для печати.", СтатусСообщения.Внимание);
        Возврат;
    КонецЕсли;

    // Получаем таблицу команд для найденной ссылки
    ТаблицаКоманд = УправлениеПечатью.КомандыПечатиОбъекта(Объект.НайденнаяСсылка);

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

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

    // Запускаем печать ВПФ
    ПечатьВыбраннойВПФ(СтрокаВПФ, Объект.НайденнаяСсылка);

КонецПроцедуры

Обратите внимание, что в данном подходе мы вручную получаем табличный документ с сервера и затем отображаем его на клиенте. Это дает нам полный контроль над процессом формирования и вывода ВПФ.

Также для формирования ВПФ может использоваться метод ПечатьПоВнешнемуИсточнику() из общего модуля ДополнительныеОтчетыИОбработки, который также требует ссылки на внешний отчет/обработку и массив объектов. Выбор метода зависит от конкретной структуры ВПФ и требований к передаче параметров.

Реализация интерфейса с флажками

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

  1. Создание табличной части на форме: Добавьте на форму вашей обработки новый реквизит типа "ТаблицаЗначений".
  2. Заполнение табличной части: После получения ТаблицаКоманд методом УправлениеПечатью.КомандыПечатиОбъекта, мы переносим данные из нее в нашу табличную часть формы. При этом мы добавляем новую колонку булевого типа, например, Печатать, которая будет отображаться как флажок.
  3. Обработка выбора: По нажатию кнопки "Печать" на вашей форме, мы обходим строки созданной табличной части. Для каждой строки, где установлен флажок Печатать, мы вызываем соответствующую процедуру печати:
    • Если это стандартная печатная форма, используем УправлениеПечатьюКлиент.ВыполнитьКомандуПечати.
    • Если это внешняя печатная форма, используем описанный выше механизм с вызовом серверной функции СформироватьВнешнююФормуНаСервере и последующим отображением через УправлениеПечатьюКлиент.ПечатьДокументов.

Это позволит пользователю выбирать несколько печатных форм и запускать их комплектом — для этого подойдёт обработка печати с автоматическим факсимиле для 1С:КА 2.


// &НаКлиенте
// Предположим, что у нас есть реквизит формы ТабличнаяЧастьКомандПечати (тип ТаблицаЗначений)
// с колонками "Идентификатор", "Представление", "МенеджерПечати", "ЭтоВПФ", "Печатать"

Процедура ОбновитьКомандыПечатиНаФорме(СсылкаНаОбъектДляПечати)

    ТабличнаяЧастьКомандПечати.Очистить();

    Если СсылкаНаОбъектДляПечати = Неопределено Тогда
        Возврат;
    КонецЕсли;

    ТаблицаКоманд = УправлениеПечатью.КомандыПечатиОбъекта(СсылкаНаОбъектДляПечати);

    Для Каждого СтрокаКоманды Из ТаблицаКоманд Цикл
        НоваяСтрока = ТабличнаяЧастьКомандПечати.Добавить();
        НоваяСтрока.Идентификатор = СтрокаКоманды.Идентификатор;
        НоваяСтрока.Представление = СтрокаКоманды.Представление;
        НоваяСтрока.МенеджерПечати = СтрокаКоманды.МенеджерПечати;
        // Определяем, является ли команда внешней печатной формой
        // Это можно сделать по типу менеджера печати или по специальному флагу, если он есть
        НоваяСтрока.ЭтоВПФ = ТипЗнч(СтрокаКоманды.МенеджерПечати) = Тип("СправочникСсылка.ДополнительныеОтчетыИОбработки");
        НоваяСтрока.Печатать = Ложь; // По умолчанию флажок снят
    КонецЦикла;

КонецПроцедуры

// &НаКлиенте
Процедура НапечататьВыбранныеКоманды(Команда)

    Если Объект.НайденнаяСсылка = Неопределено Тогда
        Сообщить("Не выбрана ссылка на объект для печати.", СтатусСообщения.Внимание);
        Возврат;
    КонецЕсли;

    МассивОбъектовДляПечати = Новый Массив;
    МассивОбъектовДляПечати.Добавить(Объект.НайденнаяСсылка);

    КоллекцияПечатныхФорм = УправлениеПечатьюКлиент.НоваяКоллекцияПечатныхФорм("Выбранные формы");

    Для Каждого СтрокаТЧ Из ТабличнаяЧастьКомандПечати Цикл
        Если СтрокаТЧ.Печатать Тогда
            Если СтрокаТЧ.ЭтоВПФ Тогда
                // Обрабатываем внешнюю печатную форму
                ТабличныйДокументВПФ = СформироватьВнешнююФормуНаСервере(Объект.НайденнаяСсылка, СтрокаТЧ.МенеджерПечати, СтрокаТЧ.Идентификатор);
                Если ТабличныйДокументВПФ <> Неопределено Тогда
                    ПечатнаяФорма = КоллекцияПечатныхФорм.Добавить();
                    ПечатнаяФорма.ИмяМакета = СтрокаТЧ.Представление;
                    ПечатнаяФорма.ТабличныйДокумент = ТабличныйДокументВПФ;
                    // Для комплекта печати важно задать область печати документа
                    УправлениеПечатью.ЗадатьОбластьПечатиДокумента(ПечатнаяФорма.ТабличныйДокумент, МассивОбъектовДляПечати[0]);
                КонецЕсли;
            Иначе
                // Обрабатываем стандартную печатную форму
                // Для стандартных форм ВыполнитьКомандуПечати сразу выводит результат,
                // поэтому их нельзя просто добавить в КоллекциюПечатныхФорм
                // Придется вызывать их отдельно или перехватывать ТабличныйДокумент, если это возможно.
                // В данном примере, для простоты, мы будем вызывать их по одной.
                УправлениеПечатьюКлиент.ВыполнитьКомандуПечати(
                    СтрокаТЧ.МенеджерПечати,
                    СтрокаТЧ.Идентификатор,
                    МассивОбъектовДляПечати,
                    ЭтаФорма
                );
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;

    // Если есть сформированные ВПФ (или другие формы, которые были добавлены в коллекцию)
    Если КоллекцияПечатныхФорм.Количество() > 0 Тогда
        УправлениеПечатьюКлиент.ПечатьДокументов(КоллекцияПечатныхФорм, , ЭтаФорма);
    КонецЕсли;

КонецПроцедуры

Важный момент: если вы формируете комплект печати, то есть хотите объединить несколько форм в один вывод или отправить их на печать разом, будьте внимательны с обработкой стандартных и внешних форм. Метод УправлениеПечатьюКлиент.ВыполнитьКомандуПечати обычно сразу выводит форму на экран или отправляет на принтер. Если вы хотите объединить стандартные формы с ВПФ в один "Комплект печати", вам может потребоваться получить табличный документ и для стандартных форм, а затем добавить его в коллекцию. Это более сложная задача, требующая, возможно, рефлексивного вызова методов менеджеров печати.

Проблемы с ВПФ в комплектах печати и их решения

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

  1. Обновите конфигурацию: В актуальных релизах БСП (начиная, например, с ERP 2.5.22.80) многие из этих проблем были исправлены. Всегда рекомендуется использовать последние версии платформы и конфигурации.
  2. Используйте УправлениеПечатью.ЗадатьОбластьПечатиДокумента: При формировании комплекта печати критически важно правильно разметить каждый табличный документ, чтобы система понимала, к какому объекту он относится. Это делается с помощью метода УправлениеПечатью.ЗадатьОбластьПечатиДокумента(ТабличныйДокумент, СсылкаНаОбъект). Если этого не сделать, система может выдать ошибку или неверно сгруппировать формы.

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

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

← На главную