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