Работа с расширениями конфигурации (Extensions) стала стандартом при доработке типовых решений 1С. Однако, когда дело доходит до предопределенных данных (элементов справочников, ПВХ и т.д.), многие разработчики сталкиваются с неочевидным поведением платформы. В этой статье мы подробно разберем, когда можно создавать предопределенные элементы в расширении, почему иногда это не работает, и какие существуют обходные пути для типовых объектов.
Давайте сразу ответим на главный вопрос: возможно ли это? Ответ: Да, но с условиями.
Начиная с версии платформы 8.3.20, фирма «1С» реализовала возможность создания предопределенных элементов в расширениях. Однако здесь кроется самый важный нюанс, который мы должны четко понимать, чтобы избежать ошибок проектирования.
Разделим объекты метаданных в расширении на две категории:
Контрагенты или Номенклатура), которые вы добавили в расширение для доработки.Если вы создали новый справочник внутри расширения (например, Расш_ВидыДополнительныхСтатусов), то начиная с платформы 8.3.20, вы имеете полное право создавать для него предопределенные элементы.
Требования для работы:
В этом случае процесс ничем не отличается от работы в обычной конфигурации: вы открываете список предопределенных элементов в дереве метаданных расширения и добавляете нужные записи.
Здесь ситуация иная. Давайте разберем, почему нельзя добавить предопределенный элемент в заимствованный справочник (например, в типовые Склады или Контрагенты).
Механизм предопределенных данных в 1С жестко завязан на уникальные идентификаторы (UUID). В основной конфигурации каждый предопределенный элемент имеет свой жестко прописанный ID. Если бы платформа разрешила добавлять предопределенные элементы в типовой справочник через расширение, возникла бы проблема синхронизации.
Представим ситуацию:
Контрагенты предопределенного элемента «Основной Покупатель».Поэтому на текущий момент (включая актуальные версии платформы) добавление предопределенных данных в заимствованные объекты метаданных невозможно.
Рассмотрим ситуацию, с которой часто сталкиваются разработчики. Вы выполнили все условия: у вас собственный справочник в расширении, платформа свежая, вы добавили предопределенный элемент в конфигураторе, обновили базу, запускаете режим «Предприятие», а элемента нет. Почему?
Существует несколько причин такого поведения, давайте их проанализируем.
Платформа 1С старается оптимизировать работу с базой данных. Зачастую физическая запись в таблице SQL для предопределенного элемента создается не в момент обновления конфигурации базы данных, а в момент первого программного обращения к этому элементу.
Попробуйте обратиться к элементу программно, чтобы «разбудить» платформу:
// Пример кода для инициализации
СсылкаНаЭлемент = Справочники.Расш_МойСправочник.МойПредопределенныйЭлемент;
Сообщить("Элемент существует: " + СсылкаНаЭлемент);
Расширения очень чувствительны к серверному кешу. Если вы добавили элемент, но не видите его, попробуйте очистить кеш сервера 1С. В некоторых случаях старая схема метаданных может «застрять» в памяти рабочих процессов.
Если автоматическое создание не сработало, и вы создали элемент в режиме «Предприятие» вручную, его можно «превратить» в предопределенный. Для этого необходимо заполнить свойство ИмяПредопределенныхДанных.
Обратите внимание: в стандартном интерфейсе это поле обычно скрыто. Заполнить его можно простой обработкой:
ЭлементОбъект = СсылкаНаРучнойЭлемент.ПолучитьОбъект();
// Имя должно в точности совпадать с именем в конфигураторе расширения
ЭлементОбъект.ИмяПредопределенныхДанных = "НашПредопределенныйВРасширении";
ЭлементОбъект.Записать();
После выполнения этого кода значок элемента в списке изменится на характерную «точку», обозначающую предопределенный элемент.
Поскольку напрямую добавить предопределенный элемент в заимствованный справочник нельзя, нам необходимо использовать проверенные практики («Best Practices»). Рассмотрим два основных подхода.
Это самый надежный и производительный способ. Суть заключается в создании специальной константы в расширении, которая будет хранить ссылку на нужный элемент.
Алгоритм действий:
Расш_СпецКонтрагентДляОбмена.СправочникСсылка.Контрагенты.Справочники.Контрагенты.НайтиПо..., а к значению константы.
// Получение значения
СпецКонтрагент = Константы.Расш_СпецКонтрагентДляОбмена.Получить();
Если СпецКонтрагент.Пустая() Тогда
// Логика обработки ошибки или создания элемента
КонецЕсли;
Преимущества:
Если вариант с константами не подходит, можно использовать поиск элемента при старте работы системы или перед выполнением операции. Обычно ищут по Коду, Наименованию или специальному дополнительному реквизиту.
// Пример функции поиска или создания
Функция ПолучитьСпецЭлемент()
ИмяЭлемента = "СлужебныйПользователь";
Найдено = Справочники.Контрагенты.НайтиПоНаименованию(ИмяЭлемента);
Если Найдено.Пустая() Тогда
НовыйЭлемент = Справочники.Контрагенты.СоздатьЭлемент();
НовыйЭлемент.Наименование = ИмяЭлемента;
НовыйЭлемент.Записать();
Возврат НовыйЭлемент.Ссылка;
Иначе
Возврат Найдено;
КонецЕсли;
КонецФункции;
Недостатки:
Давайте резюмируем информацию по работе с предопределенными элементами в расширениях:
ИмяПредопределенныхДанных вручную.Используйте эти методы, чтобы ваши решения на базе расширений были стабильными и обновляемыми.