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