Почему в 1С обрезается трехзначный номер документа при выводе на печать?

Программист
← На главную

В процессе разработки печатных форм в 1С можно столкнуться с неожиданным поведением кода. Одна из таких ситуаций — некорректное отображение номеров документов. Например, двузначный номер «98» выводится правильно, а трехзначный «108» обрезается до «1». Давайте разберем, почему так происходит и как это исправить, на примере конкретного кода.

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

Анализ исходного кода и причина ошибки

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


НомерДокументаОтгрузкиСтрока = СокрЛП(строка(ДокументОснование.Номер));

// Проблемный блок кода
Пока СтрДлина(НомерДокументаОтгрузкиСтрока) > 0 цикл
    НомерДокументаОтгрузкиСтрока = Сред(НомерДокументаОтгрузкиСтрока, 1, СтрДлина(НомерДокументаОтгрузкиСтрока) - 1);
    Если Лев(НомерДокументаОтгрузкиСтрока, 1) <> "0" тогда
        Прервать;
    КонецЕсли;
КонецЦикла;

Если КоличествоПП = 1 тогда
    КоличествоСтрокНаВывод = ""
Иначе
    КоличествоСтрокНаВывод = "-" + КоличествоПП;
КонецЕсли;

Если ЗначениеЗаполнено(НомерДокументаОтгрузкиСтрока) тогда
    ПоДокументуОтгрузки = "№ п/п 1" + КоличествоСтрокНаВывод + " № " + НомерДокументаОтгрузкиСтрока + " от " + Формат(ДокументОснование.Дата, "ДФ=dd.MM.yyyy");
Иначе
    ПоДокументуОтгрузки = "-- от --";
КонецЕсли;

На первый взгляд, цикл Пока...КонецЦикла задумывался для удаления лидирующих нулей из номера. Однако его реализация содержит логическую ошибку, которая и приводит к "обрезке" номера.

Проследим по шагам, что происходит с номером "108":

  1. Изначально переменная НомерДокументаОтгрузкиСтрока равна "108".
  2. Начинается первая итерация цикла. Выполняется строка:
    НомерДокументаОтгрузкиСтрока = Сред(НомерДокументаОтгрузкиСтрока, 1, СтрДлина(НомерДокументаОтгрузкиСтрока) - 1);
    Эта команда берет подстроку с первого символа длиной на один символ меньше, чем исходная строка. Фактически, она отсекает последний символ. Таким образом, "108" превращается в "10".
  3. Далее идет проверка: Если Лев(НомерДокументаОтгрузкиСтрока, 1) <> "0". Проверяется первый символ уже измененной строки ("10"). Первый символ — "1". Условие "1" <> "0" истинно.
  4. Срабатывает команда Прервать, и цикл немедленно завершается.

В результате после выполнения этого блока кода в переменной НомерДокументаОтгрузкиСтрока остается значение "10". Автор темы сообщил, что у него выводится "1", что может быть связано с дополнительными, не показанными в примере, преобразованиями. Тем не менее, корень проблемы именно в этом цикле — он некорректно укорачивает строку справа, а не обрабатывает нули слева. Для номера "98" цикл отработает аналогично: "98" превратится в "9", после чего цикл прервется. Очевидно, что данный алгоритм не решает поставленную задачу.

Как правильно обработать номер документа

Для корректного вывода номера документа следует отказаться от сложного и ошибочного цикла и использовать простые встроенные функции 1С.

Решение 1: Простое удаление ошибочного кода

Основная задача автора — чтобы номер "108" выводился как "108". В большинстве случаев номер документа, полученный из реквизита ДокументОснование.Номер, уже находится в нужном формате. Поэтому самое простое и эффективное решение — полностью удалить проблемный цикл.

Код примет следующий вид:


// Просто присваиваем номер, удалив возможные пробелы по краям
НомерДокументаОтгрузкиСтрока = СокрЛП(Строка(ДокументОснование.Номер));

// Далее идет остальной код для формирования строки...
Если КоличествоПП = 1 тогда
    КоличествоСтрокНаВывод = "";
Иначе
    КоличествоСтрокНаВывод = "-" + КоличествоПП;
КонецЕсли;

// ... и так далее

Этого действия уже достаточно для решения исходной проблемы.

Решение 2: Корректное удаление лидирующих нулей

Часто в 1С номера документов хранятся в строковом формате с ведущими нулями для сохранения определенной длины, например, "0000108". Если необходимо избавиться от этих нулей, существует стандартный и надежный прием — преобразование строки в число и обратно.

Шаг 1. Преобразование в число. Функция Число() преобразует строку в числовое представление. При этом все незначащие нули в начале строки автоматически отбрасываются.

Шаг 2. Преобразование обратно в строку. Функция Строка() преобразует полученное число обратно в строку, но уже без лидирующих нулей.

Посмотрим на пример:


// Исходный номер может быть "0000108"
ИсходныйНомер = ДокументОснование.Номер;

// 1. Преобразуем в число, чтобы убрать незначащие нули
НомерКакЧисло = Число(ИсходныйНомер); // Результат: 108 (тип Число)

// 2. Преобразуем обратно в строку для дальнейшей работы
НомерДокументаОтгрузкиСтрока = Строка(НомерКакЧисло); // Результат: "108" (тип Строка)

Этот метод является идиоматичным для 1С и гарантирует правильное удаление лидирующих нулей для номеров любой длины.

Итоговый код для печатной формы

Теперь соберем все вместе и напишем финальный, исправленный и надежный вариант кода для формирования строки в печатной форме. Мы будем использовать преобразование через тип Число, чтобы код корректно работал даже с номерами, содержащими ведущие нули.


// 1. Получаем номер и корректно убираем лидирующие нули
// Функция СокрЛП() на всякий случай уберет пробелы по краям
НомерДокументаОтгрузкиСтрока = СокрЛП(Строка(Число(ДокументОснование.Номер)));

// 2. Формируем суффикс для количества позиций
Если КоличествоПП = 1 тогда
    КоличествоСтрокНаВывод = "";
Иначе
    КоличествоСтрокНаВывод = "-" + КоличествоПП;
КонецЕсли;

// 3. Формируем итоговую строку для вывода
Если ЗначениеЗаполнено(НомерДокументаОтгрузкиСтрока) тогда
    ПоДокументуОтгрузки = "№ п/п 1" + КоличествоСтрокНаВывод + " № " + НомерДокументаОтгрузкиСтрока + " от " + Формат(ДокументОснование.Дата, "ДФ=dd.MM.yyyy");
Иначе
    ПоДокументуОтгрузки = "-- от --";
КонецЕсли;

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

← На главную