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