К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как выделить часть строки в 1С

Как выделить часть строки в 1С: функции Лев, Прав, Сред, СтрНайти и СтрДлина с примерами кода, типичными ошибками и готовыми решениями для разработчика.

Работа со строками — одна из самых частых задач при разработке на платформе 1С:Предприятие. Номенклатурные номера документов, артикулы, ФИО, адреса, коды из внешних систем — всё это часто нужно разрезать на части: взять префикс, отбросить суффикс, извлечь значение между разделителями. Встроенный язык 1С предоставляет для этого компактный набор функций, которых достаточно для подавляющего большинства сценариев.

Базовый инструментарий — это функции Лев(), Прав(), Сред(), СтрНайти() и СтрДлина(). Они доступны и в тонком клиенте, и на сервере, и в веб-клиенте без каких-либо ограничений, поэтому код обработки строк можно писать один раз и использовать везде. Ниже разобраны все функции с примерами, типовые сценарии и ошибки, которые чаще всего допускают разработчики.

Функции Лев и Прав: взять символы с края строки

Функция Лев(Строка, ЧислоСимволов) возвращает указанное количество символов с начала строки. Например, чтобы получить префикс номера документа из первых трёх символов:

НомерДокумента = "АБВ-000123";

Префикс = Лев(НомерДокумента, 3); // "АБВ"

Функция Прав(Строка, ЧислоСимволов) работает зеркально — возвращает символы с конца строки. Типичный пример — извлечь порядковый номер без префикса или последние цифры кода:

Код = "SKU-45678";

Цифры = Прав(Код, 5); // "45678"

Важная особенность обеих функций: если запрошенное число символов больше длины строки, ошибки не будет — вернётся вся строка целиком. Если передать 0 или отрицательное число, результатом будет пустая строка. Это удобно, потому что не требуется предварительная проверка длины, но может маскировать логические ошибки, когда вы ожидали строку определённого формата, а получили усечённую.

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

Функция Сред(Строка, НачальнаяПозиция, ЧислоСимволов) извлекает подстроку, начиная с указанной позиции. Третий параметр необязателен: если его не указывать, будет возвращено всё от начальной позиции до конца строки.

Строка = "Заказ №12345 от клиента";

Фрагмент = Сред(Строка, 9, 5); // "12345"

Остаток = Сред(Строка, 9); // "12345 от клиента"

Обратите внимание: второй параметр — это именно позиция первого нужного символа, а не смещение. Чтобы получить символы начиная с пятого, передают 5, а не 4. Если начальная позиция выходит за пределы строки, функция вернёт пустую строку.

На практике Сред() редко используют с жёстко заданными позициями — реальные данные редко имеют фиксированную длину. Обычно позицию вычисляют динамически через СтрНайти(), о чём речь в следующем разделе.

СтрНайти и СтрДлина: поиск позиции для разрезания строки

Функция СтрНайти(Строка, ПодстрокаПоиска) возвращает позицию первого вхождения подстроки или 0, если подстрока не найдена. Именно связка СтрНайти() с Лев(), Прав() и Сред() решает большинство практических задач выделения части строки.

Классический пример — разделить строку по разделителю на две части:

Строка = "Иванов Иван:менеджер";

Позиция = СтрНайти(Строка, ":");

Если Позиция > 0 Тогда

ФИО = Лев(Строка, Позиция - 1); // "Иванов Иван"

Должность = Сред(Строка, Позиция + 1); // "менеджер"

КонецЕсли;

Функция СтрДлина(Строка) возвращает количество символов в строке. Она нужна, когда требуется вычислить, сколько символов осталось после найденной позиции, или отрезать фиксированный кусок с конца через Лев():

// Убрать последние 2 символа (например, суффикс)

Строка = "Артикул-01";

БезСуффикса = Лев(Строка, СтрДлина(Строка) - 2); // "Артикул"

Порядок действий для разделения строки по разделителю
  1. 1
    Найдите позицию разделителя через СтрНайти(Строка, Разделитель)
  2. 2
    Проверьте, что позиция больше 0 — иначе разделителя в строке нет
  3. 3
    Возьмите левую часть: Лев(Строка, Позиция - 1)
  4. 4
    Возьмите правую часть: Сред(Строка, Позиция + СтрДлина(Разделитель))
  5. 5
    Проверьте результат на тестовых данных, включая строки без разделителя

Типовые сценарии выделения части строки

Извлечь числовую часть номера документа

Номера документов в 1С часто содержат префикс. Чтобы отделить числовую часть, находят позицию дефиса и берут всё, что после него:

Номер = "ОР-000042";

Позиция = СтрНайти(Номер, "-");

Если Позиция > 0 Тогда

ЧисловаяЧасть = Сред(Номер, Позиция + 1); // "000042"

КонецЕсли;

Взять имя файла из полного пути

Здесь нужен последний разделитель, а не первый. Функция СтрНайти() поддерживает направление поиска через третий параметр — НаправлениеПоиска.СКонца:

Путь = "C:\Документы\Отчеты\отчет.pdf";

