Как исправить ошибку открытия макета из внешней печатной формы после обновления БСП?

Программист 1С v8.3 (Управляемые формы) 1С:ERP Управление предприятием IT и автоматизация бизнеса
← На главную

При разработке и адаптации внешних печатных форм для современных конфигураций 1С мы нередко сталкиваемся с изменениями в архитектуре типовых решений. Рассмотрим частую проблему, которая стала появляться в таких конфигурациях, как 1С:ERP 2.4+, 1С:ЗУП 3.1.18+ и 1С:БП 3.0.101+.

Проанализируем ситуацию и текст ошибки

Представим ситуацию: мы добавили внешнюю обработку в справочник Дополнительные отчеты и обработки. Названия макетов указаны абсолютно верно. Однако, при попытке открыть раздел Макеты печатных форм (или при формировании самой формы) процесс аварийно завершается с сообщением:

Макет "ВнешняяОбработка.ПриемНаРаботу.ПФ_ODT_ДоговорМатериальнойОтветственности" не существует. Операция прервана.

В стеке ошибки мы видим отсылку к модулям мультиязычности:


{ОбщийМодуль.УправлениеПечатьюМультиязычность.Модуль(106)}: ВызватьИсключение ТекстОшибки;
{ОбщийМодуль.УправлениеПечатьюМультиязычность.Модуль(137)}: Для Каждого КодЯзыка Из ЯзыкиМакета(ИмяОбъектаМетаданныхМакета) Цикл
{РегистрСведений.ПользовательскиеМакетыПечати.Форма.МакетыПечатныхФорм.Форма(267)}: Возврат МодульУправлениеПечатьюМультиязычность.ПредставлениеЯзыковМакета(ИмяОбъектаМетаданныхМакета);

Код внешней формы, который вызывает ошибку, может выглядеть примерно так:


Для Каждого ИмяМакета Из МассивИменМакетов Цикл
    ОписаниеСекцийМакета = Новый Структура;
    Макет = УправлениеПечатью.МакетПечатнойФормы("ВнешняяОбработка.ПриемНаРаботу." + ИмяМакета);
    // Дальнейшая логика получения секций
КонецЦикла;

Выясним причину возникновения сбоя

Разберем по шагам, почему возникает исключение. Проблема связана с обновлением Библиотеки стандартных подсистем (БСП) разработчиками фирмы "1С". В новых версиях БСП был внедрен механизм мультиязычности макетов. Появился новый общий модуль УправлениеПечатьюМультиязычность, который изменил логику работы типовых функций подсистемы печати.

Когда платформа через процедуру УправлениеПечатью.МакетПечатнойФормы или аналогичные пытается получить макет по переданному пути (например, "ВнешняяОбработка.ПриемНаРаботу.ПФ_ODT_ДоговорМатериальнойОтветственности"), система использует функцию Метаданные.НайтиПоПолномуИмени(). Этот метод ищет объект в общем дереве метаданных самой конфигурации.

Поскольку внешняя обработка является подключаемым внешним файлом, в дереве метаданных конфигурации её не существует. Соответственно, метод платформы возвращает значение Неопределено. Из-за этого модуль мультиязычности не может найти объект, не может получить доступные языки макета и выбрасывает программное исключение.

Рассмотрим подробнее способы решения

Чтобы восстановить работоспособность внешней печатной формы, нам потребуется открыть её код в конфигураторе и скорректировать работу с методами БСП. Разберем два основных подхода.

Способ 1: Очистка параметра ПолныйПутьКМакету

Если сбой происходит на этапе формирования табличного документа, обратите внимание на вызов процедуры УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию.

Раньше в эту процедуру часто передавался полный путь к макету параметром ПолныйПутьКМакету. Теперь наличие этого пути для внешних форм приводит к запуску проверки мультиязычности и ошибке. Решение — передавать этот параметр пустым.


// Было (приводит к ошибке):
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(КоллекцияПечатныхФорм, ИмяМакета, СинонимМакета, ТабличныйДокумент, "ВнешняяОбработка.ПриемНаРаботу." + ИмяМакета);

// Стало (правильный вариант для внешней обработки):
УправлениеПечатью.ВывестиТабличныйДокументВКоллекцию(КоллекцияПечатныхФорм, ИмяМакета, СинонимМакета, ТабличныйДокумент, "");

При передаче пустой строки ("") БСП не пытается искать объект во внутренних метаданных, и печать проходит успешно.

Способ 2: Прямое получение макета без использования механизмов БСП

Если ошибка возникает в функции типа ПолучитьМакетыИОписанияСекций при извлечении самого макета (как описано в первоначальном коде), то вместо использования типовой функции БСП следует получать макет стандартными средствами платформы.

Метод УправлениеПечатью.МакетПечатнойФормы() теперь жестко завязан на метаданные конфигурации. Для внешних обработок мы должны получать макет напрямую из объекта самой внешней обработки.


// Было (вызывает сбой из-за отсутствия объекта в метаданных):
Макет = УправлениеПечатью.МакетПечатнойФормы("ВнешняяОбработка.ПриемНаРаботу." + ИмяМакета);

// Стало (обращаемся к объекту обработки напрямую):
ОбработкаОбъект = РеквизитФормыВЗначение("Объект"); // Если код выполняется в модуле формы
Макет = ОбработкаОбъект.ПолучитьМакет(ИмяМакета);

// Или если код располагается непосредственно в модуле объекта обработки:
Макет = ПолучитьМакет(ИмяМакета);

Важное примечание: Также в некоторых релизах разработчики рекомендуют, чтобы пользовательские макеты в формате табличного документа 1С (MXL) имели префикс ПФ_MXL_, а офисные макеты (Word/OpenOffice) префиксы ПФ_DOC_ или ПФ_ODT_ соответственно. Проверьте имена своих макетов на соответствие этому стандарту, чтобы подсистема управления печатью корректно распознавала их тип.

Применяя эти корректировки, вы адаптируете свои внешние печатные формы под новые требования библиотеки стандартных подсистем и избавитесь от исключений модуля мультиязычности.

← На главную