Как назначить определяемый тип реквизиту в расширении 1С: причины ограничения и пути обхода

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

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

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

Почему определяемый тип нельзя выбрать в расширении?

Разберем первопричину. Платформа 1С имеет жесткое архитектурное ограничение: нельзя назначить определяемый тип реквизиту, который был создан непосредственно внутри расширения. Даже если вы выполнили все предварительные условия — заимствовали ОпределяемыйТип, заимствовали все входящие в него объекты (справочники, документы) и убедились в их наличии в расширении — при открытии окна выбора типа данных для нового реквизита вы увидите только примитивные типы и ссылки на конкретные объекты, но не сам определяемый тип.

Выясним причину такого поведения системы. Это связано с безопасностью и целостностью данных. Объект ОпределяемыйТип в расширении может быть изменен пользователем (программистом) путем добавления новых типов. Если бы платформа разрешила использовать такой тип для хранения данных в базе, то при отключении расширения система не смогла бы однозначно интерпретировать структуру хранения этих данных в SQL-таблицах. Для обеспечения стабильности основной базы данных платформа блокирует использование «динамически меняющихся» типов для новых физических полей базы данных, созданных в слое расширения.

Вариант 1: Ручное создание составного типа данных

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

Рассмотрим этот процесс пошагово:

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

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

Вариант 2: Использование возможностей платформы 8.3.20 и выше

Посмотрим на ситуацию под другим углом. Начиная с версии платформы 8.3.20.1549, функционал работы с определяемыми типами в расширениях был значительно расширен. Хотя мы по-прежнему не можем выбрать их для новых реквизитов, мы можем влиять на существующие механизмы.

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

  1. Заимствуйте необходимый ОпределяемыйТип из основной конфигурации в расширение.
  2. В свойстве Тип этого заимствованного объекта в расширении добавьте ваш новый справочник или документ.

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

Вариант 3: Использование универсального ссылочного типа

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

Выполним следующие действия:

  1. Установите для реквизита тип ЛюбаяСсылка. Это позволит хранить в поле ссылку на любой объект метаданных.
  2. Для того чтобы пользователь не мог выбрать «лишние» объекты в форме, проанализируем и настроим параметры выбора программно.

Пример кода для ограничения выбора в форме (событие ПриСозданииНаСервере):


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

Важные технические нюансы и риски

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

Режим совместимости: Обратите внимание, что расширение состава определяемых типов (Вариант 2) работает корректно только в том случае, если Режим совместимости и основной конфигурации, и расширения установлен в значение не ниже 8.3.20. Если режим совместимости ниже, многие изменения в определяемых типах внутри расширения могут игнорироваться или приводить к ошибкам при обновлении базы данных.

Риск потери данных: Помните, что любые данные, хранящиеся в реквизитах, созданных внутри расширения (даже если они используют стандартные составные типы), будут безвозвратно удалены из SQL-таблиц при удалении расширения из базы данных. Если вы планируете «единовременную процедуру» (как упоминалось в обсуждении), убедитесь, что после переноса данных они будут обработаны или перемещены в основные объекты конфигурации.

Ошибки идентификаторов: Иногда при активном заимствовании объектов в расширение возникает критическая ошибка: «изменился внутренний идентификатор определяемого типа». В этой ситуации никакие настройки типа не помогут. Единственным решением будет полное удаление заимствованного определяемого типа из расширения и его повторное добавление (заимствование) из основной конфигурации.

Резюме

Выясним краткий итог нашего анализа. Прямого способа выбрать ОпределяемыйТип для собственного реквизита расширения не существует. Однако, используя ручное создание составного типа или программное управление типом ЛюбаяСсылка, вы сможете полностью реализовать необходимую бизнес-логику. Если же ваша цель — интегрировать новые объекты расширения в типовой функционал, используйте метод расширения состава заимствованного типа в платформе версии 8.3.20 и выше.

← На главную