В практике разработки на платформе 1С часто возникает задача, когда перед выводом печатной формы на экран пользователю необходимо задать дополнительные параметры. Например, в конфигурации 1С:Управление нашей фирмой (УНФ) при печати валютной ТОРГ-12 может потребоваться вручную указать курс валюты, отличный от установленного в справочнике, чтобы пересчитать итоги документа «на лету» прямо в печатной форме. Рассмотрим подробнее, как реализовать этот функционал архитектурно правильно, используя механизмы расширений и Библиотеки стандартных подсистем (БСП).
Прежде чем приступать к коду, разберем, как работает подсистема печати. Когда пользователь нажимает кнопку в подменю «Печать», система обращается к процедуре ДобавитьКомандыПечати в модуле менеджера объекта. Здесь формируется таблица команд. Главный секрет управления процессом до момента формирования табличного документа заключается в использовании колонки Обработчик в этой таблице. Если мы укажем там имя экспортной процедуры из клиентского общего модуля, управление сначала попадет туда, что позволит нам открыть свою форму, собрать данные и только потом запустить стандартный процесс печати. Для быстрого поиска и изучения процедур подсистемы можно использовать справочник по методам БСП с примерами использования.
Создадим расширение и добавим в него модуль менеджера документа РасходнаяНакладная. Нам нужно переопределить процедуру добавления команд. Используем директиву &После для встраивания в стандартный алгоритм.
&После("ДобавитьКомандыПечати")
Процедура Расш1_ДобавитьКомандыПечати(КомандыПечати)
// Добавляем новую команду для нашей валютной ТОРГ-12
КомандаПечати = КомандыПечати.Добавить();
КомандаПечати.Идентификатор = "ТОРГ12Валютный_С_Курсом";
КомандаПечати.Представление = "ТОРГ-12 (в валюте по курсу)";
КомандаПечати.ПроверкаПроведенияПередПечатью = Истина;
// Указываем обработчик в общем модуле.
// Это должна быть КЛИЕНТСКАЯ процедура.
КомандаПечати.Обработчик = "Расш1_УправлениеПечатьюКлиент.ВыполнитьПечатьТОРГ12Валютный";
КомандаПечати.Порядок = 50;
КонецПроцедуры
Обратите внимание на свойство Обработчик. Мы создадим в расширении новый общий модуль Расш1_УправлениеПечатьюКлиент с установленными флажками Клиент (управляемое приложение) и Внешнее соединение.
Теперь проанализируем ситуацию с открытием формы. Так как современные конфигурации работают в режиме «без модальности», мы не можем просто остановить выполнение кода и ждать ответа от пользователя. Нам нужно использовать механизм ОписаниеОповещения. В процедуре-обработчике мы подготовим данные и откроем нашу вспомогательную форму.
// В общем модуле Расш1_УправлениеПечатьюКлиент
Процедура ВыполнитьПечатьТОРГ12Валютный(ПараметрыКоманды, ЭтотОбъект) Экспорт
// ПараметрыКоманды содержит Массив объектов (документов), которые печатаем
ПараметрыОткрытия = Новый Структура;
ПараметрыОткрытия.Вставить("СписокДокументов", ПараметрыКоманды.ОбъектыПечати);
ОповещениеОЗакрытии = Новый ОписаниеОповещения("ПослеВыбораКурса", ЭтотОбъект, ПараметрыКоманды);
// Открываем форму, созданную в расширении
ОткрытьФорму("ОбщаяФорма.Расш1_ФормаВыбораКурса", ПараметрыОткрытия, , , , , ОповещениеОЗакрытии);
КонецПроцедуры
Создадим в расширении общую форму Расш1_ФормаВыбораКурса. Добавим на нее реквизиты Валюта (тип СправочникСсылка.Валюты) и Курс (тип Число). В форме должна быть кнопка «ОК», которая закрывает форму и возвращает структуру данных.
&НаКлиенте
Процедура КомандаОК(Команда)
РезультатВыбора = Новый Структура;
РезультатВыбора.Вставить("Валюта", Объект.Валюта);
РезультатВыбора.Вставить("Курс", Объект.Курс);
Закрыть(РезультатВыбора);
КонецПроцедуры
Возвращаемся в наш клиентский общий модуль. После того как пользователь нажал «ОК», срабатывает процедура оповещения. Здесь мы вызываем стандартный метод УправлениеПечатьюКлиент.ВыполнитьКомандуПечати, но передаем в него заполненные ПараметрыПечати.
Процедура ПослеВыбораКурса(Результат, ДополнительныеПараметры) Экспорт
Если Результат = Неопределено Тогда
Возврат; // Пользователь закрыл форму без подтверждения
КонецЕсли;
// Добавляем наши параметры в структуру параметров печати
ДополнительныеПараметры.Вставить("ДополнительныеПараметры", Результат);
// Вызываем стандартную процедуру формирования печатных форм
УправлениеПечатьюКлиент.ВыполнитьПодключаемуюКомандуПечати(
ДополнительныеПараметры.Команда,
ДополнительныеПараметры.Форма,
ДополнительныеПараметры.ОбъектыПечати,
ДополнительныеПараметры
);
КонецПроцедуры
Теперь выясним, как получить эти данные в серверной части, где формируется табличный документ. В модуле менеджера документа РасходнаяНакладная найдем или переопределим процедуру Печать. Вторым параметром в нее всегда передается структура ПараметрыПечати.
&После("Печать")
Процедура Расш1_Печать(МассивОбъектов, ПараметрыПечати, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода)
// Проверяем, есть ли в параметрах наши данные
КурсДляПересчета = 1;
ВалютаПечати = Справочники.Валюты.ПустаяСсылка();
Если ПараметрыПечати.Свойство("ДополнительныеПараметры") Тогда
КурсДляПересчета = ПараметрыПечати.ДополнительныеПараметры.Курс;
ВалютаПечати = ПараметрыПечати.ДополнительныеПараметры.Валюта;
КонецЕсли;
// Далее используем эти переменные при формировании макета
// Например, передаем их в процедуру СформироватьПечатнуюФормуТОРГ12
КонецПроцедуры
При использовании расширений часто возникает ситуация, когда новая команда печати не отображается в интерфейсе. Выясним основные причины:
ДобавитьКомандыПечати. БСП автоматически тиражирует команды на связанные списки, если идентификатор команды зарегистрирован корректно.Использование свойства Обработчик в командах печати — это наиболее гибкий и «чистый» способ вмешательства в процесс печати. Он позволяет избежать перехвата системных процедур типа Подключаемый_ВыполнитьКоманду в формах, что делает ваше расширение более стабильным при обновлениях конфигурации 1С:УНФ. В качестве альтернативного варианта кастомизации макетов через расширение можно использовать инструмент для постобработки печатных форм БСП.