При доработке типовых конфигураций (например, 1С:ЗУП 3.1, 1С:ERP, 1С:КА) разработчики нередко сталкиваются с ситуацией: в конфигураторе в справочник добавлен новый предопределенный элемент, конфигурация базы данных успешно обновлена, однако в режиме «1С:Предприятие» новый элемент отсутствует в форме списка, а прямые запросы к таблице базы данных возвращают пустой результат. При этом в программном коде обращение к менеджеру справочника вида Справочники.ПоказателиРасчетаЗарплаты.ИмяЭлемента компилируется без синтаксических ошибок, но при попытке получить данные или использовать ссылку в расчетах система выдает ошибку: Предопределенный элемент отсутствует в данных.
Разберем подробно механизм работы платформы «1С:Предприятие 8.3» с предопределенными данными, выясним причины такого поведения и рассмотрим все доступные способы исправления ситуации.
Проанализируем архитектуру хранения предопределенных элементов. В платформе 8.3 предопределенные элементы разделены на два независимых уровня:
Справочники.ПоказателиРасчетаЗарплаты.A_1111 успешно проходит проверку компилятора метаданных — для платформы это валидная ссылка.ИмяПредопределенныхДанных.Если на уровне метаданных элемент создан, но в физическую таблицу СУБД запись не добавлена, возникает рассинхронизация. Рассмотрим, как это проявляется в запросах. Если мы выполним следующий запрос:
ВЫБРАТЬ
Показатели.Ссылка,
Показатели.Предопределенный,
Показатели.ИмяПредопределенныхДанных,
Показатели.Представление
ИЗ
Справочник.ПоказателиРасчетаЗарплаты КАК Показатели
Запрос не вернет наш новый элемент, поскольку в таблице базы данных физическая запись попросту отсутствует. При попытке разыменовать ссылку или обратиться к свойствам объекта система выдает исключение Предопределенный элемент отсутствует в данных.
Выясним, почему платформа не создает физическую запись автоматически при обновлении конфигурации базы данных (по нажатию F7).
В типовых конфигурациях, построенных на базе «Библиотеки стандартных подсистем» (БСП), для ускорения реструктуризации базы данных у корня конфигурации свойство Обновление предопределенных данных установлено в значение Не обновлять автоматически. Если у конкретного справочника в свойствах на вкладке «Прочее» значение параметра установлено как Авто, объект наследует общее поведение конфигурации, и автоматическое создание физических строк в СУБД блокируется.
Рассмотрим основные способы решения этой проблемы.
Самый быстрый и безопасный способ создать недостающие записи в рабочей или тестовой базе без изменения общих настроек конфигурации — вызвать платформенный метод менеджера справочника. Данный метод выполняет сканирование метаданных и физически создает недостающие строки в базе данных.
Выполним на сервере (через внешнюю обработку или консоль кода) следующую команду:
Справочники.ПоказателиРасчетаЗарплаты.ОбновитьПредопределенныеДанные();
После выполнения этой строки платформа мгновенно добавит все недостающие предопределенные элементы в таблицу СУБД, заполнит системный реквизит ИмяПредопределенныхДанных, и элемент сразу станет доступен как в пользовательском интерфейсе, так и в запросах.
Если мы хотим, чтобы для конкретного справочника новые предопределенные элементы всегда создавались автоматически при обновлении конфигурации базы данных, изменим параметры метаданных объекта. Разберем порядок действий по шагам:
ПоказателиРасчетаЗарплаты).При применении изменений платформа выполнит реструктуризацию таблицы и автоматически создаст физические записи для всех объявленных предопределенных элементов.
Рассмотрим ситуацию, когда в пользовательском режиме элемент с нужными параметрами уже был создан вручную, и мы хотим связать его с предопределенным элементом из дерева конфигурации, чтобы не плодить дубли.
Для этого необходимо программно заполнить стандартный реквизит ИмяПредопределенныхДанных у существующего элемента базы данных:
// Получаем ссылку на существующий элемент справочника
ОбъектСправочника = ВыбраннаяСсылка.ПолучитьОбъект();
// Имя должно в точности совпадать с именем в дереве метаданных конфигуратора
ОбъектСправочника.ИмяПредопределенныхДанных = "A_1111";
// Записываем объект для фиксации связи
ОбъектСправочника.Записать();
После записи объект приобретает признак предопределенного (в интерфейсе появляется значок с точкой), и к нему можно будет обращаться через точку от менеджера справочника.
Проанализируем дополнительные технические правила, которые необходимо учитывать при разработке:
ИмяПредопределенныхДанных должно быть строго уникальным в пределах одной таблицы. Попытка назначить одно и то же имя двум разным элементам приведет к ошибке нарушения уникальности.Объект.ИмяПредопределенныхДанных = "" и выполнить запись объекта.