В процессе разработки печатных форм в 1С можно столкнуться с неожиданным поведением кода. Одна из таких ситуаций — некорректное отображение номеров документов. Например, двузначный номер «98» выводится правильно, а трехзначный «108» обрезается до «1». Давайте разберем, почему так происходит и как это исправить, на примере конкретного кода.
Проблема заключается в неверном алгоритме обработки строки с номером документа. Проанализируем исходный код, найдем ошибку и рассмотрим надежные способы ее решения с помощью стандартных функций платформы 1С.
Рассмотрим фрагмент кода, который приводит к некорректному результату. Автор пытается обработать номер документа перед его выводом в результирующую строку.
НомерДокументаОтгрузкиСтрока = СокрЛП(строка(ДокументОснование.Номер));
// Проблемный блок кода
Пока СтрДлина(НомерДокументаОтгрузкиСтрока) > 0 цикл
НомерДокументаОтгрузкиСтрока = Сред(НомерДокументаОтгрузкиСтрока, 1, СтрДлина(НомерДокументаОтгрузкиСтрока) - 1);
Если Лев(НомерДокументаОтгрузкиСтрока, 1) <> "0" тогда
Прервать;
КонецЕсли;
КонецЦикла;
Если КоличествоПП = 1 тогда
КоличествоСтрокНаВывод = ""
Иначе
КоличествоСтрокНаВывод = "-" + КоличествоПП;
КонецЕсли;
Если ЗначениеЗаполнено(НомерДокументаОтгрузкиСтрока) тогда
ПоДокументуОтгрузки = "№ п/п 1" + КоличествоСтрокНаВывод + " № " + НомерДокументаОтгрузкиСтрока + " от " + Формат(ДокументОснование.Дата, "ДФ=dd.MM.yyyy");
Иначе
ПоДокументуОтгрузки = "-- от --";
КонецЕсли;
На первый взгляд, цикл Пока...КонецЦикла задумывался для удаления лидирующих нулей из номера. Однако его реализация содержит логическую ошибку, которая и приводит к "обрезке" номера.
Проследим по шагам, что происходит с номером "108":
НомерДокументаОтгрузкиСтрока равна "108".НомерДокументаОтгрузкиСтрока = Сред(НомерДокументаОтгрузкиСтрока, 1, СтрДлина(НомерДокументаОтгрузкиСтрока) - 1);Если Лев(НомерДокументаОтгрузкиСтрока, 1) <> "0". Проверяется первый символ уже измененной строки ("10"). Первый символ — "1". Условие "1" <> "0" истинно.Прервать, и цикл немедленно завершается.В результате после выполнения этого блока кода в переменной НомерДокументаОтгрузкиСтрока остается значение "10". Автор темы сообщил, что у него выводится "1", что может быть связано с дополнительными, не показанными в примере, преобразованиями. Тем не менее, корень проблемы именно в этом цикле — он некорректно укорачивает строку справа, а не обрабатывает нули слева. Для номера "98" цикл отработает аналогично: "98" превратится в "9", после чего цикл прервется. Очевидно, что данный алгоритм не решает поставленную задачу.
Для корректного вывода номера документа следует отказаться от сложного и ошибочного цикла и использовать простые встроенные функции 1С.
Основная задача автора — чтобы номер "108" выводился как "108". В большинстве случаев номер документа, полученный из реквизита ДокументОснование.Номер, уже находится в нужном формате. Поэтому самое простое и эффективное решение — полностью удалить проблемный цикл.
Код примет следующий вид:
// Просто присваиваем номер, удалив возможные пробелы по краям
НомерДокументаОтгрузкиСтрока = СокрЛП(Строка(ДокументОснование.Номер));
// Далее идет остальной код для формирования строки...
Если КоличествоПП = 1 тогда
КоличествоСтрокНаВывод = "";
Иначе
КоличествоСтрокНаВывод = "-" + КоличествоПП;
КонецЕсли;
// ... и так далее
Этого действия уже достаточно для решения исходной проблемы.
Часто в 1С номера документов хранятся в строковом формате с ведущими нулями для сохранения определенной длины, например, "0000108". Если необходимо избавиться от этих нулей, существует стандартный и надежный прием — преобразование строки в число и обратно.
Шаг 1. Преобразование в число. Функция Число() преобразует строку в числовое представление. При этом все незначащие нули в начале строки автоматически отбрасываются.
Шаг 2. Преобразование обратно в строку. Функция Строка() преобразует полученное число обратно в строку, но уже без лидирующих нулей.
Посмотрим на пример:
// Исходный номер может быть "0000108"
ИсходныйНомер = ДокументОснование.Номер;
// 1. Преобразуем в число, чтобы убрать незначащие нули
НомерКакЧисло = Число(ИсходныйНомер); // Результат: 108 (тип Число)
// 2. Преобразуем обратно в строку для дальнейшей работы
НомерДокументаОтгрузкиСтрока = Строка(НомерКакЧисло); // Результат: "108" (тип Строка)
Этот метод является идиоматичным для 1С и гарантирует правильное удаление лидирующих нулей для номеров любой длины.
Теперь соберем все вместе и напишем финальный, исправленный и надежный вариант кода для формирования строки в печатной форме. Мы будем использовать преобразование через тип Число, чтобы код корректно работал даже с номерами, содержащими ведущие нули.
// 1. Получаем номер и корректно убираем лидирующие нули
// Функция СокрЛП() на всякий случай уберет пробелы по краям
НомерДокументаОтгрузкиСтрока = СокрЛП(Строка(Число(ДокументОснование.Номер)));
// 2. Формируем суффикс для количества позиций
Если КоличествоПП = 1 тогда
КоличествоСтрокНаВывод = "";
Иначе
КоличествоСтрокНаВывод = "-" + КоличествоПП;
КонецЕсли;
// 3. Формируем итоговую строку для вывода
Если ЗначениеЗаполнено(НомерДокументаОтгрузкиСтрока) тогда
ПоДокументуОтгрузки = "№ п/п 1" + КоличествоСтрокНаВывод + " № " + НомерДокументаОтгрузкиСтрока + " от " + Формат(ДокументОснование.Дата, "ДФ=dd.MM.yyyy");
Иначе
ПоДокументуОтгрузки = "-- от --";
КонецЕсли;
Вывод: при работе со строками и числами в 1С всегда старайтесь использовать встроенные функции платформы (Число(), Строка(), Формат(), СокрЛП() и т.д.). Они оптимизированы, надежны и позволяют избежать логических ошибок, которые легко допустить при написании собственных алгоритмов посимвольной обработки строк.