Каждый разработчик и администратор систем на платформе «1С:Предприятие 8» рано или поздно сталкивается со странным поведением автонумерации. Типичный сценарий: при создании нового документа (например, РеализацияТоваровУслуг) система вместо инкрементирования (увеличения на единицу) последнего номера упорно предлагает один и тот же код — например, "0999". Более того, при записи документа номер успешно дублируется, не вызывая конфликтов уникальности, либо система выдает ошибку о нарушении уникальности, но следующий по порядку номер все равно не присваивает.
В этой статье мы подробно разберем, почему возникает подобный сбой, как работает внутренний механизм автонумерации платформы «1С:Предприятие», и по шагам пройдем процесс диагностики и исправления этой ошибки.
Для того чтобы эффективно устранить сбой, нам необходимо понять, как платформа генерирует новый номер. Процесс состоит из нескольких важных этапов:
Префикс + НовыйЧисловойНомер. При этом обязательно используются лидирующие нули для сохранения фиксированной длины номера (например, 11 символов).rphost) кэширует диапазон номеров в оперативной памяти.Рассмотрим ситуацию, описанную в теме. Длина номера документа составляет 11 символов, тип номера — строка. При создании нового документа по определенной организации система постоянно выдает номер "0999 " (четыре цифры и семь пробелов на конце).
Проанализируем эту ситуацию по шагам:
"0999". Так как длина номера в метаданных зафиксирована (11 символов), платформа автоматически дополнила строку пробелами справа. Получился номер "0999 "."0999 " справа налево. Самым правым символом оказывается пробел. Пробел — это не цифра. Алгоритм выделения числовой части мгновенно останавливается на первом шаге, так и не дойдя до цифр "0999"."0999 " целиком является текстовым префиксом. Следовательно, при попытке увеличить номер на единицу увеличивать нечего. Платформа просто подставляет этот псевдо-префикс "0999 " в качестве нового номера. И этот процесс повторяется бесконечно.Для решения проблемы нам потребуется выполнить комплекс действий: найти некорректные документы в базе данных, исправить их номера и очистить кэш сервера 1С.
Обычный просмотр списка документов в интерфейсе может не показать проблему, так как пробелы в конце строк визуально незаметны. Нам потребуется написать простой запрос в консоли запросов или выполнить код для поиска документов, длина номеров которых без учета концевых пробелов отличается от нормальной, либо в которых отсутствуют лидирующие нули.
Выполним следующий запрос в консоли для поиска некорректных номеров за текущий год:
ВЫБРАТЬ
Реализация.Ссылка КАК Документ,
Реализация.Номер КАК Номер,
ДЛИНАСТРОКИ(Реализация.Номер) КАК ДлинаНомера
ИЗ
Документ.РеализацияТоваровУслуг КАК Реализация
ГДЕ
Реализация.Дата МЕЖДУ &НачалоГода И &КонецГода
И (ПОДСТРОКА(Реализация.Номер, 11, 1) = " " ИЛИ Реализация.Номер ПОДОБНО "% ")
Этот запрос вернет все документы, у которых на конце номера присутствует пробел. Именно эти документы ломают алгоритм автонумерации.
После того как проблемные документы найдены, их номера необходимо привести к каноническому виду: убрать пробелы справа и добавить лидирующие нули слева, чтобы общая длина строки строго соответствовала длине номера в конфигурации (в нашем случае — 11 символов).
Например, номер "0999 " должен превратиться в "00000000999" (или содержать префикс организации, например "ОБ000000999").
Для исправления можно воспользоваться следующей обработкой (выполнить в контексте внешнего отчета или обработки):
Выборка = Документы.РеализацияТоваровУслуг.Выбрать(НачалоГода(ТекущаяДата()), КонецГода(ТекущаяДата()));
Пока Выборка.Следующий() Цикл
ТекущийНомер = Выборка.Номер;
// Очищаем пробелы справа и слева
ЧистыйНомер = СокрЛП(ТекущийНомер);
// Если длина изменилась (были пробелы), исправляем номер
Если ДлинаСтроки(ЧистыйНомер) < ДлинаСтроки(ТекущийНомер) Тогда
ОбъектДокумента = Выборка.ПолучитьОбъект();
// Дополняем лидирующими нулями до 11 символов
НовыйНомер = ЧистыйНомер;
Пока ДлинаСтроки(НовыйНомер) < 11 Цикл
НовыйНомер = "0" + НовыйНомер;
КонецЦикла;
ОбъектДокумента.Номер = НовыйНомер;
ОбъектДокумента.ОбменДанными.Загрузка = Истина; // Чтобы обойти лишние проверки при записи
ОбъектДокумента.Записать();
Сообщить("Документ " + Выборка + " успешно переименован с " + ТекущийНомер + " на " + НовыйНомер);
КонецЕсли;
КонецЦикла;
Важное примечание: Настоятельно рекомендуем установить префиксы для всех организаций в справочнике Организации. Это позволит изолировать нумерацию документов разных юридических лиц друг от друга и избежать подобных коллизий в будущем.
Даже если мы полностью исправили все номера в базе данных, новые документы могут по-прежнему создаваться со старым ошибочным номером "0999". Это происходит потому, что сервер приложений 1С хранит этот номер в оперативной памяти (кэше рабочего процесса).
Чтобы заставить сервер пересчитать автонумерацию заново на основе исправленных данных в СУБД, у нас есть два пути:
Вариант А. Программное обновление нумерации (рекомендуемый способ)
Этот способ хорош тем, что не требует остановки работы пользователей и перезапуска служб сервера. Нам достаточно запустить встроенный метод платформы ОбновитьНумерациюОбъектов(). Выполнить данный код можно в консоли кода или в простой внешней обработке:
// Обновляем нумерацию для конкретного типа документов
ОбновитьНумерациюОбъектов(Метаданные.Документы.РеализацияТоваровУслуг);
Сообщить("Кэш автонумерации для документов Реализация товаров и услуг успешно сброшен!");
Вариант Б. Перезапуск службы сервера 1С
Если программный метод по какой-то причине недоступен, можно перезапустить службу сервера «1С:Предприятие» (или перезагрузить рабочие процессы rphost в консоли администрирования кластера). При перезапуске процесса кэш оперативной памяти очистится, и при создании следующего документа система выполнит запрос к СУБД для поиска актуального максимального номера.
Чтобы проблема с зависанием номеров не повторялась в будущем, рекомендуем внедрить на проекте следующие правила:
ТолькоПросмотр = Истина для обычных пользователей. Изменять номера вручную должны иметь право только администраторы системы.ПриУстановкеНовогоНомера) корректно отрабатывает заполнение префиксов. Префикс гарантирует разделение пространств нумерации и предотвращает наложение диапазонов.Применяя эти несложные правила и понимая внутреннюю логику работы платформы 1С, вы сможете оперативно решать любые проблемы, связанные со сбоями нумерации объектов в вашей информационной базе.