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

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

В процессе сопровождения и разработки конфигураций на платформе 1С разработчики нередко сталкиваются с ситуацией, когда в журнале документов обнаруживаются пропуски («дыры») в номерах. Проанализируем, приводит ли программный вызов создания нового документа к потере номеров, почему многократное использование метода УстановитьНовыйНомер порождает разрывы в цепочке и как правильно организовать непрерывную нумерацию.

Как работает автонумератор платформы при вызове метода Новый

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

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

Влияние метода УстановитьНовыйНомер в рамках одного объекта

Рассмотрим ситуацию, когда в программном коде или обработке несколько раз для одного и того же объекта вызывается метод УстановитьНовыйНомер().

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

Посмотрим на пример некорректного кода:


Док = СоздатьОбъект("Документ.Перемещение");
Док.Новый();
Док.УстановитьНовыйНомер(); // Получен номер, например, "00000005"
// Какой-то промежуточный алгоритм или повторный вызов функции инициализации
Док.УстановитьНовыйНомер(); // Номер стал "00000006"
Док.Записать(); // В базе зафиксирован номер 6, а номер 5 остался неиспользованным

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

Пропуски номеров при одновременной работе пользователей

Проанализируем типичный многопользовательский сценарий, при котором визуально пропадают номера:

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

В результате в базе данных зафиксирован номер 000005, тогда как номер 000004 не был сохранен никем. Так как автонумератор платформы ищет только максимальный записанный номер и прибавляет к нему единицу, номер 000004 автоматически платформой повторно предложен не будет, и в журнале образуется пропуск.

Дополнительные причины сбоев в последовательности номеров

Выясним, какие еще факторы влияют на нарушение последовательности нумерации:

  1. Смешение разрядности и текстовая природа номеров. Номер документа хранится в виде строки. Сравнение номеров происходит по правилам лексикографической сортировки. Если пользователь ввел номер без лидирующих нулей (например, «1» вместо «00000001») или случайно указал завышенное значение (например, «999999»), автонумератор посчитает его максимальным, что сломает порядок выдачи номеров.
  2. Изменение даты документа. Если периодичность нумерации настроена «В пределах года», а пользователь создал документ текущей датой и затем изменил дату на прошлый год, сформированный номер останется прежним, что создаст пропуск в текущем периоде и потенциальный дубль в прошлом.
  3. Смена префиксов. Если префикс назначается программно при выборе организации или склада уже после того, как номер был сформирован, старый номер освобождается, но в контексте отчетов может выглядеть как утерянный.
  4. Пакетное или непосредственное удаление. Физическое удаление ранее проведенных документов из базы оставляет невосполнимые разрывы в цепочке.

Рекомендации по организации непрерывной нумерации

Для предотвращения пропусков и стабилизации автонумерации применим следующие решения:

  1. Присвоение номера непосредственно перед записью. Для документов с жесткими требованиями к отсутствию пропусков перенесем процедуру назначения номера в предопределенное событие перед записью объекта. В таком случае номер генерируется ровно в момент сохранения документа в транзакции.
  2. Блокировка ручного ввода номеров. Отключим доступность поля номера на экранных формах для интерактивного редактирования пользователями. Это исключит появление номеров без лидирующих нулей и ошибок ввода разрядности.
  3. Регулярный контроль и групповая перенумерация. Проверим информационную базу на наличие документов с нарушенным форматом номера и при необходимости выполним сервисную перенумерацию за закрытый отчетный период.
  4. Использование выделенного нумератора. При строгих законодательных требованиях к непрерывности (кассовые ордера, счета-фактуры) реализуем программный счетчик номеров через отдельный объект учета с блокировкой на время получения следующего значения.
← На главную