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