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