Почему метод УстановитьНовыйНомер() в 1С вдруг присваивает странные текстовые номера вместо числовых?

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

Каждый разработчик и администратор баз данных «1С:Предприятие» рано или поздно сталкивается с загадочным поведением автонумерации. Представьте ситуацию: весь год документы создавались последовательно, с аккуратными числовыми номерами вроде 000008633 и 000008634. И вдруг система генерирует номер ООО НПП , после чего как ни в чем не бывало продолжает нумерацию с 000008636. Первая реакция — это недоумение и подозрение на критический сбой кэша платформы.

В этой статье мы подробно разберем, почему возникает подобное поведение, как работает механизм автонумерации в 1С на низком уровне, и как защитить систему от подобных инцидентов.

Суть проблемы: почему сбивается автонумерация?

Проанализируем ситуацию, описанную автором темы. В процессе работы обработки последовательно создавались документы. Номера присваивались следующим образом:

  1. 000008633 (успешно создан)
  2. 000008634 (успешно создан)
  3. ООО НПП (внезапное текстовое значение вместо ожидаемого 000008635)
  4. 000008636 (следующий по порядку корректный номер)

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

Но почему тогда система не выдала ошибку уникальности и продолжила нумерацию дальше с корректного числа, пропустив ровно один шаг? Чтобы ответить на этот вопрос, нам нужно заглянуть «под капот» платформы «1С:Предприятие 8».

Как устроен Менеджер автонумерации на низком уровне

Начиная с версии платформы 8.1, в 1С встроен специальный Менеджер автонумерации. Он призван решить проблему жестких транзакционных блокировок в СУБД.

В старых версиях (например, в 1С 8.0) для получения нового номера платформа выполняла транзакционный запрос к таблице базы данных (условно выбирая максимальный номер через MAX), полностью блокируя таблицу. При высокой интенсивности работы десятков пользователей это гарантированно приводило к частым взаимоблокировкам (Deadlocks).

Современный Менеджер автонумерации работает иначе:

Режимы автонумерации и механизм «сгорания» номеров

В свойствах любого объекта конфигурации (документа или справочника) существует важнейшая настройка — Режим автонумерации объектов. Рассмотрим два доступных режима:

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

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

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

  1. При записи очередного документа система запрашивает новый номер. Кэш выдает значение 000008635. Этот номер резервируется в оперативной памяти сервера приложений.
  2. В этот момент пользователь (или некорректно написанный код обработки) вручную перезаписывает поле номера текстовым значением ООО НПП . Документ успешно записывается в базу данных с этим текстом.
  3. Для системы зарезервированное значение 000008635 считается израсходованным. Оно навсегда уходит из пула автонумерации.
  4. При создании следующего документа метод УстановитьНовыйНомер() снова обращается к кэшу сервера приложений. Кэш выдает следующий свободный по порядку номер — 000008636.

Алгоритм парсинга номеров платформой 1С

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

Как быстро найти виновника? Инструменты расследования

Если вы столкнулись с подобной проблемой, не спешите грешить на динамическое обновление или системные ошибки. Проведите детальное расследование.

Способ 1. Использование Журнала регистрации

Перейдите в Журнал регистрации и установите отбор по метаданным проблемного документа. Найдите событие записи документа с некорректным номером. Вы увидите точное время транзакции и имя пользователя, под сеансом которого было выполнено это действие.

Способ 2. Использование Версионирования объектов

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

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

Роль и особенности метода ОбновитьНумерациюОбъектов()

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

Этот метод заставляет сервер приложений 1С принудительно обратиться к физическим таблицам СУБД, выполнить поиск максимального номера с учетом префиксов и переинициализировать (обновить) кэш менеджера автонумерации актуальными данными из базы данных.

Вызывать метод можно для конкретного типа объектов:

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

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

Как разработчику защитить автонумерацию от вмешательства пользователей

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

Решение 1. Ограничение прав на редактирование номера на уровне интерфейса

В управляемых или обычных формах документов свойство поля ввода номера «Доступность» или «ТолькоПросмотр» следует устанавливать в значение Истина. Изменение номера должно быть доступно только администраторам системы через специальную роль или по кнопке «Разрешить редактирование номера».

Решение 2. Программный контроль при установке нового номера

Используйте механизм подписок на события или обработчик события ПриУстановкеНовогоНомера в модуле объекта для жесткого контроля формата номера или программной подстановки префиксов:


Процедура ПриУстановкеНовогоНомера(СтандартнаяОбработка, Префикс)
    
    // Автоматически добавляем префикс организации или подразделения
    Префикс = Префикс + "ОП-"; 
    
КонецПроцедуры

Используя эти несложные правила и понимая внутренние механизмы платформы «1С:Предприятие 8», вы навсегда избавитесь от проблем с автонумерацией и сможете быстро локализовать любые некорректные действия пользователей.

← На главную