Почему в 1С 8.3.14 возникает ошибка «Процедура или функция с указанным именем не определена (ПолучитьМакетОформления)»?

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

При переводе старых конфигураций (особенно использующих обычные формы и построитель отчетов) на новые релизы платформы «1С:Предприятие», начиная с версии 8.3.14, разработчики часто сталкиваются с неприятной ситуацией. Код, который годами стабильно работал на платформе 8.3.12, внезапно отказывается компилироваться, выдавая ошибку:

{ОбщийМодуль.ОбщегоНазначения.Модуль(4333,32)}: Процедура или функция с указанным именем не определена (ПолучитьМакетОформления)

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

Выясняем причину: особенности контекста и компиляции

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

Почему же в старых версиях платформы (например, 8.3.12) эта ошибка не «выстреливала» при старте системы, а в 8.3.14 стала критичной? Дело в механизмах проверки кода и оптимизации компиляции:

  1. Ужесточение контроля синтаксиса: В старых релизах платформы компиляция модулей для неиспользуемых контекстов могла происходить «лениво» (по требованию). Если процедура, содержащая вызов ПолучитьМакетОформления(), физически никогда не вызывалась на сервере, платформа могла игнорировать некорректный вызов при запуске. Начиная с версии 8.3.14, валидация кода под все объявленные в свойствах модуля контексты стала обязательной и более строгой.
  2. Свойства общего модуля: Проблемный вызов чаще всего находится в общем модуле (например, ОбщегоНазначения). У таких модулей в свойствах практически всегда взведен флаг «Сервер». При обновлении платформы система пытается скомпилировать этот модуль для сервера, натыкается на сугубо клиентскую функцию ПолучитьМакетОформления() и прерывает работу с ошибкой.

Перейдем к практическим вариантам решения этой проблемы.

Решение 1. Использование директив препроцессора (Быстрый путь)

Если код, содержащий вызов макета оформления, должен выполняться исключительно на клиенте (в толстом клиенте), самым простым и правильным решением будет явное указание платформе инструкций препроцессора. Мы должны «скрыть» этот участок кода от серверного компилятора.

Рассмотрим подробнее, как переписать проблемный участок кода. Вместо исходного варианта:


ПострПечать.МакетОформления = ПолучитьМакетОформления(?(Оформление = Неопределено, СтандартноеОформление.Интерфейс, Оформление));

Используем конструкцию с директивами препроцессора:


#Если ТолстыйКлиентОбычноеПриложение Или ТолстыйКлиентУправляемоеПриложение Тогда
    ПострПечать.МакетОформления = ПолучитьМакетОформления(?(Оформление = Неопределено, СтандартноеОформление.Интерфейс, Оформление));
#Иначе
    // Если код компилируется на сервере или в тонком клиенте, 
    // мы можем либо ничего не делать, либо задать альтернативное поведение.
    ПострПечать.МакетОформления = Неопределено;
#КонецЕсли

Этот нехитрый прием полностью решает проблему компиляции общего модуля. Серверный компилятор просто проигнорирует строку внутри условия препроцессора, а толстый клиент успешно выполнит её во время работы пользователя.

Решение 2. Обходной путь через Общий макет (Для серверных отчетов)

Что делать, если построитель отчета инициализируется на стороне сервера (например, в регламентном задании, которое генерирует отчет и отправляет его по электронной почте)? В этом случае директивы препроцессора нам не помогут, так как на сервере функция ПолучитьМакетОформления() физически не может быть выполнена.

Для таких ситуаций мы можем применить изящный обходной путь:

  1. Запустим «1С:Предприятие» в режиме толстого клиента один раз и выполним код, который получит нужный макет оформления и сохранит его в файл на диск в формате табличного документа (.mxl):
    
    Макет = ПолучитьМакетОформления(СтандартноеОформление.Интерфейс);
    Макет.Записать("C:\temp\MyInterfaceTemplate.mxl");
    
  2. Откроем конфигуратор нашей базы данных.
  3. В ветке метаданных найдем раздел «Общие» -> «Общие макеты».
  4. Добавим новый общий макет с типом «Табличный документ» и назовем его, например, МакетОформленияИнтерфейс.
  5. Загрузим в созданный макет ранее сохраненный файл MyInterfaceTemplate.mxl.
  6. Теперь в нашем общем модуле мы можем отказаться от использования проблемного метода ПолучитьМакетОформления() и заменить его на обращение к общему макету, который прекрасно работает в любом контексте (и на клиенте, и на сервере):

// Этот код абсолютно безопасен и будет успешно работать на сервере
ПострПечать.МакетОформления = ПолучитьОбщийМакет("МакетОформленияИнтерфейс");

Данный подход гарантирует одинаковый внешний вид отчетов независимо от того, где они формируются.

Решение 3. Проверка и разделение свойств общих модулей

Если вы столкнулись с этой ошибкой, рекомендуем также проанализировать структуру ваших общих модулей. Зачастую разработчики помещают клиентские процедуры (работающие с формами, интерфейсом или макетами оформления) в универсальные общие модули, у которых включены все галочки компиляции.

Выполните следующие шаги для аудита:

  1. Найдите общий модуль, в котором произошла ошибка, в дереве метаданных конфигуратора.
  2. Нажмите по нему правой кнопкой мыши и откройте «Свойства».
  3. Обратите внимание на флаги компиляции: если модуль предназначен только для работы интерфейса обычного приложения, снимите флаг «Сервер».
  4. Если модуль действительно должен содержать как серверные, так и клиентские процедуры, лучшим решением будет разделить его на два отдельных модуля: например, ОбщегоНазначенияКлиент (без флага «Сервер») и ОбщегоНазначенияСервер. Перенесите вызовы работы с макетами оформления в клиентский модуль.

Разделение логики по контекстам выполнения — это стандарт хорошего тона при разработке на платформе 1С, который убережет вашу конфигурацию от подобных ошибок при любых последующих обновлениях платформы.

← На главную