При работе с документами часто возникает ситуация, когда сбивается автонумерация. Например, вместо стандартного номера с ведущими нулями 00000000690 в базе появляется короткий номер 690. Это приводит к тому, что последующие документы начинают нумероваться без нулей, либо нарушается хронологический порядок сортировки. Разберем, как исправить эту проблему программно, на какие особенности типа данных следует обратить внимание и как корректно обновить нумерацию в системе.
Прежде чем приступать к написанию программного кода, выясним причину и структуру хранения номера. В платформе 1С стандартный реквизит Номер у документов может иметь один из двух типов данных:
"00000000690".Число физически невозможно сохранить ведущие нули в базе данных. Число 00000000690 на уровне СУБД всегда будет сохранено как 690.Если в вашем документе тип номера действительно числовой, получить лидирующие нули непосредственно в реквизите не удастся. В таком случае нули формируются исключительно динамически для вывода на печать или отображения в форме с помощью форматирования строки:
СтрокаНомера = Формат(ДокументОбъект.Номер, "ЧЦ=11; ЧВН=");
Если же тип номера — строка (что справедливо для 99% документов), мы можем дополнить его нулями слева и перезаписать объект.
Рассмотрим по шагам, как исправить номера в строковом реквизите программным способом:
РежимЗаписиДокумента.Запись, чтобы не инициировать повторное проведение и не заблокировать регистры.ОбновитьНумерациюОбъектов(), чтобы платформа не продолжала создавать документы по сбитой нумерации.Посмотрим на практический пример кода. Предположим, длина номера в метаданных документа ПутевойЛист составляет 11 символов, и нам нужно привести короткие номера к стандартному виду:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПутевойЛист.Ссылка КАК Ссылка,
| ПутевойЛист.Номер КАК Номер
|ИЗ
| Документ.ПутевойЛист КАК ПутевойЛист
|ГДЕ
| ДЛИНАСТРОКИ(ПутевойЛист.Номер) < 11
|УПОРЯДОЧИТЬ ПО
| ПутевойЛист.Дата ВОЗР";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ДокОбъект = Выборка.Ссылка.ПолучитьОбъект();
// Формируем новый номер нужной длины (11 знаков)
СтарыйНомер = СокрЛП(Выборка.Номер);
НовыйНомер = Прав("00000000000" + СтарыйНомер, 11);
ДокОбъект.Номер = НовыйНомер;
Попытка
// Записываем документ без перепроведения
ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
Исключение
Сообщить("Ошибка при записи документа " + Выборка.Ссылка + ": " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
// Обязательно сбрасываем кэш автонумератора платформы
ОбновитьНумерациюОбъектов(Метаданные.Документы.ПутевойЛист);
Проанализируем потенциальные сложности, с которыми можно столкнуться при массовой смене номеров:
РежимЗаписиДокумента.Проведение. Смена номера не должна затрагивать движения регистров, остатки и финансовые итоги прошлых периодов."ТЕМП-") либо обрабатывают документы в порядке убывания номеров."00-00000690"), простое дополнение нулями слева испортит структуру. В таких случаях нулями дополняется только цифровая часть номера после префикса.ОбновитьНумерациюОбъектов(), следующий созданный пользователем документ может снова получить неправильный короткий номер.Если нет возможности писать внешнюю обработку или открывать конфигуратор, рассмотрим альтернативный вариант: использование типовой обработки «Групповое изменение реквизитов». В дополнительных настройках обработки можно включить выполнение произвольного алгоритма на встроенном языке, снять флаг перепроведения документов и выполнить дополнение номера ведущими нулями прямо в пользовательском режиме.