При доработке конфигураций 1С, особенно таких крупных, как ERP, часто возникает необходимость изменить длину номера документа. Казалось бы, простая задача: зашли в конфигуратор, изменили свойство "Длина" с 9 на 10 или 11 символов, обновили базу. Однако на практике разработчики сталкиваются с неприятным сюрпризом: новые документы продолжают создаваться со старым количеством цифр, а спереди появляется пробел (например, вместо "0000000001" создается " 000000001").
В этой статье мы подробно разберем, как работает механизм автонумерации в платформе 1С:Предприятие, почему система "игнорирует" новую длину поля и как правильно исправить эту ситуацию, не нарушив работу типовых механизмов БСП.
Чтобы понять причину проблемы, нам нужно заглянуть "под капот" платформы. Когда пользователь или программный код вызывает метод УстановитьНовыйНомер() (или когда документ записывается с пустым номером), система выполняет следующий алгоритм:
Если последний записанный в базе документ имел номер длиной 9 символов (например, "000000123"), то при создании нового документа платформа возьмет число 124 и дополнит его лидирующими нулями до длины предыдущего номера (то есть до 9 символов). Поскольку мы увеличили длину поля в метаданных до 10 символов, а платформа сгенерировала строку из 9 символов, оставшееся место заполняется пробелом слева.
Таким образом, 1С не смотрит на настройку "Длина" в конфигураторе как на прямое указание "сколько нулей добавить". Она смотрит на уже существующие данные.
Исходя из алгоритма работы платформы, решение становится очевидным: нам нужно "показать" системе новый формат номера. Для этого в базе данных должен появиться хотя бы один документ с правильным количеством разрядов.
Разберем пошаговый алгоритм действий для исправления ситуации:
"ПР0000123" (9 символов + пробел где-то неявно)
"ПР00000123" (10 символов, без пробелов)
Если документов немного, можно исправить их вручную. Но если база рабочая и документов тысячи, лучше написать небольшую обработку. Давайте рассмотрим пример кода, который поможет нормализовать номера.
Логика следующая: мы перебираем документы, формируем правильную строку номера с учетом новой длины и записываем их.
Процедура ИсправитьНумерациюДокументов()
// Выбираем документы, которые нужно исправить
// Важно: сортируем по дате, чтобы не нарушить хронологию
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РеализацияТоваровУслуг.Ссылка КАК Ссылка,
| РеализацияТоваровУслуг.Номер КАК Номер
|ИЗ
| Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
|УПОРЯДОЧИТЬ ПО
| РеализацияТоваровУслуг.Дата";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ДокОбъект = Выборка.Ссылка.ПолучитьОбъект();
// Очищаем номер от пробелов (СтрЗаменить или СокрЛП)
ЧистыйНомер = СокрЛП(ДокОбъект.Номер);
// Здесь должна быть ваша логика формирования нового номера.
// Например, если мы знаем, что префикс занимает 2 символа, а общая длина стала 11.
// Это упрощенный пример, в реальности нужно учитывать префиксы организации и ИБ.
// Допустим, нам нужно просто добавить "0" перед числовой частью, если длина меньше нужной
Пока СтрДлина(ЧистыйНомер) < 11 Цикл
// Вставляем ноль после префикса (предположим префикс "ТД")
// Или просто добавляем лидирующие нули, если префиксы уже обработаны
// Для надежности лучше использовать функцию Префиксации из БСП, но для разового исправления:
// Вариант: если номер был "ТД 001", стал "ТД001", добиваем до "ТД0000001"
// Этот код требует адаптации под вашу структуру номера!
ЧистыйНомер = "0" + ЧистыйНомер;
КонецЦикла;
ДокОбъект.Номер = ЧистыйНомер;
// Записываем в режиме ОбменДанными, чтобы не срабатывали лишние проверки
ДокОбъект.ОбменДанными.Загрузка = Истина;
ДокОбъект.Записать();
КонецЦикла;
// ВАЖНО: После исправления всех номеров обновляем нумерацию
ОбновитьНумерациюОбъектов(Метаданные.Документы.РеализацияТоваровУслуг);
КонецПроцедуры
Обратите особое внимание на метод ОбновитьНумерациюОбъектов(). Без его выполнения механизм автонумерации не узнает о том, что текущий максимальный номер изменился.
В современных конфигурациях, таких как 1С:ERP, механизм нумерации обернут в логику БСП (Библиотеки Стандартных Подсистем). Это добавляет ряд нюансов, которые мы должны учитывать.
Категорически не рекомендуется изменять длину номера непосредственно в объектах типовой конфигурации. Это затруднит последующие обновления. Правильный подход — использовать Расширения конфигурации. В расширении можно заимствовать свойство Номер и изменить его длину. При этом основная конфигурация останется на поддержке.
В ERP событие установки номера перехватывается подписками (например, ПриУстановкеНовогоНомераДокумента). Они вызывают процедуры префиксации, которые добавляют к номеру префикс организации и префикс информационной базы. Если вы хотите изменить логику формирования номера (а не просто длину), не нужно править модули объектов. Создайте свою подписку на событие или используйте переопределяемые модули БСП.
Перед тем как принимать решение об изменении длины номера в ERP, проанализируйте следующие риски:
Проблема с "коротким" номером и пробелами — это штатное поведение платформы 1С. Система всегда пытается продолжить последовательность в том формате, который "видит" в базе данных.
Для решения задачи необходимо:
ОбновитьНумерациюОбъектов().