При формировании текстовых чеков, выгрузке данных в файлы с фиксированной шириной полей (TXT, DBF, EDI) или выводе информации моноширинным шрифтом разработчики часто сталкиваются с задачей: строка должна иметь строго определенную длину (например, 46 символов). Если строка короче — её нужно дополнить пробелами, если длиннее — убрать лишние символы или пробелы.
Простая замена функций СтрЗаменить(Строка, " ", "") не подходит, так как она полностью удаляет все пробелы внутри текста, нарушая его читаемость. Рассмотрим несколько проверенных подходов к решению этой задачи.
Разберем один из самых простых и производительных способов. Вместо циклов и сложного поиска лишних символов мы сначала очищаем исходный текст от концевых пробелов методом СокрЛП(), добавляем к нему заранее известное заведомо большее количество пробелов, после чего отсекаем нужную длину с помощью Лев() или Прав().
Посмотрим на пример дополнения строки пробелами справа до 46 символов:
БуферПробелов = " "; // 46 пробелов
ИсходнаяСтрока = " RUB =" + Формат(РезультатЗапроса.СдачаВRUB, "ЧДЦ=2; ЧГ=0");
СтрокаДляВывода = Лев(СокрЛП(ИсходнаяСтрока) + БуферПробелов, 46);
Если необходимо выровнять число или текст по правому краю, используем функцию Прав():
СтрокаДляВывода = Прав(БуферПробелов + СокрЛП(ИсходнаяСтрока), 46);
Проанализируем вариант с использованием готовых функций БСП. В общем модуле СтроковыеФункцииКлиентСервер существует удобный метод ДополнитьСтроку(), который позволяет дополнять текст заданным символом слева или справа до нужной длины.
Рассмотрим пример кода:
ТекстПродажи = " Продажа в EUR";
СуммаТекст = "=" + Формат(РезультатЗапроса.СуммаДокумента, "ЧДЦ=2; ЧГ=0");
ИтоговаяДлина = 46;
ТекущаяДлина = СтрДлина(ТекстПродажи) + СтрДлина(СуммаТекст);
НедостаетСимволов = ИтоговаяДлина - ТекущаяДлина;
Если НедостаетСимволов > 0 Тогда
ТекстПродажи = СтроковыеФункцииКлиентСервер.ДополнитьСтроку(
ТекстПродажи,
СтрДлина(ТекстПродажи) + НедостаетСимволов,
" ",
"Справа"
);
КонецЕсли;
СтрокаДляВывода = ТекстПродажи + СуммаТекст;
Выясним, как поступить, если исходный шаблон строки содержит заданный блок пробелов между текстом и значением (например, между "RUB" и "="), и при превышении длины нужно сократить именно этот внутренний разделитель.
В этом случае вычислим разницу длин и заменяем ровно подчитанное количество пробелов:
СдачаТекст = Формат(РезультатЗапроса.СдачаВRUB, "ЧДЦ=2; ЧГ=0");
КоличествоСимволовВСтроке = " RUB ="; // Шаблон с запасом пробелов
СтрокаДляВывода = КоличествоСимволовВСтроке + СдачаТекст;
ЛишнихПробелов = СтрДлина(СтрокаДляВывода) - 46;
Если ЛишнихПробелов > 0 Тогда
СтрокаПробелов = "";
Пока ЛишнихПробелов > 0 Цикл
СтрокаПробелов = СтрокаПробелов + " ";
ЛишнихПробелов = ЛишнихПробелов - 1;
КонецЦикла;
// Заменяем блок пробелов нужной длины на один пробел
СтрокаДляВывода = СтрЗаменить(СтрокаДляВывода, " RUB" + СтрокаПробелов, " RUB");
КонецЕсли;
При работе со строками фиксированной длины следует учитывать несколько критически важных моментов:
Формат() при форматировании чисел вставляет неразрывный пробел (символ Символы.НПП с кодом 160) в качестве разделителя триад. Обычные функции СокрЛП() и СтрЗаменить(С, " ", "") его не обрабатывают. Чтобы отключить разделитель триад, обязательно передавайте параметр ЧГ=0 или ЧРГ='' в форматной строке.СтрДлина() возвращает количество Unicode-символов. Если вы формируете файл для обмена в кодировке CP866 или UTF-8, учтите, что длина строки в байтах может отличаться от длины в символах.
Квалификаторы = Новый КвалификаторыСтроки(46, ДопустимаяДлина.Фиксированная);
ОписаниеТипа = Новый ОписаниеТипов("Строка",,,, Квалификаторы);
СтрокаФиксированнойДлины = ОписаниеТипа.ПривестиЗначение(ИсходнаяСтрока);