При разработке алгоритмов обработки текстовых данных в платформе 1С программисты часто сталкиваются с особенностями работы встроенной функции СтрЧислоСтрок(). Если строка заканчивается одним или несколькими символами перевода строки (Символы.ПС), стандартная функция может возвращать меньшее значение, чем фактически ожидается. Разберем причины такого поведения платформы и рассмотрим практические способы точного подсчета строк.
Проанализируем механику работы встроенных функций 1С. Функция СтрЧислоСтрок() воспринимает завершающий символ перевода строки как терминатор (маркер окончания текущей строки), а не как разделитель. Если после последнего перевода строки больше нет символов, платформа не регистрирует создание новой пустой строки.
Такое поведение обеспечивает строгую согласованность с функцией СтрПолучитьСтроку(). Если бы функция СтрЧислоСтрок() возвращала увеличенное значение, последующий вызов СтрПолучитьСтроку() по максимальному индексу приводил бы к ошибке времени выполнения. Аналогичным образом ведет себя и объект ТекстовыйДокумент при вызове метода КоличествоСтрок().
Однако в задачах парсинга файлов, валидации шаблонов или подготовки данных для выгрузки пустые строки в конце текста часто являются значимыми. Рассмотрим эффективные способы их учета.
Наиболее лаконичный и современный вариант в платформе 1С:Предприятие 8.3 — использование функции СтрРазделить(). Третий параметр этой функции (ВключатьПустые) определяет, будут ли сохраняться пустые элементы при разбиении строки.
Посмотрим на пример кода:
ИсходныйТекст = "Строка 1" + Символы.ПС + Символы.ПС;
// Третий параметр Ложь отключает пропуск пустых строк (пустые строки сохраняются)
МассивСтрок = СтрРазделить(ИсходныйТекст, Символы.ПС, Ложь);
РеальноеЧислоСтрок = МассивСтрок.Количество();
Сообщить("Количество строк: " + РеальноеЧислоСтрок);
Разберем, как это работает: передавая Ложь в параметр СокращатьНепечатаемыеСимволы / ПропускатьПустые, мы получаем массив, содержащий все строки, включая пустые в конце текста. Размер полученного массива точно отражает фактическое количество строк.
Если требуется избежать создания промежуточного массива для экономии оперативной памяти при обработке объемных строк, применим математический подсчет разделителей с помощью функции СтрЧислоВхождений().
Количество строк в тексте всегда равно количеству разделителей плюс единица. Чтобы платформа не игнорировала завершающий перенос строки, добавим в конец временный непустой символ (например, пробел):
ИсходныйТекст = "Строка 1" + Символы.ПС + Символы.ПС;
// Добавляем пробел в конец, чтобы завершающий перевод строки стал полноценным разделителем
ЧислоСтрок = СтрЧислоВхождений(ИсходныйТекст + " ", Символы.ПС) + 1;
Сообщить("Количество строк: " + ЧислоСтрок);
При получении данных из внешних источников (веб-сервисы, файлы, сформированные в операционных системах Linux, macOS или Windows) символы перевода строк могут отличаться:
Символы.ВК + Символы.ПССимволы.ПССимволы.ВКЕсли текст содержит смешанные или отличные от стандартного Символы.ПС переносы, прямой подсчет может вернуть некорректный результат. В таких случаях предварительно нормализуем текст к единому разделителю перед подсчетом строк.
Разберем универсальную процедуру нормализации и подсчета строк:
НормализованныйТекст = СтрЗаменить(ИсходныйТекст, Символы.ВК + Символы.ПС, Символы.ПС);
НормализованныйТекст = СтрЗаменить(НормализованныйТекст, Символы.ВК, Символы.ПС);
РеальноеЧислоСтрок = СтрРазделить(НормализованныйТекст, Символы.ПС, Ложь).Количество();
Следует различать логические строки (разделенные символом переноса) и визуальные строки (отображаемые на экране или в печатной форме с учетом ширины колонок):
ТабличныйДокумент. Текст помещается в область с включенным свойством АвтоПереносСтрок, а результирующее размещение проверяется с помощью метода ПроверитьВывод() или путем замера высоты сформированной строки.