При разработке и выпуске обновлений конфигураций 1С разработчики часто сталкиваются с задачей добавления нового предопределенного элемента в существующий справочник. На этапе разработки в тестовой базе конфигуратор автоматически подставляет очередной код (например, 000123). Однако в рабочей информационной базе пользователи продолжают непрерывно вводить новые элементы, и к моменту применения обновления этот код с высокой вероятностью оказывается уже занят.
Если же разработчик решает перестраховаться и задает заведомо большой код со смещением (например, 100123), возникает другая неприятность: механизм автонумерации платформы начинает отсчитывать все последующие пользовательские коды от этого завышенного значения. Разберем детально, почему так происходит и как корректно внедрить новый предопределенный элемент без ошибок реструктуризации и сбоев нумерации.
Выясним причину такого поведения платформы. При реструктуризации базы данных во время применения конфигурации платформа создает предопределенные элементы в транзакции на уровне СУБД. Если в метаданных конфигуратора новому предопределенному элементу назначен код, который уже занят пользовательским элементом в рабочей базе, платформа фиксирует нарушение уникальности. Транзакция обновления аварийно прерывается системной ошибкой: «Значение поля "Код" не уникально», и применение изменений блокируется.
Проанализируем также механизм автонумерации: платформа вычисляет следующий код как лексикографический максимум среди существующих кодов справочника. Если вручную задать элементу код 100123 при текущем диапазоне 000123, счетчик автоматически переключится на новый максимум. В результате следующий созданный пользователем элемент получит номер 100124, что нарушит принятую разрядность и порядок нумерации в базе данных.
Рассмотрим наиболее гибкий и безопасный подход, который появился в платформе 8.3. Он позволяет полностью исключить создание записи на этапе реструктуризации СУБД и перенести привязку в пользовательский режим.
Разберем по шагам реализацию данного способа:
Не обновлять автоматически. Это запрещает платформе автоматически создавать в базе данных записи для новых предопределенных элементов при реструктуризации.1С:Предприятие создаем новый элемент справочника либо находим подходящий существующий. При создании нового элемента платформа выделит для него следующий свободный код в штатном режиме.ИмяПредопределенныхДанных.Посмотрим на пример программной привязки существующего или вновь созданного элемента:
ЭлементСправочника = Справочники.Номенклатура.СоздатьЭлемент();
ЭлементСправочника.Наименование = "Основная услуга";
ЭлементСправочника.УстановитьНовыйКод();
ЭлементСправочника.ИмяПредопределенныхДанных = "ОсновнаяУслуга";
ЭлементСправочника.Записать();
Важно помнить: платформа строго контролирует уникальность свойства ИмяПредопределенныхДанных. Нельзя присвоить одно и то же имя двум разным элементам. Если элемент с заполненным именем предопределенного объекта помечен на удаление, стандартная процедура удаления помеченных объектов не сможет его удалить, пока имя предопределенных данных не будет очищено.
Если в конфигурации оставлен стандартный режим обновления предопределенных данных, предотвратить ошибку реструктуризации можно административным путем перед накатыванием обновления на рабочую базу.
Разберем последовательность действий:
1С:Предприятие и находим элемент, который уже занимает этот код.Рассмотрим вариант, применимый в справочниках, где для реквизита Код в метаданных не установлен признак «Запрет незаполненных значений».
УстановитьНовыйКод() для только что созданного предопределенного элемента:
ПредопределеннаяСсылка = Справочники.Номенклатура.ОсновнаяУслуга;
ЭлементОбъект = ПредопределеннаяСсылка.ПолучитьОбъект();
Если ЭлементОбъект <> Неопределено И ПустаяСтрока(ЭлементОбъект.Код) Тогда
ЭлементОбъект.УстановитьНовыйКод();
ЭлементОбъект.Записать();
КонецЕсли;
Проанализируем ситуацию, когда код со смещением (например, 100123) все же попал в базу и нумерация начала присваивать некорректные номера. Чтобы вернуть нумератор к правильной последовательности, необходимо:
ОбновитьНумерациюОбъектов(Метаданные.Справочники.Номенклатура);
Данный метод анализирует текущие максимальные значения кодов в таблице базы данных и синхронизирует внутренний механизм автонумерации платформы с фактическими данными.
Во многих современных типовых конфигурациях разработчики отказываются от жестко заданных предопределенных элементов метаданных в пользу констант или настроечных регистров сведений. Разберем, как это работает:
Константы.ОсновнаяУслуга).УстановитьНовыйКод().Справочники.Номенклатура.ОсновнаяУслуга) используется чтение константы.Такой подход полностью устраняет риск коллизий при реструктуризации базы данных на уровне СУБД и сохраняет предсказуемость механизма автонумерации.