Ситуация, когда при попытке записать или провести документ система выдает сообщение «Значение поля Номер не уникально», является одной из самых неприятных для администраторов и программистов 1С. Особенно остро проблема проявляется в клиент-серверном варианте работы, когда ошибка носит «плавающий» характер: она может исчезать после перезапуска сервера и внезапно появляться снова через несколько часов или дней. В этой статье мы подробно разберем причины такого поведения платформы и выработаем комплексный алгоритм решения проблемы.
Для начала проанализируем ситуацию: почему перезапуск службы Агент сервера 1С:Предприятия временно помогает? Дело в том, что начиная с версии платформы 8.2, в целях оптимизации производительности, сервер 1С использует механизм кэширования номеров. Чтобы не обращаться к базе данных за каждым новым номером, сервер «бронирует» для каждой активной сессии (или рабочего процесса) диапазон номеров (обычно по 10 штук).
Если в системе происходит аварийное завершение сеанса, сбой транзакции или некорректная работа кода в расширении, этот забронированный «хвост» номеров может остаться в памяти сервера как свободный, в то время как в самой базе данных номер уже может быть занят другим пользователем. При попытке выдать следующий номер из кэша сервер натыкается на дубль, существующий в таблицах SQL, и выдает ошибку уникальности.
Первым делом рассмотрим стандартный программный способ, который должен заставить систему пересчитать последний использованный номер в базе данных. Для этого в платформе 1С существует метод ОбновитьНумерациюОбъектов. Проанализируем, как его правильно применить.
Мы можем создать внешнюю обработку и выполнить в ней следующий код для конкретных типов документов (например, для реализации и поступления товаров):
ВыборкаМетаданных = Метаданные.Документы;
Для Каждого ОбъектМетаданных Из ВыборкаМетаданных Цикл
ОбновитьНумерациюОбъектов(ОбъектМетаданных);
КонецЦикла;
Этот метод принудительно сбрасывает внутренний счетчик сервера и заставляет его выполнить запрос к СУБД для поиска максимального номера. Однако, как показывает практика, если проблема в «зависшем» кэше конкретного рабочего процесса rphost, этот метод может не сработать мгновенно без перезапуска процесса.
Выясним причину сбоя счетчика через анализ данных. Часто ошибка возникает из-за того, что кто-то из пользователей вручную изменил номер документа, добавив в него лишний символ или изменив длину. Рассмотрим по шагам, как выявить проблему:
BT000656 появился BT999999 или BT00065Z), значит, автонумерация «уперлась» в этот предел.Рассмотрим более глубокий уровень анализа — взаимодействие с MS SQL Server. Если у вас развернуто несколько кластеров 1С или есть тестовые базы, возможна ситуация, когда тестовая база ошибочно подключена к рабочей СУБД. В этом случае два разных сервера 1С пытаются управлять нумерацией в одной и той же таблице, не зная о кэше друг друга.
Мы рекомендуем выполнить следующие действия в консоли SQL Management Studio:
Если стандартное обновление нумерации не помогает, разберем метод ручного сдвига счетчика. Суть заключается в том, чтобы найти документ, на котором «спотыкается» система (в нашем примере это BT000656), и временно изменить его номер на заведомо больший, который гарантированно не будет занят в ближайшее время.
Посмотрим на пример логики действий:
BT000656.BT000999 (при условии, что текущая нумерация еще далека от этого значения).BT000999, тем самым «перепрыгнув» проблемный участок кэша.Проанализируем программный код. В конфигурациях на «Обычных формах» (как в случае автора темы) часто используется подписка на событие или обработчик в модуле объекта ПриУстановкеНовогоНомера. Рассмотрим, какие ошибки в коде могут приводить к неуникальности:
Процедура ПриУстановкеНовогоНомера(СтандартнаяОбработка, Префикс)
// Если здесь жестко задается префикс без учета организации или подразделения
// это может привести к конфликту, если префикс уже исчерпан.
Префикс = "BT";
КонецПроцедуры
Если в вашей системе установлены расширения, обязательно проверьте их. Расширение может перехватывать установку номера и возвращать префикс, который уже используется другим типом документов или другой организацией. Мы рекомендуем запустить отладчик в момент возникновения ошибки и проверить значение переменной Префикс и то, как платформа пытается вычислить следующий номер.
Чтобы избежать повторения проблемы в будущем, проанализируем важность регламентных операций:
Подводя итог: если ошибка «плавающая» и лечится перезапуском rphost, корень проблемы почти всегда в кэшировании номеров. Сочетание методов программного обновления нумерации и контроля за чистотой данных (отсутствие ручных правок) позволяет полностью устранить данную неисправность.