Как правильно обратиться к макету внешней обработки и перенести типовой код

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

При разработке внешних обработок на базе типовых решений 1С (например, «Розница», «Управление торговлей» или «ERP») разработчики часто сталкиваются с проблемой: после сохранения обработки как внешней код продолжает обращаться к макетам, «вшитым» в основную конфигурацию. Это происходит из-за жестких ссылок в программном коде. Рассмотрим подробно, как перенаправить эти обращения на макеты самой внешней обработки и как корректно перенести логику из модуля менеджера.

Проблема контекста: получение макета из формы

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


СхемаКомпоновкиДанных = Обработки.ПечатьЭтикетокИЦенников.ПолучитьМакет("ПоляШаблона");

Здесь происходит прямое обращение к менеджеру встроенной обработки. Чтобы заставить систему искать макет внутри вашего .epf файла, нам нужно получить доступ к объекту обработки. Разберем, как это сделать в модуле управляемой формы.

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

Рассмотрим пример правильной функции на сервере в модуле формы:


&НаСервере
Функция ПолучитьМакетСвоейОбработки(ИмяМакета)
    // Преобразуем данные формы в объект внешней обработки
    ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
    
    // Теперь у нас есть доступ ко всем методам объекта, включая макеты
    Возврат ОбработкаОбъект.ПолучитьМакет(ИмяМакета);
КонецФункции

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

Перенос кода из модуля менеджера в модуль объекта

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

Проанализируем последствия простого копирования. Если вы просто вставите код, он может перестать работать по двум причинам:

  1. Жесткие ссылки: В коде могут остаться обращения вида Обработки.ИмяТиповойОбработки.КакаяТоФункция(). Их нужно заменить на локальные вызовы.
  2. Область видимости: Если функции должны вызываться из формы, они должны быть помечены ключевым словом Экспорт.

Выясним причину ошибки, возникающей после переноса: Переменная не определена (РеквизитФормыВЗначение). Это происходит, если вы пытаетесь использовать функции модуля формы внутри модуля объекта. Запомните важное правило: в модуле объекта функция РеквизитФормыВЗначение не нужна и недоступна.

В модуле объекта вы уже находитесь «внутри» обработки. Чтобы получить макет здесь, используйте следующий код:


// В модуле объекта внешней обработки
Схема = ЭтотОбъект.ПолучитьМакет("ПоляШаблона");
// Или просто
Схема = ПолучитьМакет("ПоляШаблона");

Как «отвязать» код от конфигурации: массовая замена

Посмотрим на ситуацию практически. Типовые механизмы печати ценников огромны. Искать каждое обращение вручную — трудоемкая задача. Чтобы быстро адаптировать код, выполним следующие шаги:

  1. Откройте модуль объекта вашей внешней обработки.
  2. Нажмите Ctrl + H (замена).
  3. В поле «Искать» введите имя типовой обработки с префиксом, например: Обработки.ПечатьЭтикетокИЦенников.
  4. В поле «Заменить на» для модуля объекта оставьте пустое место (если это вызов функции того же модуля) или ЭтотОбъект.
  5. Нажмите «Заменить все».

Рассмотрим пример трансформации кода. Было:


СтруктураНастроек = Обработки.ПечатьЭтикетокИЦенников.ПолучитьПустуюСтруктуруНастроек();
СхемаКомпоновкиДанных = Обработки.ПечатьЭтикетокИЦенников.ПолучитьМакет(СтруктураНастроек.ИмяМакета);

Стало (в модуле объекта):


СтруктураНастроек = ПолучитьПустуюСтруктуруНастроек(); // Функция теперь локальна
СхемаКомпоновкиДанных = ПолучитьМакет(СтруктураНастроек.ИмяМакета); // Макет берется из файла

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

При переносе кода из модуля менеджера в модуль объекта важно следить за именами переменных. Рассмотрим ситуацию: в модуле менеджера была переменная Объект, используемая локально в какой-то процедуре. При переносе в модуль объекта она может начать конфликтовать с контекстом, если у обработки есть реквизит с таким же именем.

Совет: Всегда проверяйте раздел объявлений переменных в начале модуля. Если во внешней обработке добавлены новые реквизиты, убедитесь, что их имена уникальны и не перекрывают служебные функции платформы или переменные в скопированном коде.

Особенности СКД во внешних обработках

Если ваша обработка использует сложные схемы компоновки данных (СКД) для формирования этикеток, обратите внимание на параметр ИмяМакетаСхемыКомпоновкиДанных. В типовых решениях это имя часто передается в структуре настроек.

Разберем, как гарантировать загрузку именно вашей схемы:

  1. Убедитесь, что в макетах внешней обработки имя СКД совпадает с тем, которое ожидает код (например, ПоляШаблона).
  2. Если вы переименовали макет во внешней обработке (например, в ПоляШаблона_Свой), обязательно найдите в коде место, где заполняется СтруктураНастроек, и обновите значение этого поля.

Проанализируем типичный фрагмент настройки СКД:


// В модуле объекта
Процедура ИнициализироватьСхему(СтруктураНастроек) Экспорт
    // Если СтруктураНастроек.ИмяМакета прилетает пустой или со старым именем
    Если ПустаяСтрока(СтруктураНастроек.ИмяМакета) Тогда
        ИмяМакета = "ПоляШаблона";
    Иначе
        ИмяМакета = СтруктураНастроек.ИмяМакета;
    КонецЕсли;
    
    Схема = ПолучитьМакет(ИмяМакета);
    // Дальнейшая работа с СКД...
КонецПроцедуры

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

← На главную