Можно ли добавить предопределенный элемент справочника в расширении конфигурации 1С?

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

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

Основные принципы работы предопределенных данных в расширениях

Давайте сразу ответим на главный вопрос: возможно ли это? Ответ: Да, но с условиями.

Начиная с версии платформы 8.3.20, фирма «1С» реализовала возможность создания предопределенных элементов в расширениях. Однако здесь кроется самый важный нюанс, который мы должны четко понимать, чтобы избежать ошибок проектирования.

Разделим объекты метаданных в расширении на две категории:

  1. Собственные объекты расширения — это справочники, документы и другие объекты, которые вы создали непосредственно в дереве расширения (их нет в основной конфигурации).
  2. Заимствованные объекты — это объекты из основной конфигурации (например, типовой справочник Контрагенты или Номенклатура), которые вы добавили в расширение для доработки.

Сценарий 1: Собственные объекты расширения

Если вы создали новый справочник внутри расширения (например, Расш_ВидыДополнительныхСтатусов), то начиная с платформы 8.3.20, вы имеете полное право создавать для него предопределенные элементы.

Требования для работы:

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

Сценарий 2: Заимствованные (типовые) объекты

Здесь ситуация иная. Давайте разберем, почему нельзя добавить предопределенный элемент в заимствованный справочник (например, в типовые Склады или Контрагенты).

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

Представим ситуацию:

  1. Вы добавили в расширении в справочник Контрагенты предопределенного элемента «Основной Покупатель».
  2. Поставщик типового решения выпустил обновление, где тоже добавил предопределенного «Основной Покупатель», но с другим ID.
  3. При обновлении произойдет конфликт идентификаторов, который платформа не сможет разрешить корректно.

Поэтому на текущий момент (включая актуальные версии платформы) добавление предопределенных данных в заимствованные объекты метаданных невозможно.

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

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

Существует несколько причин такого поведения, давайте их проанализируем.

1. Ленивая инициализация (Lazy Initialization)

Платформа 1С старается оптимизировать работу с базой данных. Зачастую физическая запись в таблице SQL для предопределенного элемента создается не в момент обновления конфигурации базы данных, а в момент первого программного обращения к этому элементу.

Попробуйте обратиться к элементу программно, чтобы «разбудить» платформу:


// Пример кода для инициализации
СсылкаНаЭлемент = Справочники.Расш_МойСправочник.МойПредопределенныйЭлемент;
Сообщить("Элемент существует: " + СсылкаНаЭлемент);

2. Проблемы с кешем

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

3. Ручное связывание (ИмяПредопределенныхДанных)

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

Обратите внимание: в стандартном интерфейсе это поле обычно скрыто. Заполнить его можно простой обработкой:


ЭлементОбъект = СсылкаНаРучнойЭлемент.ПолучитьОбъект();
// Имя должно в точности совпадать с именем в конфигураторе расширения
ЭлементОбъект.ИмяПредопределенныхДанных = "НашПредопределенныйВРасширении";
ЭлементОбъект.Записать();

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

Обходные пути: Как добавить «предопределенного» в типовой справочник?

Поскольку напрямую добавить предопределенный элемент в заимствованный справочник нельзя, нам необходимо использовать проверенные практики («Best Practices»). Рассмотрим два основных подхода.

Метод 1: Использование Констант (Рекомендуемый)

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

Алгоритм действий:

  1. В расширении создаем Константу, например, Расш_СпецКонтрагентДляОбмена.
  2. Тип значения константы устанавливаем СправочникСсылка.Контрагенты.
  3. В режиме «Предприятие» создаем нужного контрагента и выбираем его в эту константу.
  4. В коде обращаемся не к Справочники.Контрагенты.НайтиПо..., а к значению константы.

// Получение значения
СпецКонтрагент = Константы.Расш_СпецКонтрагентДляОбмена.Получить();

Если СпецКонтрагент.Пустая() Тогда
    // Логика обработки ошибки или создания элемента
КонецЕсли;

Преимущества:

Метод 2: Поиск по реквизитам (Менее надежный)

Если вариант с константами не подходит, можно использовать поиск элемента при старте работы системы или перед выполнением операции. Обычно ищут по Коду, Наименованию или специальному дополнительному реквизиту.


// Пример функции поиска или создания
Функция ПолучитьСпецЭлемент()
    
    ИмяЭлемента = "СлужебныйПользователь";
    Найдено = Справочники.Контрагенты.НайтиПоНаименованию(ИмяЭлемента);
    
    Если Найдено.Пустая() Тогда
        НовыйЭлемент = Справочники.Контрагенты.СоздатьЭлемент();
        НовыйЭлемент.Наименование = ИмяЭлемента;
        НовыйЭлемент.Записать();
        Возврат НовыйЭлемент.Ссылка;
    Иначе
        Возврат Найдено;
    КонецЕсли;
    
КонецФункции;

Недостатки:

Итоги

Давайте резюмируем информацию по работе с предопределенными элементами в расширениях:

  1. Для собственных справочников расширения: Можно (платформа 8.3.20+, режим совместимости 8.3.19+).
  2. Для заимствованных справочников: Нельзя (ограничение архитектуры).
  3. Если элемент собственного справочника не появился: проверьте кеш, попробуйте обратиться программно или установите ИмяПредопределенныхДанных вручную.
  4. Для связи с конкретными элементами типовых справочников используйте Константы в расширении.

Используйте эти методы, чтобы ваши решения на базе расширений были стабильными и обновляемыми.

← На главную