Как правильно увеличить номер документа на единицу в 1С?

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

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

Анализ типичной ошибки ручного инкремента

Рассмотрим ситуацию, с которой столкнулся автор темы. Попытка получить последний номер через запрос и прибавить к нему единицу выглядит следующим образом:


Функция ПолучитьПоследнийНомерРеал()
    НомерДок = 0;
    Запрос = Новый Запрос("ВЫБРАТЬ Первые 1 Док.Номер КАК Номер ИЗ Документ.РеализацияТоваровУслуг КАК Док УПОРЯДОЧИТЬ ПО Номер УБЫВ");
    ВДЗ = Запрос.Выполнить().Выбрать();
    Если ВДЗ.Следующий() Тогда
        НомерДок = ВДЗ.Номер + 1;
    КонецЕсли;
    Возврат НомерДок;
КонецФункции

Проанализируем, почему этот код работает некорректно. Основная причина заключается в том, что поле Номер в документах 1С имеет тип Строка. Когда мы выполняем операцию ВДЗ.Номер + 1, платформа интерпретирует это как конкатенацию (склеивание) строк, а не арифметическое сложение. Именно поэтому вместо ожидаемого номера «БП-0000019» получается «БП-00000181».

Даже если попытаться преобразовать строку в число, прибавить единицу и вернуть обратно в строку, возникнет проблема ведущих нулей. Если номер документа имеет формат «0000018», то после преобразования в число 18 и прибавления единицы мы получим 19. При обратном преобразовании в строку без учета маски мы запишем «19». Для 1С это критично: система ищет максимальный номер по строковым правилам сортировки. Строка, начинающаяся на «9», будет считаться «больше», чем строка, начинающаяся на «0», что в конечном итоге приведет к сбою автонумерации у всех последующих документов.

Использование метода УстановитьНовыйНомер()

Самый правильный и надежный способ присвоить документу следующий номер — воспользоваться встроенным методом объекта УстановитьНовыйНомер(). Этот метод заставляет платформу автоматически вычислить следующий свободный номер в соответствии с заданными в метаданных правилами (периодичность, длина номера, префиксы).

Разберем синтаксис этого метода. Важно помнить, что это именно процедура, она не возвращает значение, а устанавливает его непосредственно в свойство Номер объекта документа:


// Правильное использование в модуле объекта или при программном создании
НовыйДокумент = Документы.РеализацияТоваровУслуг.СоздатьДокумент();
НовыйДокумент.Дата = ТекущаяДата();
// Устанавливаем номер с учетом префикса информационной базы или организации
НовыйДокумент.УстановитьНовыйНомер("БП"); 
НовыйДокумент.Записать();

Проанализируем ситуацию, если вам нужно вызвать этот метод для уже существующего, но еще не записанного в базу объекта. Попытка присвоить результат метода переменной, как в примере ДокРеализации.Номер = ДокРеализации.УстановитьНовыйНомер(), приведет к ошибке, так как метод не возвращает значения. Достаточно просто вызвать процедуру у объекта.

Работа с префиксами и событие ПриУстановкеНовогоНомера

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

  1. Метод УстановитьНовыйНомер(Префикс) принимает строковый префикс.
  2. Платформа ищет в базе данных документ с таким же префиксом и максимальным числовым окончанием.
  3. К найденному числу прибавляется единица, и номер дополняется ведущими нулями до необходимой длины.

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


Процедура ПриУстановкеНовогоНомера(СтандартнаяОбработка, Префикс)
    // Добавляем к стандартному префиксу код организации
    Префикс = Префикс + Организация.Префикс;
    // Можно добавить логику в зависимости от вида операции
    Если ВидОперации = Перечисления.ВидыОперацийРеализации.Экспорт Тогда
        Префикс = Префикс + "ЭК";
    КонецЕсли;
КонецПроцедуры

Проблема «украденных» номеров и транзакций

Вернемся к вопросу использования запросов для получения последнего номера (как в Сообщении 0). Выясним причину, почему это опасно в многопользовательской среде. Между моментом, когда ваш запрос получил «последний» номер, и моментом, когда вы попытаетесь записать новый документ, другой пользователь может успеть создать документ и занять этот номер. Это приведет к ошибке неуникальности номера.

Штатный механизм 1С при использовании УстановитьНовыйНомер() работает более интеллектуально. В современных версиях платформы (8.3) управление нумерацией может происходить в двух режимах:

Что делать, если нумерация «сбилась»?

Если кто-то из пользователей вручную ввел номер, не соответствующий маске (например, вместо «БП-00018» ввел «99999»), автоматическая нумерация может перестать работать корректно. Система будет пытаться найти номер, следующий за «99999», и если длина номера ограничена, она выдаст ошибку. В такой ситуации необходимо:

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

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

← На главную