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