Как решить проблему с ошибкой «Номер не уникален» при создании документа в 1С?

Программист 1С v8.3 (Обычные формы) 1C:Бухгалтерия
← На главную

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

Причина возникновения конфликтов нумерации

Для начала проанализируем, почему платформа ведет себя именно так. В свойствах формы документа есть параметр Автонумерация. Если там установлено значение Использовать, платформа запрашивает новый номер у системы в момент открытия формы. Если два бухгалтера одновременно нажали кнопку «Создать», они оба могут получить в своих формах один и тот же номер, например, «00001». Тот, кто нажмет «Записать» первым, займет этот номер, а второй получит ошибку уникальности.

Решение 1: Отключение автонумерации в форме (Самый эффективный способ)

Самый простой и правильный способ решить проблему — сделать так, чтобы номер присваивался не при открытии документа, а непосредственно в момент его записи в базу данных. Разберем по шагам, как это сделать:

  1. Откроем конфигуратор и найдем нужный нам документ.
  2. Перейдем на закладку «Формы» и откроем форму документа.
  3. В окне свойств формы найдем категорию «Использование» и свойство Автонумерация.
  4. Установим значение «Не использовать».

Теперь при создании нового документа поле Номер будет оставаться пустым. Номер будет автоматически сгенерирован платформой только тогда, когда пользователь нажмет кнопку «Записать» или «ОК», то есть в момент начала транзакции записи. Это сводит вероятность конфликта к минимуму, так как время между получением номера и завершением записи исчисляется миллисекундами.

Решение 2: Настройка режима автонумерации объектов

Выясним, как настройки самой конфигурации влияют на этот процесс. В корне дерева конфигурации (самый верхний элемент) есть свойство Режим автонумерации объектов. Рассмотрим два доступных варианта:

  1. Освобождать автоматически: Система пытается повторно использовать номера, которые были удалены. Это может привести к «дыркам» в нумерации и замедлению работы, так как СУБД приходится постоянно искать свободные промежутки.
  2. Не освобождать автоматически: Это стандарт для современных конфигураций. Платформа просто берет максимальный номер, который когда-либо существовал в базе, и прибавляет к нему единицу. Мы рекомендуем использовать именно этот режим для стабильной работы и высокой производительности.

Важный момент: Если вы столкнулись с тем, что номера «перескакивают» через 10 или 100 значений в платформе 8.3, это работа механизма кэширования номеров. Для большинства бизнес-задач это не критично, но если бухгалтерия требует строгой последовательности, кэширование можно отключить в настройках сервера 1С.

Решение 3: Программное управление номером через события

Если нам нужно не просто присвоить номер, а добавить к нему префикс организации или подразделения, лучше всего использовать встроенное событие ПриУстановкеНовогоНомера. Проанализируем, как это реализовано в типовых конфигурациях.

Вместо того чтобы писать код в модуле формы, мы воспользуемся модулем объекта. Это гарантирует, что логика сработает и при ручном вводе, и при создании документа программно (например, через обмен данными).


Процедура ПриУстановкеНовогоНомера(СтандартнаяОбработка, Префикс)
    
    // Добавляем префикс организации, если он задан
    Префикс = СокрЛП(Организация.Префикс) + "ЦБ"; 
    
    // СтандартнаяОбработка = Истина означает, что платформа сама 
    // сформирует остальную часть номера после префикса
КонецПроцедуры

Для «своих» документов в типовых конфигурациях (например, Бухгалтерия 2.0 или 3.0) правильнее использовать Подписки на события. Это позволит не снимать документ с поддержки и сохранить возможность легкого обновления. Создадим подписку на событие ПриУстановкеНовогоНомера и привяжем её к общему модулю.

Решение 4: Кнопка ручного обновления номера (Вариант для сложных случаев)

Иногда возникают ситуации, когда специфические требования заказчика не позволяют использовать стандартный механизм (например, сложная нумерация в зависимости от валюты или склада). В этом случае можно добавить в форму кнопку «Присвоить номер», которая будет выполнять запрос к базе и находить последний свободный номер. Посмотрим на пример кода такой обработки:


&НаСервере
Процедура ПрисвоитьНомерНаСервере()
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |	Док.Номер КАК Номер
        |ИЗ
        |	Документ.НашСвойДокумент КАК Док
        |ГДЕ
        |	Док.Дата МЕЖДУ &НачалоГода И &КонецГода
        |УПОРЯДОЧИТЬ ПО
        |	Док.Номер УБЫВ";
    
    Запрос.УстановитьПараметр("НачалоГода", НачалоГода(Объект.Дата));
    Запрос.УстановитьПараметр("КонецГода", КонецГода(Объект.Дата));
    
    Результат = Запрос.Выполнить().Выбрать();
    Если Результат.Следующий() Тогда
        // Логика инкремента строкового номера
        НовыйЧисловойНомер = Число(Результат.Номер) + 1;
        Объект.Номер = Формат(НовыйЧисловойНомер, "ЧЦ=9; ЧВН=; ЧГ=0");
    Иначе
        Объект.Номер = "000000001";
    EndIf;
КонецПроцедуры

Внимание: Этот метод является рискованным в высоконагруженных системах, так как между выполнением запроса и записью документа другой пользователь может успеть занять этот же номер. Если вы используете ручной расчет номера, обязательно делайте это внутри транзакции с использованием блокировки данных.

Подведем итоги

Чтобы навсегда забыть об ошибке «Номер не уникален», придерживайтесь следующей стратегии:

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

Рассмотренные подходы позволят сделать работу пользователей комфортной, а нумерацию документов — стабильной и предсказуемой.

← На главную