Как удалить часть строки после определенного по счету символа-разделителя в 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

Часто в практике разработки на 1С возникает задача, когда имеется длинная строка с множеством одинаковых разделителей (например, запятых), и нам нужно удалить или отсечь всю информацию, находящуюся правее определенного по счету разделителя. Разберем ситуацию: есть строка, в которой 10 запятых, и нам необходимо удалить все, что находится правее 8-й запятой.

Проанализируем, в каких случаях чаще всего возникает такая необходимость:

  1. Парсинг данных из текстовых файлов формата CSV, когда требуется проигнорировать несколько последних «колонок» в строке.
  2. Работа с адресными классификаторами (КЛАДР, ФИАС), где элементы адреса строго разделены запятыми. Обрезка помогает отделить базовый адрес от пользовательских комментариев, номеров абонентских ящиков или лишних помещений.
  3. Обработка сложных логов, веб-ссылок или составных штрихкодов, где нужно отсечь неактуальный «хвост» параметров.

Рассмотрим подробнее несколько способов решения этой задачи, начиная от самых современных и оптимальных, заканчивая устаревшими подходами и их критикой.

Способ 1: Современный подход через СтрНайти и Лев (для платформы 8.3.6 и новее)

Начиная с версии платформы 1С:Предприятие 8.3.6, разработчикам доступна мощная функция СтрНайти, которая пришла на смену старой функции Найти. Главное преимущество новой функции — наличие параметра НомерВхождения.

Синтаксис функции выглядит следующим образом:

СтрНайти(<Строка>, <ПодстрокаПоиска>, <НаправлениеПоиска>, <НачальнаяПозиция>, <НомерВхождения>)

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


ПозицияВосьмойЗапятой = СтрНайти(Строка, ",", , , 8);
Если ПозицияВосьмойЗапятой > 0 Тогда
    НужнаяСтрока = Лев(Строка, ПозицияВосьмойЗапятой);
Иначе
    НужнаяСтрока = Строка; // Если запятых меньше 8, оставляем как есть
КонецЕсли;

Важно: Данный метод является наиболее быстрым и лаконичным для современных конфигураций.

Способ 2: Использование массивов через СтрРазделить и СтрСоединить

Еще один актуальный и красивый метод основан на превращении строки в массив. Мы воспользуемся функцией СтрРазделить, которая разбивает исходный текст на элементы массива, используя указанный разделитель.

Разберем алгоритм по шагам:

  1. Разбиваем строку по запятой с помощью СтрРазделить.
  2. Берем первые 8 элементов из полученного массива и помещаем их в новый массив.
  3. Собираем новый массив обратно в строку встроенной функцией СтрСоединить, передав запятую в качестве разделителя.

Этот метод отлично подходит, если вам нужно не просто обрезать строку, но и предварительно проанализировать или видоизменить отдельные блоки (например, очистить адресные элементы от лишних пробелов).

Способ 3: Регулярные выражения (RegEx) через COM-объект

Если задача подразумевает более сложную логику отсечения, можно применить регулярные выражения. Для этого в 1С создается объект VBScript.RegExp. При правильном составлении шаблона поиска, регулярное выражение позволяет за один проход отсечь все данные после нужной по счету запятой.

Ограничения кроссплатформенности: Выясним важный нюанс этого подхода. Использование Новый COMОбъект("VBScript.RegExp") жестко привязывает ваш код к операционной системе Windows. Если сервер 1С развернут на базе ОС Linux, вызов данного COM-объекта приведет к критической ошибке платформы. Поэтому применять данный метод стоит только в строго контролируемой Windows-среде, а лучше — отдавать предпочтение встроенным строковым функциям 1С.

Способ 4: Решение для старых платформ (8.2 и ниже)

В старых версиях платформы функция Найти искала только первое вхождение символа. Поэтому разработчикам приходилось писать циклы.

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

Проанализируем пример из обсуждения, который часто встречается в старом коде:


Адрес = Строка.Адрес;
Разделитель = ",";
Строки = СтрЗаменить(Адрес, Разделитель, Символы.ПС);
НомерПомещения = СтрПолучитьСтроку(Строки, 10);
а = 1;
АдресРодителя = "";
Пока НЕ а = 9 Цикл
    АдресРодителя = АдресРодителя + СтрПолучитьСтроку(Строки, а) + ",";
    а = а + 1;
КонецЦикла;

Критика данного метода: Рассмотрим, почему этот код считается плохой практикой в современных реалиях.

  1. Устаревший синтаксис: Использование функции СтрПолучитьСтроку официально признано устаревшим начиная с версии 8.3.6. Фирма «1С» настоятельно рекомендует заменять ее работу на массивы (через СтрРазделить).
  2. Падение производительности: Склеивание строк внутри цикла с помощью оператора сложения (АдресРодителя = АдресРодителя + ...) крайне неэффективно. В платформе 1С строки неизменяемы. При каждой итерации цикла и каждом сложении система выделяет новую память и копирует данные. Если такой код будет выполняться при массовой загрузке справочника на сотни тысяч строк, это вызовет серьезные "тормоза".

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

← На главную