Почему автонумерация справочника в 1С идет через один номер и как это исправить?

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

При разработке или доработке справочников в платформе «1С:Предприятие» разработчики нередко сталкиваются с ситуацией, когда системная автонумерация начинает работать со странным шагом: каждый новый элемент получает код через один от предыдущего (например, 000000144, 000000146, 000000148). При этом в модулях объекта и подписках на события может не быть никакого явного кода генерации номера, а замер производительности показывает чистое выполнение стандартных механизмов записи. Разберем детально механику возникновения этой ошибки и выясним, как вернуть корректную последовательную нумерацию.

Механизм возникновения проблемы: почему код увеличивается на два

Чтобы понять суть сбоя, проанализируем, как платформа «1С:Предприятие» управляет последовательностями номеров. За генерацию кодов отвечает внутренний системный механизм — Менеджер автонумерации. Он выделяет номера из системного пула и кеширует их на сервере.

Шаг через единицу (+2 к каждому новому записанному элементу) возникает из-за двойного запроса номера за один цикл создания и сохранения объекта:

  1. Первый запрос номера: в форме объекта включено свойство Автонумерация. При интерактивном открытии окна создания нового элемента форма сразу обращается к менеджеру автонумерации и резервирует очередной номер (например, 000000145).
  2. Потеря первого номера: если реквизит кода на форме не связан напрямую с реквизитом данных объекта (например, поле формы не привязано к Объект.Код в управляемых формах или к Код в обычных формах) либо код программно очищается перед записью, то к моменту начала транзакции записи реквизит объекта остается пустым (Код = "").
  3. Второй запрос номера: при фиксации транзакции записи платформа видит, что у сохраняемого элемента код не заполнен, и автоматически запрашивает у менеджера автонумерации следующий свободный код. Менеджер выдает уже номер 000000146.
  4. «Сгорание» пропущенного кода: так как в свойствах конфигурации параметр РежимАвтонумерацииОбъектов по умолчанию имеет значение НеОсвобождатьАвтоматически, первый выданный номер (000000145) не возвращается обратно в пул и навсегда теряется. В результате каждый новый записанный элемент получает номер через один.

Способ 1. Отключение автонумерации в свойствах формы

Самое быстрое и правильное решение в описанной ситуации — отключить предварительное резервирование кода формой:

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

После отключения этого свойства номер не будет генерироваться заранее при открытии формы элемента. Платформа назначит код один-единственный раз — непосредственно в момент записи объекта в базу данных.

Способ 2. Проверка привязки данных элемента управления

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

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

Способ 3. Проверка программного обработчика установки кода

Еще одна распространенная причина перескакивания номеров — ошибка в обработчике события ПриУстановкеНовогоКода в модуле объекта справочника. Если разработчик программно вызывает метод генерации номера, но забывает отключить штатный механизм, платформа выполняет автонумерацию повторно.

Посмотрим на пример правильного оформления данного события:


Процедура ПриУстановкеНовогоКода(СтандартнаяОбработка, Префикс)
    
    // Если мы формируем код вручную или вызываем метод УстановитьНовыйКод:
    Префикс = "ОС-";
    
    // Если требуется полностью переопределить генерацию кода:
    // ЭтотОбъект.УстановитьНовыйКод(Префикс);
    // СтандартнаяОбработка = Ложь; // Обязательно отключаем штатный вызов!
    
КонецПроцедуры

Если строка СтандартнаяОбработка = Ложь; отсутствует при программном вызове метода УстановитьНовыйКод(), произойдет ровно такое же задвоение инкремента счетчика.

Способ 4. Сброс кеша автонумерации на сервере

Если после устранения причин нумерация продолжает идти со смещением или в последовательности образовались «дыры» из-за закешированных пулов, выполним сброс механизма нумерации. Для этого запустим процедуру обновления пространства номеров:

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

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

← На главную