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

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

В процессе работы с программными продуктами «1С:Предприятие 8» пользователи и администраторы часто сталкиваются с неочевидным поведением системы при нумерации документов. Типичная ситуация: пользователь нажимает кнопку «Создать», открывается форма нового документа, и система автоматически показывает ему следующий по порядку номер (например, 000001). Если пользователь передумывает, закрывает форму без сохранения, а затем снова пытается создать документ, новый объект неожиданно получает номер 000002. Куда исчез первый номер? Почему система зарезервировала его и «потеряла»? Разберем подробно технические причины этого поведения и рассмотрим правильные варианты решения этой проблемы в современных реалиях разработки.

Причина поведения: Режим автонумерации объектов в платформе 1С

Для того чтобы понять, почему платформа ведет себя именно так, заглянем во внутреннее устройство системы. На самом верхнем уровне дерева метаданных в свойствах конфигурации существует важная настройка под названием «Режим автонумерации объектов». Этот параметр определяет, как именно СУБД и сервер приложений взаимодействуют с генератором номеров для документов и кодов справочников.

Данный параметр может принимать два значения:

  1. «Освобождать автоматически». Этот режим использовался по умолчанию в старых версиях платформы (например, в «1С:Предприятии 8.0»). При открытии новой формы система сразу же выделяет для нее очередной свободный номер. Если сеанс завершается без записи документа (пользователь закрыл форму, отменил создание), зарезервированный номер возвращается обратно в пул свободных номеров. При создании следующего документа система снова попытается выдать этот же номер.
  2. «Не освобождать автоматически». Этот режим стал основным стандартом, начиная с версии платформы «1С:Предприятие 8.1». При открытии формы нового документа система резервирует за текущим сеансом уникальный номер из пула. Даже если документ не будет записан и форма просто закроется, этот зарезервированный номер «сгорает». Платформа больше не предложит его автоматически, и следующий созданный документ гарантированно получит следующий по порядку номер.

Давайте проанализируем, почему разработчики платформы приняли решение отказаться от автоматического освобождения номеров и сделать режим «Не освобождать автоматически» основным.

Почему режим «Не освобождать автоматически» является основным?

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

Во-первых, это вызывает избыточные блокировки базы данных. Чтобы система точно знала, какие номера свободны, а какие освободились, ей приходится постоянно опрашивать таблицы базы данных и блокировать их при генерации каждого нового номера. При одновременной работе десятков и сотен пользователей это неизбежно приводит к эскалации блокировок, зависаниям интерфейса и ошибкам ожидания блокировок СУБД.

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

Режим «Не освобождать автоматически» решает эти проблемы. Он работает значительно быстрее в клиент-серверных базах данных, поскольку сервер приложений выдает номера из кэша и не выполняет постоянные ресурсоемкие проверки таблиц СУБД на наличие освободившихся номеров.

Как решить проблему пропусков в современных конфигурациях

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

Решение №1: Присвоение номера в момент записи (а не при открытии)

Это самый надежный и современный архитектурный подход, который применяется во всех типовых решениях «1С:Предприятия 8» (например, в «1С:Бухгалтерии 3.0», «1С:ERP» или «1С:Управлении торговлей 11»).

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

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


Процедура ПередЗаписью(Отказ, РежимЗаписи, РежимПроведения)
    
    Если ЭтоНовый() И Не ЗначениеЗаполнено(ЭтотОбъект.Номер) Тогда
        // Платформа автоматически сгенерирует номер непосредственно в момент транзакции записи
        ЭтотОбъект.УстановитьНовыйНомер();
    КонецЕсли;
    
КонецПроцедуры

Этот подход полностью устраняет проблему пустых номеров. Пользователь может открывать и закрывать сколько угодно экранных форм, номера при этом расходоваться не будут. Номер присвоится только в тот момент, когда документ гарантированно сохранится в базу данных.

Решение №2: Программный сброс кэша нумерации

Иногда пропуски номеров возникают из-за того, что в кэше сервера приложений «залипли» неиспользованные номера, и платформа продолжает отсчет со слишком большого значения. В таких случаях можно выполнить принудительное обновление кэша номеров для конкретного объекта метаданных.

Для этого используется встроенный метод платформы ОбновитьНумерациюОбъектов(). Мы можем запустить специальную обработку или выполнить этот код во внешнем соединении:


// Обновляем нумерацию для конкретного вида документа
ОбновитьНумерациюОбъектов(Метаданные.Документы.РеализацияТоваровУслуг);

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

Решение №3: Ручное исправление сбитой нумерации

Часто проблема с автонумерацией возникает по вине самих пользователей. Если кто-то вручную отредактировал номер документа (например, вместо «0000-000025» написал «0000-00025» или случайно стер лидирующие нули, добавил лишние буквы), платформа теряет способность правильно распознавать префиксы и длину номера. В результате автонумерация сбивается, и номера начинают генерироваться некорректно или пропускаться.

Давайте разберем по шагам, как исправить сбившуюся нумерацию вручную:

  1. Проанализируем список последних созданных документов нужного вида. Найдем документ, начиная с которого сбилась последовательность или изменился формат номера.
  2. Временно разрешим редактирование номера в форме этого документа (в типовых конфигурациях для этого обычно есть специальное действие в меню «Еще» — «Редактировать номер»).
  3. Приведем номер в строгое соответствие с установленным в системе шаблоном. Очень важно соблюдать длину номера, количество ведущих нулей и правильность префиксов (например, «РТ-000015» вместо «РТ-15»).
  4. Запишем документ.
  5. При необходимости выполним метод ОбновитьНумерациюОбъектов() для данного документа, чтобы сбросить кэш.

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

← На главную