При работе с информационными базами 1С:Предприятие часто возникает необходимость создания тестовых сред или копий рабочих баз для разработки и проверки обновлений. Однако программисты и системные администраторы нередко сталкиваются с неприятной ситуацией: в свежесозданной копии базы при попытке создать новый документ (например, ЗаказПокупателя) система выдает критическую ошибку: «Значение поля "Номер" не уникально». При этом поиск показывает, что документ с таким номером уже существует в базе, хотя в оригинальной (рабочей) базе нумерация идет корректно.
В этой статье мы подробно разберем, почему возникает этот эффект, как работает механизм нумерации на уровне кластера серверов 1С и какими способами можно быстро вернуть работоспособность системы.
Для того чтобы понять природу ошибки, проанализируем архитектуру взаимодействия сервера приложений 1С и сервера СУБД (например, MS SQL Server). Многие ошибочно полагают, что за генерацию следующего номера отвечает база данных, однако в среде 1С:Предприятие 8 это не так. Функцию управления номерами берет на себя Сервис нумерации объектов, входящий в состав менеджера кластера 1С.
Рассмотрим механизм работы этого сервиса подробнее:
rmngr или rphost.Restore из бэкапа), сервер приложений 1С об этом «не знает». В его оперативной памяти по-прежнему хранится информация о том, какой номер был выдан последним в предыдущем состоянии базы.Проанализируем ситуацию: это не баг платформы, а логичное следствие разделения ответственности между сервером приложений и СУБД. Кэширование необходимо для исключения избыточных блокировок при одновременной работе сотен пользователей.
Самый быстрый и эффективный способ исправить ситуацию без перезагрузки серверов — использовать встроенный метод платформы ОбновитьНумерациюОбъектов(). Эта функция заставляет сервер 1С принудительно перечитать максимальные значения номеров из таблиц базы данных и сбросить свой внутренний кэш.
Рассмотрим, как применить этот метод на практике. Если проблема возникла с конкретным типом документа, например, ЗаказПокупателя, мы можем запустить обработку со следующим кодом:
// Обновление нумерации для конкретного типа документа
МетаданныеОбъекта = Метаданные.Документы.ЗаказПокупателя;
ОбновитьНумерациюОбъектов(МетаданныеОбъекта);
Если же вы не знаете точно, в каких объектах сбилась нумерация, или хотите провести «профилактику» всей базы, метод можно вызвать без параметров. В этом случае система просканирует все справочники и документы, имеющие автонумерацию:
// Полное обновление нумерации для всей информационной базы
ОбновитьНумерациюОбъектов();
Сообщить("Нумерация объектов успешно обновлена!");
Важный нюанс: при выполнении этой операции на очень больших базах данных (терабайтные объемы) сканирование всех таблиц может занять значительное время и создать нагрузку на дисковую подсистему SQL-сервера. Поэтому в рабочих средах рекомендуется указывать конкретный тип метаданных.
Если по каким-то причинам вы не можете запустить внешнюю обработку (например, нет прав на запуск внешних обработок или конфигуратор заблокирован), существует административный способ решения проблемы. Поскольку кэш номеров живет в оперативной памяти процессов сервера 1С, полная очистка этой памяти решит проблему.
Выполним следующие шаги:
1C:Enterprise 8.3 Server Agent (в списке служб Windows она обычно называется 1C:Enterprise 8.3 Server Agent).rphost, rmngr и ragent в диспетчере задач.После перезапуска сервис нумерации инициализируется «с нуля». При первом обращении к созданию документа сервер выполнит запрос к СУБД SELECT MAX(Number)... и начнет отсчет от реально существующего в базе максимума.
В современных конфигурациях, построенных на базе Библиотеки стандартных подсистем (БСП), таких как «1С:ERP», «1С:Управление торговлей 11» или «1С:Бухгалтерия 3.0», предусмотрены штатные инструменты для решения подобных проблем. Это позволяет избежать написания кода.
Выясним, где найти этот инструмент:
Также стоит проверить регламентные задания. В некоторых случаях автоматическое задание по обновлению нумерации может быть выключено, что приводит к накоплению ошибок при частом восстановлении копий.
Иногда возникают ситуации, когда вызов функции не приносит результата. Рассмотрим подробнее такие случаи:
БФ-0001 ввел БФ-9999), автоматика начнет отсчет от этого огромного номера. В этом случае нужно найти этот документ, исправить его номер на корректный, и только потом вызывать ОбновитьНумерациюОбъектов()."001" и " 001" (с пробелом впереди) для системы абсолютно разные, но при поиске максимального значения они могут создавать путаницу в алгоритмах автонумерации.Подводя итог, можно сказать, что ситуация с неуникальностью номеров в копиях баз — это штатное поведение системы, обусловленное механизмами оптимизации. Использование ОбновитьНумерациюОбъектов() является «золотым стандартом» решения этой задачи для любого программиста 1С.