При оформлении первичных документов в системе 1С:ERP пользователи и разработчики нередко сталкиваются с неприятной ситуацией: при попытке записать или провести новый документ программа выдает ошибку о том, что значение поля Номер не уникально. При этом автоматически подставляемый номер уже занят документом, созданным некоторое время назад, а при последующих попытках платформа лишь прибавляет к нему единицу, снова натыкаясь на занятые позиции. Разберем детально, из-за чего возникает данный сбой, как выяснить первопричину и какими методами восстановить штатную работу механизма автонумерации.
Для понимания корня проблемы проанализируем, как платформа 1С формирует и проверяет уникальность номеров. По умолчанию система выполняет поиск максимального значения MAX(Номер) среди документов заданного вида в пределах установленной периодичности (как правило, в пределах календарного года) и с учетом заданного префикса. Затем к полученному числу прибавляется единица. Сбой этого механизма происходит по ряду типичных причин:
Прежде чем исправлять нумерацию, необходимо выяснить, какой именно объект мешает записи и кто внес изменения. Разберем, как провести аудит:
ПометкаУдаления:
ВЫБРАТЬ
Док.Ссылка КАК Ссылка,
Док.Дата КАК Дата,
Док.Номер КАК Номер,
Док.ПометкаУдаления КАК ПометкаУдаления
ИЗ
Документ.ПриобретениеТоваровУслуг КАК Док
ГДЕ
Док.Номер ПОДОБНО "%000125%"
Если поиск выявил помеченный на удаление документ, дублирующий номер, решением будет окончательное удаление помеченных объектов либо ручное изменение номера у удаляемого документа, чтобы освободить последовательность.
Если документы проверены, явных дублей нет, но сервер 1С упорно пытается назначить уже существующий старый номер, проанализируем состояние счетчика автонумерации. Для сброса внутренних закэшированных счетчиков и пересчета максимального номера платформой предусмотрен штатный метод ОбновитьНумерациюОбъектов().
Рекомендуется вызывать этот метод не для всей информационной базы (чтобы не создавать избыточную нагрузку на сервер), а точечно для проблемного объекта метаданных. Создадим внешнюю обработку или выполним код во внешней обработке с контекстом сервера:
// Сброс и актуализация счетчика для конкретного вида документов
МетаданныеДокумента = Метаданные.Документы.ПриобретениеТоваровУслуг;
ОбновитьНумерациюОбъектов(МетаданныеДокумента);
Метод выполняет перечитывание актуального максимального номера непосредственно из таблиц базы данных и сбрасывает закэшированные значения в оперативной памяти кластера 1С.
В ситуациях, когда сбой произошел в рамках единичной сессии, перед записью конкретного нового объекта можно принудительно заставить систему пересчитать номер с учетом префикса информационной базы и организации:
// Принудительное назначение нового номера перед записью объекта
ДокументОбъект = СсылкаНаДокумент.ПолучитьОбъект();
ПрефиксНомера = "ФР-"; // Задаем актуальный префикс
ДокументОбъект.УстановитьНовыйНомер(ПрефиксНомера);
ДокументОбъект.Записать();
Если нумерация сбилась системно (например, кто-то создал документ с номером вроде 99999, после чего платформа не может корректно вычислить следующий номер или уперлась в границу разрядности), выполним следующие действия:
ОбновитьНумерациюОбъектов() для данного типа метаданных.Таким образом, сочетание проверки скрытых и помеченных на удаление записей с точечным вызовом ОбновитьНумерациюОбъектов() позволяет быстро и надежно ликвидировать конфликт уникальности номеров без риска повреждения данных.