Разработка внешних печатных форм (ВПФ) — одна из наиболее частых задач при адаптации конфигураций на платформе 1С:Предприятие 8 под требования бизнеса. Часто возникает необходимость выводить одну и ту же форму в двух вариантах: например, официальный счет-договор с факсимиле (подписями и печатью) для быстрой отправки клиенту по электронной почте и оригинал без факсимиле для последующей передачи в бухгалтерию.
В этой статье мы подробно разберем, как правильно реализовать вывод двух команд для одной внешней печатной формы, используя механизмы Библиотеки стандартных подсистем (БСП). Мы рассмотрим правильную структуру регистрации обработки, особенности работы серверного метода печати, передачу параметров формирования и разберем критические ошибки, из-за которых новые команды могут не появляться в интерфейсе программы.
Нам необходимо доработать внешнюю печатную форму для документа ЗаказПокупателя (или любого другого, например, ПриходнаяНакладная). Вместо одной стандартной кнопки в меню «Печать» должны появиться две независимые команды:
При этом сам макет печатной формы и логика его заполнения должны оставаться едиными, чтобы избежать дублирования кода. Управление выводом факсимиле будет происходить с помощью передачи дополнительного булевого параметра. При необходимости быстро запустить разработку можно использовать готовый пример внешней печатной формы для БСП с выводом факсимиле.
Для того чтобы система БСП поняла, что наша обработка предоставляет две разные команды печати, их необходимо должным образом описать в таблице команд функции СведенияОВнешнейОбработке.
Многие начинающие разработчики совершают ошибку, жестко кодируя создание таблицы значений вручную или задавая одинаковые идентификаторы для разных представлений. Рассмотрим правильный, современный шаблон регистрации с использованием стандартных методов БСП:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке();
// Указываем тип внешней обработки
ПараметрыРегистрации.Вид = ДополнительныеОтчетыИОбработкиКлиентСервер.ВидОбработкиПечатнаяФорма();
// Назначаем обработку для нужных документов
ПараметрыРегистрации.Назначение.Добавить("Документ.ЗаказПокупателя");
ПараметрыРегистрации.Наименование = НСтр("ru='Счет-договор (внешняя)'");
ПараметрыРегистрации.Версия = "1.1";
ПараметрыРегистрации.Информация = НСтр("ru='Внешняя печатная форма счет-договора с опцией вывода факсимиле'");
// Безопасный режим. Если планируется загрузка картинок с диска, может потребоваться Ложь
ПараметрыРегистрации.БезопасныйРежим = Ложь;
// Добавляем ПЕРВУЮ команду - печать обычного счета
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = НСтр("ru='Счет-договор'");
НоваяКоманда.Идентификатор = "_СчетДоговор"; // Уникальный технический идентификатор
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
НоваяКоманда.ПоказыватьОповещение = Истина;
НоваяКоманда.Модификатор = "ПечатьMXL"; // Указывает, что результатом будет табличный документ
// Добавляем ВТОРУЮ команду - печать счета с факсимиле
НоваяКоманда = ПараметрыРегистрации.Команды.Добавить();
НоваяКоманда.Представление = НСтр("ru='Счет-договор (с факсимиле)'");
НоваяКоманда.Идентификатор = "_СчетДоговорФаксимиле"; // Уникальный технический идентификатор
НоваяКоманда.Использование = ДополнительныеОтчетыИОбработкиКлиентСервер.ТипКомандыВызовСерверногоМетода();
НоваяКоманда.ПоказыватьОповещение = Истина;
НоваяКоманда.Модификатор = "ПечатьMXL";
Возврат ПараметрыРегистрации;
КонецФункции
Важное примечание: Обратите внимание на использование уникальных строковых значений в поле Идентификатор (_СчетДоговор и _СчетДоговорФаксимиле). Платформа 1С использует именно эти строки для связывания пользовательского клика по кнопке с конкретной веткой алгоритма на сервере. Если идентификаторы будут одинаковыми, система выведет только одну команду или выдаст ошибку при регистрации.
После выбора команды пользователем БСП передает управление в экспортную процедуру Печать модуля объекта внешней обработки. Наша задача — определить, какая именно команда была вызвана, и запустить формирование табличного документа с соответствующими параметрами.
Выяснить, какую команду нажал пользователь, нам помогает функция УправлениеПечатью.НужноПечататьМакет. В нее обязательно нужно передавать именно Идентификатор команды, определенный нами на Шаге 1, а не текстовое представление для пользователя.
Проанализируем правильную реализацию этой процедуры:
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
// 1. Проверяем вызов команды обычной печати (без факсимиле)
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "_СчетДоговор") Тогда
// Формируем документ, передавая Ложь в параметр ВыводитьФаксимиле
ТабДокумент = СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати, Ложь);
// Выводим полученный табличный документ в коллекцию форм
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"_СчетДоговор",
НСтр("ru='Счет-договор'"),
ТабДокумент
);
КонецЕсли;
// 2. Проверяем вызов команды печати с факсимиле
Если УправлениеПечатью.НужноПечататьМакет(КоллекцияПечатныхФорм, "_СчетДоговорФаксимиле") Тогда
// Формируем документ, передавая Истина в параметр ВыводитьФаксимиле
ТабДокумент = СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати, Истина);
// Выводим полученный табличный документ в коллекцию форм
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(
КоллекцияПечатныхФорм,
"_СчетДоговорФаксимиле",
НСтр("ru='Счет-договор (с факсимиле)'"),
ТабДокумент
);
КонецЕсли;
КонецПроцедуры
Теперь разберем структуру самой функции СформироватьПечатнуюФорму. Она должна принимать булевый параметр (например, ВыводитьФаксимиле) и использовать его при заполнении областей макета.
Рассмотрим упрощенный пример того, как это реализуется в коде:
Функция СформироватьПечатнуюФорму(МассивОбъектов, ОбъектыПечати, ВыводитьФаксимиле)
ТабличныйДокумент = Новый ТабличныйДокумент;
ТабличныйДокумент.ИмяПараметровПечати = "ПАРАМЕТРЫ_ПЕЧАТИ_СчетДоговор";
// Получаем макет печатной формы (из макетов нашей внешней обработки)
Макет = ПолучитьМакет("МакетСчетДоговор");
// Выводим шапку, табличную часть и подвал документа...
// [Здесь располагается стандартный алгоритм заполнения областей]
// Пример вывода области подвалов с факсимиле или без
Если ВыводитьФаксимиле Тогда
// Выводим область макета, где расположены картинки подписей и печати
ОбластьПодвал = Макет.ПолучитьОбласть("ПодвалСФаксимиле");
Иначе
// Выводим стандартную область с пустыми линиями для ручной подписи
ОбластьПодвал = Макет.ПолучитьОбласть("ПодвалОбычный");
КонецЕсли;
// Заполняем параметры области подвала
// ОбластьПодвал.Параметры.Заполнить(ДанныеДокумента);
ТабличныйДокумент.Вывести(ОбластьПодвал);
Возврат ТабличныйДокумент;
КонецФункции
Если после внесения изменений в код вы столкнулись с тем, что команды не появились или выводятся некорректно, проанализируйте следующие важные моменты:
Платформа 1С и БСП кэшируют структуру параметров регистрации внешних обработок в базе данных. Если вы просто сохранили код файла .epf на диске, база данных ничего не узнает о новых командах. Чтобы обновить кэш, обязательно выполните следующие действия в режиме предприятия:
.epf с диска.Ни в коем случае не передавайте русское наименование команды с пробелами в функцию УправлениеПечатью.НужноПечататьМакет. Строка "Счет-договор (с факсимиле)" в качестве идентификатора работать не будет — метод вернет Ложь, и печать не запустится. Используйте только строгие латинские или кириллические идентификаторы без пробелов и спецсимволов (например, "_СчетДоговорФаксимиле").
Если ваши изображения печатей и подписей хранятся не внутри макета обработки, а подгружаются динамически из внешних файлов на сервере или сетевых папок, БСП в безопасном режиме заблокирует к ним доступ. Для решения этой проблемы установите свойство ПараметрыРегистрации.БезопасныйРежим = Ложь; или настройте необходимые разрешения файловой системы в профилях безопасности.
В старых конфигурациях 1С (например, старых редакциях УТ 11 или КА 1.1) ручное создание ТаблицыЗначений для команд было нормой. В современных конфигурациях всегда используйте инициализацию структуры регистрации через вызов общего модуля ДополнительныеОтчетыИОбработки.СведенияОВнешнейОбработке(). Это гарантирует совместимость структуры по колонкам даже при обновлении конфигурации.
Поскольку внешние обработки выполняются в изолированном контексте, отлаживать серверную процедуру Печать в них напрямую бывает сложно (точки останова конфигуратора могут «не ловить» выполнение кода ВПФ). Чтобы упростить процесс:
Печать() напрямую.