Часто при разработке внешних печатных форм (ВПФ) для 1С:Управление нашей фирмой (УНФ) программисты сталкиваются с ситуацией: макет во внешнем файле .epf изменен, колонтитулы поправлены, логотипы добавлены, но при печати из программы пользователь видит старую стандартную форму. Разберем детально, почему так происходит, проанализируем типичные ошибки в коде и выясним, как правильно организовать обращение к макету внутри внешней обработки.
Основная причина того, что изменения макета «не подтягиваются», кроется в механизме копирования стандартного кода из конфигурации во внешнюю обработку. Когда мы берем за основу стандартную обработку печати (например, ПечатьСчетНаОплату), код внутри нее часто содержит жесткие ссылки на менеджер этой же обработки в самой конфигурации. Рассмотрим типичный фрагмент проблемного кода:
Обработки.ПечатьСчетНаОплату.СформироватьПФ(ПечатнаяФорма, ДанныеОбъектовПечати, ОбъектыПечати, СтрокаТаблицы.ЧастичнаяОплата);
В данном случае, даже если вы добавили свой макет во внешнюю форму, программа игнорирует его и вызывает процедуру СформироватьПФ из состава основной конфигурации. Та процедура, в свою очередь, обращается к стандартному макету, зашитому в системе. Таким образом, ваша внешняя обработка превращается в обычную «прослойку», которая просто делегирует выполнение задачи стандартному функционалу.
Прежде чем приступать к исправлению логики печати, убедимся, что функция СведенияОВнешнейОбработке заполнена корректно. Это фундамент, который позволяет БСП (Библиотеке стандартных подсистем) правильно идентифицировать нашу обработку. Рассмотрим пример реализации:
Функция СведенияОВнешнейОбработке() Экспорт
ПараметрыРегистрации = Новый Структура;
мПредставление = ЭтотОбъект.Метаданные().Представление();
ПараметрыРегистрации.Вставить("Вид", "ПечатнаяФорма");
ПараметрыРегистрации.Вставить("Наименование", мПредставление);
ПараметрыРегистрации.Вставить("Версия", "1.0");
ПараметрыРегистрации.Вставить("БезопасныйРежим", Ложь);
ПараметрыРегистрации.Вставить("ВерсияБСП", "2.3.6.53");
Команды = Новый ТаблицаЗначений;
Команды.Колонки.Добавить("Представление", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("Идентификатор", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("Использование", Новый ОписаниеТипов("Строка"));
Команды.Колонки.Добавить("Модификатор", Новый ОписаниеТипов("Строка"));
Команда = Команды.Добавить();
Команда.Представление = мПредставление + " (внешний)";
Команда.Идентификатор = "СчетНаОплатуВнешний"; // Уникальный ID
Команда.Использование = "ВызовСерверногоМетода";
Команда.Модификатор = "ПечатьMXL";
ПараметрыРегистрации.Вставить("Команды", Команды);
Назначения = Новый Массив;
Назначения.Добавить("Документ.ЗаказПокупателя");
ПараметрыРегистрации.Вставить("Назначение", Назначения);
Возврат ПараметрыРегистрации;
КонецФункции
Важный момент: использование модификатора ПечатьMXL сообщает системе, что мы планируем возвращать сформированный табличный документ для стандартного окна просмотра.
Перейдем к основной процедуре, которую вызывает система при нажатии кнопки «Печать». Нам нужно проследить, чтобы каждый вызов функции формирования вел не в конфигурацию, а к методам, описанным внутри нашей обработки. Выясним, как это сделать правильно. Проанализируем исправленную процедуру:
Процедура Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода) Экспорт
// Получаем описание печатной формы из коллекции
ПечатнаяФорма = УправлениеПечатью.СведенияОПечатнойФорме(КоллекцияПечатныхФорм, "СчетНаОплатуВнешний");
Если ПечатнаяФорма <> Неопределено Тогда
ПечатнаяФорма.ТабличныйДокумент = Новый ТабличныйДокумент;
ПечатнаяФорма.ТабличныйДокумент.Автомасштаб = Истина;
// ВНИМАНИЕ: Вызываем локальную функцию СформироватьПФ текущего модуля
СформироватьПФ(ПечатнаяФорма.ТабличныйДокумент, МассивОбъектов, ОбъектыПечати);
КонецЕсли;
КонецПроцедуры
Здесь мы убрали обращение к Обработки.ПечатьСчетНаОплату. Теперь управление передается функции СформироватьПФ, которая должна находиться в этом же модуле объекта внешней обработки.
Теперь разберем, как именно нужно получать макет. Чтобы 1С взяла макет из файла обработки, а не из конфигурации, необходимо использовать метод ЭтотОбъект.ПолучитьМакет(). Посмотрим на пример кода внутри функции формирования:
Процедура СформироватьПФ(ТабличныйДокумент, МассивОбъектов, ОбъектыПечати)
// Получаем макет, который лежит ВНУТРИ этой внешней обработки
Макет = ЭтотОбъект.ПолучитьМакет("ПФ_MXL_СчетНаОплату");
Если Макет = Неопределено Тогда
// Подстраховка для разработчика
ВызватьИсключение "Критическая ошибка: Макет не найден в составе внешней обработки!";
КонецЕсли;
// Дальнейшая логика заполнения данных...
// Например, обход объектов:
Для Каждого СсылкаИзМассива Из МассивОбъектов Цикл
ОбластьЗаголовок = Макет.ПолучитьОбласть("Заголовок");
// Заполнение параметров области...
ОбластьЗаголовок.Параметры.ТекстЗаголовка = "Счет на оплату № " + СсылкаИзМассива.Номер;
ТабличныйДокумент.Вывести(ОбластьЗаголовок);
УправлениеПечатью.ЗадатьОбластьПечатиДокумента(ТабличныйДокумент, 1, ОбъектыПечати, СсылкаИзМассива);
КонецЦикла;
КонецПроцедуры
Обратите внимание на использование ЭтотОбъект. Это ключевое слово гарантирует, что поиск макета ПФ_MXL_СчетНаОплату будет производиться в контексте текущего запущенного объекта (вашей ВПФ).
Если код исправлен, ссылки ведут куда нужно, но в Тонком клиенте все равно отображается старый вариант — мы имеем дело с кэшированием. В 1С:УНФ внешние обработки хранятся в справочнике Дополнительные отчеты и обработки в виде двоичных данных в базе данных. Проанализируем, что происходит при изменении файла на диске:
C:\MyForms\MyPrintForm.epf.Решение: каждый раз после изменения кода или макета во внешнем файле необходимо заходить в справочник «Дополнительные отчеты и обработки», открывать карточку вашей формы и нажимать кнопку «Обновить из файла». Только после этого новая версия макета попадет в базу данных и станет доступна пользователям.
УНФ 3.0 активно использует программное формирование областей макета для вывода печатей и подписей (факсимиле). Если вы создаете свой макет, важно сохранить имена стандартных областей (например, Подписи, Печать) и названия параметров в них. Рассмотрим, как система обычно обрабатывает эти данные:
ВывестиФаксимиле(), программа может выдать ошибку или просто проигнорировать вывод части данных.Поэтому при редактировании макета старайтесь не удалять существующие именованные ячейки, а лишь перемещать их или менять их визуальное оформление (шрифт, границы, цвет).
Отладка внешних печатных форм затруднена тем, что они выполняются в фоновом режиме или через временные файлы. Рассмотрим эффективный метод отладки:
Чтобы точка останова сработала в вашем .epf файле, можно временно воспользоваться «заглушкой» в модуле менеджера документа или в специальной обработке-отладчике, которая вызывает внешнюю обработку напрямую с диска командой:
// Пример для отладки
ОбработкаОбъект = ВнешниеОбработки.Создать("D:\Work\MyPrintForm.epf", Ложь);
ОбработкаОбъект.Печать(МассивОбъектов, КоллекцияПечатныхФорм, ОбъектыПечати, ПараметрыВывода);
Используя этот подход совместно с исправлением ссылок на локальные методы и ЭтотОбъект, мы обеспечим стабильную работу и легкую модификацию печатных форм в 1С:УНФ.