Позиция = СтрНайти(Путь, "\", НаправлениеПоиска.СКонца);

ИмяФайла = Сред(Путь, Позиция + 1); // "отчет.pdf"

Извлечь значение между двумя разделителями

Когда нужный фрагмент находится между двумя маркерами, применяют два поиска подряд:

Строка = "Товар [АРТ-7788] Новый";

Начало = СтрНайти(Строка, "[");

Конец = СтрНайти(Строка, "]");

Если Начало > 0 И Конец > Начало Тогда

Артикул = Сред(Строка, Начало + 1, Конец - Начало - 1); // "АРТ-7788"

КонецЕсли;

Перед выделением подстроки из данных, пришедших извне (файлы, обмены, ввод пользователя), удалите лишние пробелы функцией СокрЛП() — незаметный пробел в начале или конце строки смещает все позиции и ломает логику разбора.
ПЗ
Практическое замечание

Разбиение строки на массив: СтрРазделить

Если строка содержит несколько значений через один разделитель (CSV-формат, список через запятую), удобнее не искать позиции вручную, а использовать СтрРазделить(Строка, Разделитель). Функция возвращает массив подстрок:

Строка = "красный;зеленый;синий";

Массив = СтрРазделить(Строка, ";");

// Массив[0] = "красный", Массив[1] = "зеленый", Массив[2] = "синий"

По умолчанию пустые элементы между разделителями включаются в результат. Если они не нужны, передайте третьим параметром Ложь. Обратная операция — сборка строки из массива — выполняется функцией СтрСоединить().

Учтите, что индексация массивов в 1С начинается с 0, хотя позиции символов в строках — с 1. Это несоответствие регулярно становится источником ошибок при смешанном коде.

Частые ошибки и ограничения

Типичные ошибки
01
Не проверяется результат СтрНайти(): если подстрока не найдена, функция вернёт 0, и Сред(Строка, 0 + 1) молча выдаст всю строку с первого символа — ошибка останется незамеченной
02
Путаница с позициями: разработчики с опытом в других языках передают позицию 0 как начало строки, но в 1С первый символ имеет позицию 1
03
Использование Прав() без учёта реальной длины: если строка короче ожидаемой, вернётся вся строка, а не ожидаемый суффикс
04
Поиск первого вхождения вместо последнего: в путях файлов и многосоставных кодах разделитель встречается несколько раз, нужен поиск с конца

Ещё одно ограничение касается регистра: СтрНайти() ищет с учётом регистра символов. Если регистр данных непредсказуем (пользовательский ввод), предварительно приведите обе строки к одному регистру через ВРег() или НРег(), но помните, что позиции при этом не меняются — меняется только результат сравнения.

Для сложных шаблонов (например, «три буквы, дефис, шесть цифр») простых функций недостаточно. В таких случаях либо пишут посимвольный разбор в цикле, либо используют объекты работы с регулярными выражениями, доступные в новых версиях платформы, либо выносят проверку формата на этап валидации данных до их попадания в строку.

Контрольные точки

Как проверить результат

Строка с разделителем
Норма

Левая и правая части выделены корректно, разделитель не попал в результат

Тревожный признак

Разделитель остался в одной из частей — ошибка на единицу в позиции

Строка без разделителя
Норма

СтрНайти вернул 0, выполнена ветка обработки отсутствия разделителя

Тревожный признак

Код молча вернул всю строку или пустое значение без диагностики

Пустая строка на входе
Норма

Функции вернули пустую строку без исключения

Тревожный признак

Возникло исключение или в результат попали посторонние данные

Сводная таблица функций работы с подстроками

ФункцияЧто делаетКогда применять
Лев(Строка, N)N символов с началаПрефиксы, первые символы кода
Прав(Строка, N)N символов с концаСуффиксы, последние цифры номера
Сред(Строка, Поз, N)Фрагмент с позиции ПозИзвлечение из середины, всё после разделителя
СтрНайти(Строка, Подстрока)Позиция вхождения или 0Определение точки разреза строки
СтрДлина(Строка)Количество символовВычисление остатка строки, отрезание с конца
СтрРазделить(Строка, Разд)Массив подстрокСписки значений через разделитель
Итог

Что важно запомнить

Для выделения части строки в 1С используют Лев(), Прав() и Сред(), позицию разреза находят через СтрНайти(), длину — через СтрДлина(). Позиции символов начинаются с 1, а ненайденная подстрока даёт 0 — это всегда нужно проверять. Для списков через разделитель удобнее СтрРазделить().

Частые вопросы

Что вернёт СтрНайти, если подстрока не найдена?

Функция вернёт 0. Поэтому перед использованием позиции в Лев(), Прав() или Сред() обязательно проверяйте условие «Позиция > 0», иначе получите неочевидный результат: Сред(Строка, 1) вернёт всю строку целиком, и ошибка останется незамеченной.

Как взять последние N символов строки, если её длина меньше N?

Просто вызовите Прав(Строка, N) — функция не вызовет ошибку и вернёт всю строку целиком. Если такое поведение нежелательно, предварительно сравните СтрДлина(Строка) с требуемой длиной и обработайте короткую строку отдельно.

Как удалить из строки первые несколько символов?

Используйте Сред(Строка, N + 1), где N — количество удаляемых символов. Например, Сред("ПРЕФИКС-123", 8) вернёт "123". Альтернатива — Прав(Строка, СтрДлина(Строка) - N), результат будет тем же.

Учитывает ли СтрНайти регистр символов?

Да, поиск выполняется с учётом регистра: "Арт" и "арт" — разные подстроки. Если регистр не важен, приведите обе строки к одному регистру функциями ВРег() или НРег() перед поиском.

Как найти позицию последнего вхождения подстроки?

Передайте в СтрНайти() третьим параметром НаправлениеПоиска.СКонца. Это типичный приём при извлечении имени файла из полного пути или последнего сегмента составного кода, где разделитель встречается несколько раз.

Чем СтрРазделить лучше ручного разбора через СтрНайти?

СтрРазделить сразу возвращает массив всех частей строки и избавляет от цикла с ручным вычислением позиций, что снижает риск ошибок «на единицу». Ручной разбор оправдан только когда нужны одна-две части или разделители разные.