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