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

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

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

Почему конфигуратор «не видит» чужие расширения

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

Решение 1: Объединение расширений в одно

Самый простой и логичный способ, который рекомендует большинство опытных разработчиков — это объединение связанных объектов в рамках одного расширения. Если расширение «А» не может существовать без объектов расширения «Б», то их разделение зачастую избыточно.

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

  1. Полная поддержка ссылочной целостности на уровне платформы.
  2. Возможность визуального выбора типов в конфигураторе.
  3. Отсутствие проблем при обновлении и миграции данных.
  4. Простота в поддержке: вам не нужно следить за порядком подключения нескольких расширений.

Решение 2: Использование механизма зависимостей (Платформа 8.3.24+)

В современных версиях платформы (начиная с 8.3.24) разработчики 1С добавили штатный механизм управления зависимостями. Теперь в свойствах расширения можно явно указать, от каких других расширений оно зависит.

Проанализируем алгоритм действий:

  1. Откроем свойства вашего расширения.
  2. Найдем пункт Зависимости.
  3. Добавим в список расширение "YYY", которое содержит нужный справочник.

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

Решение 3: Программное создание реквизитов формы

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

Рассмотрим, как это реализовать через метод ИзменитьРеквизиты. Выясним последовательность действий в модуле формы:


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

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

Решение 4: Хранение ссылки через Уникальный Идентификатор (GUID)

Чтобы данные сохранялись в базе, мы можем создать в своем расширении реквизит с типом Строка (длиной 36 символов) или УникальныйИдентификатор. Мы будем записывать туда GUID ссылки из чужого расширения.

Разберем пример получения ссылки по сохраненному идентификатору:


// Получение ссылки из GUID для работы в коде
ИмяСправочника = "XXX"; 
ТекGUID = Новый УникальныйИдентификатор(СтрокаСИдентификатором);
СсылкаНаОбъект = Справочники[ИмяСправочника].ПолучитьСсылку(ТекGUID);

Если Не СсылкаНаОбъект.Пустая() Тогда
    // Работаем с объектом как обычно
КонецЕсли;

Этот метод позволяет обойти жесткую типизацию конфигуратора. Однако при работе с запросами возникнут сложности: вы не сможете напрямую обращаться к полям этого справочника через точку (например, Документ.МойРеквизитGUID.Наименование).

Решение 5: Работа с данными в запросах

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

  1. Использование консоли запросов: Как было замечено на форуме, «тру-разработчики» отлаживают такие запросы в режиме предприятия, где метаданные всех расширений уже объединены. В коде же текст запроса пишется вручную без использования конструктора, если конструктор выдает ошибку.
  2. Временные таблицы: Вы можете сначала программно сформировать массив ссылок, а затем передать его в запрос как параметр. Платформа корректно типизирует эти данные во временной таблице.

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   ТЗ.СсылкаОбъекта КАК Ссылка
    |ПОМЕСТИТЬ ВТ_Объекты
    |ИЗ
    |   &ВнешняяТЗ КАК ТЗ;
    |
    |ВЫБРАТЬ
    |   ВТ.Ссылка.Наименование КАК Наименование,
    |   ВТ.Ссылка.Код КАК Код
    |ИЗ
    |   ВТ_Объекты КАК ВТ";

// Предварительно получаем массив ссылок через Справочники[...].ПолучитьСсылку()
Запрос.УстановитьПараметр("ВнешняяТЗ", ТаблицаСОбъектами);
Результат = Запрос.Выполнить();

Проблема выбора типа и баги платформы

Иногда даже внутри одного расширения возникают проблемы с отображением типов (как в 15-м сообщении обсуждения). Проанализируем ситуацию: вы добавили справочник, применили изменения, но не видите его в списке доступных типов для другого реквизита.

Как это лечится:

Итоги и рекомендации

Подводя итог, можно сказать: если у вас есть возможность объединить расширения — сделайте это. Это избавит вас от 90% проблем с типами и запросами.

Если же архитектура требует строгого разделения, используйте механизм зависимостей (на новых платформах) в сочетании с программным созданием реквизитов на форме. Хранение через GUID оправдано только в исключительных случаях, когда ссылки могут динамически указывать на объекты разных, заранее неизвестных расширений.

← На главную