В процессе эксплуатации систем на базе 1С:Предприятие часто возникает ситуация, когда стандартной разрядности кода справочника перестает хватать. Например, если в справочнике Контрагенты исторически использовались пятизначные номера, а бизнес-процессы потребовали перехода на шестизначные или более длинные последовательности. Однако простая попытка создать элемент с новым номером часто приводит к ошибке: "Код не уникальный".
В этой статье мы подробно разберем, почему 1С сопротивляется смене разрядности, как работает механизм автонумерации и какие способы решения проблемы существуют, чтобы не нарушить целостность данных.
Разберем ситуацию: у вас есть текстовый код длиной 9 символов. Текущие коды выглядят как "99998", "99999". Вы хотите начать нумерацию "000001", "000002". Вы создаете элемент вручную, но при попытке автоматического подбора следующего номера система снова предлагает "99999" и выдает ошибку. Чтобы понять причину, проанализируем алгоритм поиска нового номера платформой 1С.
Для текстовых полей 1С использует лексикографическую сортировку (строковую). В этой логике строка "99999" всегда будет "больше", чем строка "000001", независимо от того, сколько значащих цифр в них содержится. Когда платформа ищет "максимальный" существующий код, она находит "99999". Следующим логическим шагом для системы является попытка прибавить единицу к этому числу. Если длина поля позволяет (в нашем примере 9 символов), система пытается сформировать код "100000".
Проблема кроется в том, что если в базе уже есть элементы, которые сбивают эту последовательность, или если система "застряла" на старом кэшированном значении, автоматика будет пытаться выдать уже существующий номер, игнорируя ваши новые "нули" в начале кода.
Это наиболее элегантный способ, который позволяет не трогать исторические данные. Использование префикса фактически создает новую "ветку" нумерации, которая не пересекается со старой.
Рассмотрим, как это работает. Если мы добавим префикс (например, код узла распределенной базы данных или просто буквенный префикс "УЗ-"), платформа начнет искать максимальный код только среди тех элементов, которые начинаются на этот префикс. Проанализируем шаги реализации:
УЗ-.УЗ-000001.УЗ-000002, УЗ-000003 и так далее.Этот метод хорош тем, что старые коды (без префиксов) больше не участвуют в расчете автоматического номера для новой серии. Длина оставшейся части кода после префикса (в нашем случае 6 знаков из 9) будет заполняться ведущими нулями автоматически, что обеспечит правильную сортировку в будущем.
Если использование префиксов по каким-то причинам невозможно, нам придется "научить" систему правильно определять максимум. Для этого необходимо, чтобы все коды имели одинаковую длину и были дополнены ведущими нулями.
Рассмотрим ситуацию: у нас есть код "99999". Чтобы система корректно перешла к шестизначным числам, этот код должен превратиться в "099999" (если мы ориентируемся на 6 знаков) или в "000099999" (на всю длину поля 9 знаков). Разберем шаги:
Важно: При этом способе меняются старые коды. Если ваши контрагенты или сотрудники привыкли искать элементы по старым коротким номерам, это может вызвать временные неудобства.
Начиная с версии платформы 8.3, 1С кэширует номера на стороне сервера для повышения производительности. Это означает, что даже если вы вручную переименовали все элементы, система может "помнить" старый максимум в своем кэше.
Чтобы сбросить кэш и заставить платформу заново проанализировать таблицу базы данных, необходимо выполнить команду ОбновитьНумерациюОбъектов(). Рассмотрим пример кода, который можно запустить во внешней обработке:
// Обновление нумерации для справочника Контрагенты
МетаданныеСправочника = Метаданные.Справочники.Контрагенты;
ОбновитьНумерациюОбъектов(МетаданныеСправочника);
Сообщить("Нумерация справочника успешно обновлена!");
Этот метод очищает закэшированные номера и заставляет систему честно найти в базе данных строку, которая является максимальной согласно правилам сортировки.
Если вы понимаете, что физической длины поля (например, 9 символов) вам в будущем не хватит, можно увеличить длину кода в метаданных справочника. Проанализируем последствия этого действия:
Контрагенты.Посмотрим на ситуацию со стороны базы данных: при увеличении длины поля старые записи остаются короткими строками. При сравнении строк "99999" и "000000000000001" первая все равно будет больше. Поэтому увеличение длины — это лишь подготовительный этап к использованию префиксов или ведущих нулей.
Проанализировав все способы, мы рекомендуем придерживаться следующего алгоритма действий при необходимости увеличить разрядность кода:
ОбновитьНумерациюОбъектов(), чтобы очистить серверный кэш номеров.Соблюдение этих правил позволит вам избежать ошибок уникальности и обеспечит стабильную работу механизма автоматического присвоения номеров в ваших конфигурациях.