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

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

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

Разберем причину: почему нельзя просто выбрать ДокументСсылка

Многие начинающие разработчики пытаются установить для определяемого типа тип ДокументСсылка (корневой объект), ожидая, что это автоматически позволит хранить ссылку на любой документ в системе. Проанализируем ситуацию: в платформе 1С тип ДокументСсылка является общим, абстрактным типом. Когда мы создаем ОпределяемыйТип, система должна четко понимать, какие именно таблицы СУБД будут задействованы для хранения этих данных.

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

Посмотрим на особенности работы в расширениях

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

  1. Создание новых типов: В старых версиях (например, 8.3.13, упомянутой в обсуждении) создание собственного определяемого типа непосредственно в расширении было недоступно. Начиная с версии 8.3.15, эта возможность появилась. Теперь мы можем создать ОпределяемыйТип внутри расширения и использовать его для новых реквизитов, добавленных в этом же расширении.
  2. Заимствование существующих типов: Если ОпределяемыйТип уже существует в основной конфигурации, мы можем заимствовать его в расширение. Важное преимущество: в расширении мы можем дополнить состав этого типа объектами, которые созданы в самом расширении. Однако помните, что удалить из состава типа те объекты, которые были определены в основной конфигурации, через расширение невозможно.
  3. Тип реквизита в расширении: Если ваша задача — создать реквизит в расширении, который ссылается на «любой документ», и вы не хотите или не можете использовать определяемый тип, вам придется создавать реквизит составного типа прямо в расширении. Но здесь нас подстерегает «ловушка» обновления, о которой мы поговорим ниже.

Проанализируем архитектурный подход: Основная конфигурация или Расширение?

Рассмотрим важный совет из практики опытных разработчиков. Существует стратегия, при которой новые реквизиты (данные) добавляются в основную конфигурацию, а вся логика их обработки выносится в расширение. Почему это бывает полезно?

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

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

  1. Создаем в расширении новый ОпределяемыйТип (если версия платформы позволяет).
  2. В его свойствах выбираем «Составной тип данных».
  3. Отмечаем все документы, ссылки на которые планируется хранить.
  4. Используем этот тип для нужных реквизитов.

Важный нюанс: Производительность составных типов

Разберем ситуацию с точки зрения СУБД. Когда мы создаем ОпределяемыйТип, включающий в себя, к примеру, 200 видов документов, это существенно влияет на структуру таблиц. В SQL-базе для хранения такого реквизита может создаваться большое количество полей (в зависимости от настроек платформы и конкретной реализации).

Рекомендуется: Не включать в составной тип вообще все документы системы «на всякий случай». Проанализируйте, какие именно объекты реально будут участвовать в бизнес-процессе. Ограничение состава типа — это прямой путь к повышению скорости работы запросов и уменьшению размера базы данных.

Выясним риски: Безопасность данных в расширениях

Многих разработчиков беспокоит вопрос: что произойдет с данными в реквизитах, созданных через расширение, если это расширение будет отключено или удалено? Проясним этот момент:

Пример программной работы с типами

Иногда нам нужно проверить, относится ли ссылка к нашему определяемому типу программно. Рассмотрим, как это сделать правильно в коде:


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

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

Подведем итоги

Для реализации задачи по созданию универсального поля документов в расширении, мы рекомендуем:

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