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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

В процессе работы с платформой 1С программисты часто сталкиваются с ситуацией, когда автонумерация задач или документов начинает работать некорректно. Типичный симптом: номера внезапно «теряют» лидирующие нули, превращаясь из строк вида 000009999 в обычные числа типа 9999. Это приводит к тому, что при попытке создать следующий объект платформа выдает ошибку: «Значение поля Номер не уникально». Разберем детально, почему это происходит и как исправить ситуацию.

Почему сбивается нумерация и пропадают нули?

Проанализируем механику работы платформы. Поле Номер в большинстве объектов имеет тип Строка. Для строк в 1С применяется лексикографическая сортировка. В этой логике строка 9999 считается «больше», чем строка 000010000, потому что символ «9» имеет больший код, чем символ «0».

Когда пользователь или внешняя обработка записывает номер без лидирующих нулей, система при поиске следующего свободного номера находит эту «максимальную» строку 9999 и пытается прибавить к ней единицу. Однако, достигнув предела разрядности, заданного строкой без нулей, или столкнувшись с уже существующим номером, механизм автонумерации зацикливается, что и вызывает ошибку уникальности.

Основные причины сбоя:

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

Способ 1: Использование метода ОбновитьНумерациюОбъектов

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

Выполнить его можно через консоль кода или внешнюю обработку для конкретного типа метаданных:

ОбновитьНумерациюОбъектов(Метаданные.Задачи.ЗадачаИсполнителя);

Это решение часто помогает, если проблема вызвана кэшированием или если вы уже исправили последние ошибочные номера вручную, но система продолжает выдавать ошибку.

Способ 2: Программная перенумерация существующих задач

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

Рассмотрим пример кода для перенумерации:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ЗадачаИсполнителя.Ссылка КАК Ссылка
    |ИЗ
    |	Задача.ЗадачаИсполнителя КАК ЗадачаИсполнителя
    |УПОРЯДОЧИТЬ ПО
    |	ЗадачаИсполнителя.Дата";

Выборка = Запрос.Выполнить().Выбрать();
Счетчик = 1;

Пока Выборка.Следующий() Цикл
    Объект = Выборка.Ссылка.ПолучитьОбъект();
    // Формируем номер с лидирующими нулями (например, для длины 9)
    Объект.Номер = Формат(Счетчик, "ЧЦ=9; ЧГ=0; ЧВН=");
    
    Попытка
        Объект.Записать();
        Счетчик = Счетчик + 1;
    Исключение
        Сообщить("Ошибка при записи задачи " + Выборка.Ссылка + ": " + ОписаниеОшибки());
    КонецПопытки;
КонецЦикла;

Важный нюанс: при преобразовании числа в строку функцией Строка() или Формат() для чисел больше 999 может возникнуть неразрывный пробел (разделитель групп разрядов). Чтобы этого избежать, в строке формата мы используем ЧГ=0. Если же вы используете простое преобразование, не забудьте удалить пробелы с помощью СтрЗаменить(Текст, Символы.НПП, "").

Способ 3: Использование типовых обработок

Если вы не хотите писать код, можно воспользоваться стандартными инструментами. Например, обработка «Универсальный подбор и обработка объектов» (доступна на ИТС) позволяет массово изменять реквизиты. Однако для задач бизнес-процесса может потребоваться предварительная настройка отборов, чтобы не нарушить логику связанных процессов.

Как предотвратить проблему в будущем?

Чтобы ситуация не повторилась, проанализируем защитные меры, которые можно внедрить в конфигурацию:

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

Помните, что если вы решите изменить длину номера в конфигураторе (например, с 9 до 12 символов), платформа не добавит лидирующие нули к старым номерам автоматически. После изменения длины выполнение программной перенумерации (Способ 2) является обязательным шагом для сохранения работоспособности автонумерации.

← На главную