Как вывести лидирующие нули в номере документа в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Анализ типичной ошибки при использовании функции Формат

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


Ном = Число(Ном) + 1;
ДлиНом = СтрДлина(Ном);
НомерЗаказа = Формат(Ном, "ЧЦ=" + ДлиНом + "; ЧВН=; ЧГ=0");

Здесь кроется логическая ловушка. Когда мы вычисляем СтрДлина(Ном) для числа, например, 125, мы получаем значение 3. Далее в параметр ЧЦ (Число цифр) передается именно эта тройка. Функция Формат видит, что общее число знаков должно быть равно 3, и само число состоит из 3 знаков. В итоге лидирующим нулям просто некуда «втиснуться». Чтобы они появились, значение ЧЦ должно быть строго больше, чем фактическое количество разрядов в числе.

Решение №1: Использование функции Формат с фиксированной длиной

Самый правильный и быстрый способ — это указать в функции Формат ту длину номера, которая предусмотрена в метаданных вашего документа или бизнес-логике. Выясним, как это реализовать на практике. Если мы хотим, чтобы номер всегда состоял, например, из 10 знаков, код должен выглядеть следующим образом:


// Предположим, текущее числовое значение номера равно 125
НомЧислом = Число(СтарыйНомер) + 1; 

// Формируем строку с жестко заданной длиной 10 знаков
// ЧЦ=10 — общая длина
// ЧВН= — признак вывода лидирующих нулей
// ЧГ=0 — отключение группировки разрядов (чтобы не было пробелов)
НомерЗаказа = Формат(НомЧислом, "ЧЦ=10; ЧВН=; ЧГ=0");

В этом случае число 126 превратится в строку «0000000126». Обратите внимание на параметр ЧГ=0. Если ваше число станет больше 1000, 1С по умолчанию может вставить неразрывный пробел как разделитель групп разрядов (например, «0 000 001 250»). Для строкового номера документа это недопустимо, поэтому группировку мы всегда отключаем.

Решение №2: Метод дополнения строки (добавка и обрезка)

Существует альтернативный «программистский» метод, который не зависит от специфических параметров функции Формат и иногда кажется более наглядным. Рассмотрим его по шагам. Его суть заключается в том, чтобы приклеить к числу заведомо большое количество нулей, а затем отсечь лишнее с правой стороны.

Разберем пример:


Ном = 125;
ЖелаемаяДлина = 8;
// Создаем строку из нулей и прибавляем к ней наше число, предварительно убрав пробелы
СтрокаСНулями = "00000000" + СокрЛП(Строка(Ном)); 

// Берем только нужные нам символы справа
НомерЗаказа = Прав(СтрокаСНулями, ЖелаемаяДлина);
// Результат: "00000125"

Этот метод хорош тем, что он абсолютно прозрачен и работает во всех версиях платформы, включая 1С 7.7. Однако стоит помнить, что функция Прав() вернет неверный результат, если длина вашего числа внезапно окажется больше, чем ЖелаемаяДлина. Поэтому всегда делайте запас нулей в исходной строке-шаблоне.

Решение №3: Работа с префиксами и БСП

В современных конфигурациях (например, 1С:ERP, Управление торговлей 11 или Бухгалтерия 3.0), построенных на базе Библиотеки стандартных подсистем (БСП), для работы с номерами существуют специальные программные интерфейсы. Проанализируем, почему это удобнее.

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


// Использование встроенных механизмов БСП для формирования номера
ПолныйНомер = ПрефиксацияОбъектовКлиентСервер.СформироватьПолныйНомер(Префикс, НомерБезПрефикса);

Если вам нужно просто дополнить номер нулями до длины, определенной в метаданных, можно использовать функцию ОбщегоНазначения.ДополнитьСтрокуЛев() (если она доступна в вашей версии конфигурации). Это делает код более читаемым и соответствующим стандартам разработки 1С.

Важность лидирующих нулей для сортировки

Зачем вообще так мучиться с нулями? Выясним причину. В 1С реквизит «Номер» документа почти всегда имеет тип Строка. Сортировка строковых данных в базе данных происходит посимвольно (лексикографически).

Посмотрим на примере, что произойдет без лидирующих нулей:

  1. Номер "1"
  2. Номер "10"
  3. Номер "100"
  4. Номер "2"

Как видите, хронологический порядок полностью нарушается. Номер «2» оказывается в списке после «100». Когда мы используем лидирующие нули, все строки становятся одинаковой длины, и сортировка начинает работать корректно:

Правильный порядок:

  1. Номер "001"
  2. Номер "002"
  3. Номер "010"
  4. Номер "100"

Проблема «битых» номеров

Иногда разработчики сталкиваются с тем, что автоматическая нумерация в 1С «ломается». Это происходит, если пользователь один раз вручную ввел номер без нулей (например, просто «5» вместо «0000000005»). Платформа запоминает этот формат и следующий номер выдает как «6».

Чтобы исправить эту ситуацию, недостаточно просто поменять код. Нужно либо вручную переименовать последние документы, вернув им нули, либо воспользоваться стандартной обработкой Обновление нумерации объектов. Также важно следить за тем, чтобы тип значения, который вы возвращаете в реквизит Номер, всегда оставался строковым. Как только вы случайно преобразуете результат функции Формат обратно в число, все ваши усилия по набиванию нулей будут аннулированы платформой.

Подведем итог: для корректного вывода нулей используйте Формат(Число, "ЧЦ=НужнаяДлина; ЧВН=; ЧГ=0"), всегда следите за тем, чтобы результат оставался строкой, и не забывайте про важность одинаковой длины номеров для правильной работы пользовательских списков.

← На главную