Как правильно создать новый предопределенный элемент справочника без конфликта кодов при обновлении?

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

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

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

Почему возникает ошибка при обновлении и сбивается нумерация?

Выясним причину такого поведения платформы. При реструктуризации базы данных во время применения конфигурации платформа создает предопределенные элементы в транзакции на уровне СУБД. Если в метаданных конфигуратора новому предопределенному элементу назначен код, который уже занят пользовательским элементом в рабочей базе, платформа фиксирует нарушение уникальности. Транзакция обновления аварийно прерывается системной ошибкой: «Значение поля "Код" не уникально», и применение изменений блокируется.

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

Способ 1. Использование свойства «Обновление предопределенных данных» и привязка по имени

Рассмотрим наиболее гибкий и безопасный подход, который появился в платформе 8.3. Он позволяет полностью исключить создание записи на этапе реструктуризации СУБД и перенести привязку в пользовательский режим.

Разберем по шагам реализацию данного способа:

  1. В конфигураторе открываем свойства нужного справочника и находим свойство Обновление предопределенных данных.
  2. Устанавливаем для него значение Не обновлять автоматически. Это запрещает платформе автоматически создавать в базе данных записи для новых предопределенных элементов при реструктуризации.
  3. Создаем в ветке метаданных предопределенный элемент с требуемым именем, не акцентируя внимание на значении кода.
  4. Применяем изменения в рабочей базе. Так как автоматическое создание отключено, обновление проходит без коллизий уникальности.
  5. В режиме 1С:Предприятие создаем новый элемент справочника либо находим подходящий существующий. При создании нового элемента платформа выделит для него следующий свободный код в штатном режиме.
  6. Программно связываем элемент с предопределенным именем из метаданных, заполнив реквизит ИмяПредопределенныхДанных.

Посмотрим на пример программной привязки существующего или вновь созданного элемента:


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

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

Способ 2. Предварительная перенумерация конфликтующего элемента

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

Разберем последовательность действий:

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

Способ 3. Создание предопределенного элемента с пустым кодом

Рассмотрим вариант, применимый в справочниках, где для реквизита Код в метаданных не установлен признак «Запрет незаполненных значений».

  1. При создании предопределенного элемента в конфигураторе полностью очищаем поле Код, оставляя его пустым.
  2. Обновляем рабочую базу. Реструктуризация проходит успешно, так как пустой код не вызывает конфликта уникальности числовых последовательностей.
  3. После обновления запускаем обработчик обновления информационной базы или разовую обработку, где вызываем метод УстановитьНовыйКод() для только что созданного предопределенного элемента:

ПредопределеннаяСсылка = Справочники.Номенклатура.ОсновнаяУслуга;
ЭлементОбъект = ПредопределеннаяСсылка.ПолучитьОбъект();
Если ЭлементОбъект <> Неопределено И ПустаяСтрока(ЭлементОбъект.Код) Тогда
    ЭлементОбъект.УстановитьНовыйКод();
    ЭлементОбъект.Записать();
КонецЕсли;

Как восстановить счетчик автонумерации при сбое

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

  1. Исправить некорректный код проблемного элемента на правильный (в рамках стандартной разрядности).
  2. Вызвать процедуру пересчета счетчика платформы в глобальном контексте:

ОбновитьНумерациюОбъектов(Метаданные.Справочники.Номенклатура);

Данный метод анализирует текущие максимальные значения кодов в таблице базы данных и синхронизирует внутренний механизм автонумерации платформы с фактическими данными.

Альтернативное архитектурное решение: отказ от предопределенных элементов

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

  1. В метаданных создается константа с типом ссылки на справочник (например, Константы.ОсновнаяУслуга).
  2. В обработчике обновления конфигурации (например, при первом запуске новой версии) программно создается обычный элемент справочника с вызовом УстановитьНовыйКод().
  3. Полученная ссылка сохраняется в значение константы.
  4. В прикладном коде вместо обращения к предопределенному элементу через точку (Справочники.Номенклатура.ОсновнаяУслуга) используется чтение константы.

Такой подход полностью устраняет риск коллизий при реструктуризации базы данных на уровне СУБД и сохраняет предсказуемость механизма автонумерации.

← На главную