Можно ли в регистр сведений основной конфигурации добавить документ-ссылку из расширения?

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

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

Почему поле типа ЛюбаяСсылка остается пустым?

Для начала выясним причину такого поведения платформы. Тип ЛюбаяСсылка в 1С не является «абсолютно всеядным». На этапе компиляции основной конфигурации этот тип жестко ограничивается списком всех ссылочных типов, существующих только в основной конфигурации. Объекты, добавленные в расширениях, не входят в этот предопределенный список автоматически.

Проанализируем ситуацию на уровне базы данных. Когда мы пытаемся записать ссылку из расширения в поле типа ЛюбаяСсылка, система может физически поместить GUID и идентификатор типа в таблицу SQL. Однако при попытке чтения данных через механизм объектной модели 1С, платформа видит, что идентификатор типа документа из расширения не зарегистрирован в составе типа ЛюбаяСсылка основной конфигурации. В результате система возвращает Неопределено или пустую ссылку, так как для ядра основной базы этого типа «не существует».

Вариант 1: Расширение типа измерения в самом расширении

Самый очевидный путь — это «захватить» регистр сведений в расширение и изменить тип его измерения. Разберем по шагам, как это сделать правильно:

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

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


// Допустим, мы находимся в модуле документа "Ремонт" в расширении
НаборЗаписей = РегистрыСведений.НашРегистрИзОсновы.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(СсылкаНаДокумент); // Если регистр подчинен

НоваяЗапись = НаборЗаписей.Добавить();
// Теперь платформа "знает", что этот тип допустим для данного измерения в контексте расширения
НоваяЗапись.ИзмерениеСсылка = Объект.Ссылка; 
НаборЗаписей.Записать();

Вариант 2: Использование Уникального Идентификатора (UUID)

Если нам необходимо хранить ссылки на объекты из множества разных расширений, и мы не хотим постоянно «перетряхивать» составной тип регистра, можно применить более гибкий, но трудоемкий метод. Мы можем хранить не саму ссылку, а её GUID.

Рассмотрим реализацию этого метода. В основной конфигурации в регистре сведений создадим измерение с типом Строка (длиной 36 символов) или УникальныйИдентификатор. Это позволит нам записывать данные из любого места системы без конфликтов типов.

Запись данных будет выглядеть следующим образом:


НоваяЗапись = НаборЗаписей.Добавить();
// Сохраняем ссылку как строку-идентификатор
НоваяЗапись.ИдентификаторОбъекта = Строка(ДокументОбъект.Ссылка.УникальныйИдентификатор());

Для чтения и преобразования обратно в ссылку нам потребуется вспомогательная функция. Проанализируем пример получения ссылки:


Функция ПолучитьСсылкуИзСтроки(ИмяМетаданных, СтрокаGUID) Экспорт
    // ИмяМетаданных - например, "Документ.Ремонт"
    ГУИД = Новый УникальныйИдентификатор(СтрокаGUID);
    Возврат Документы[ИмяМетаданных].ПолучитьСсылку(ГУИД);
КонецФункции

Преимущество: Данные не «исчезнут», даже если расширение будет временно отключено. После повторного подключения расширения ссылки снова станут валидными.

Вариант 3: Создание отдельного регистра в расширении

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

Посмотрим на преимущества этого подхода:

Риски и технические ограничения

Выясним причины, по которым использование объектов расширений в измерениях основных регистров может быть опасным:

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

Рекомендации

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

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

Если необходимо, чтобы основная конфигурация видела эти данные — используйте промежуточный справочник-посредник в основной конфигурации или храните идентификаторы в виде строк/UUID. Также можно рассмотреть вариант создания служебного справочника в основе, где один из реквизитов будет хранить GUID объекта из расширения, а сам регистр будет ссылаться на этот справочник.

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

← На главную