Разработка и Конфигурация · 12 мин
Как найти значение в строке в 1С
Как найти значение в строке в 1С: функции СтрНайти и Найти, поиск подстроки, работа с регистром, поиск в таблице значений и запросах. Примеры кода и типичные ошибки.
Поиск значения в строке — одна из самых частых задач при разработке и доработке конфигураций 1С. Она возникает при разборе адресов, проверке форматов данных, поиске подстроки в наименовании товара, обработке файлов обмена и фильтрации данных. Встроенный язык 1С предоставляет несколько инструментов для этого: от простых функций поиска подстроки до полноценных механизмов запросов.
Выбор способа зависит от контекста: нужно ли найти позицию символа в строковой переменной, проверить вхождение текста в поле базы данных или отобрать строки таблицы значений по условию. У каждого подхода свои ограничения по производительности, учёту регистра и направлению поиска.
Ниже разобраны основные функции и сценарии с примерами кода, условиями выбора и типичными ошибками, которые допускают разработчики при работе со строками в 1С.
Функция СтрНайти — основной способ поиска подстроки
Функция СтрНайти() появилась в платформе 8.3.6 и является рекомендуемым способом поиска подстроки. Она возвращает номер позиции, с которой начинается искомый фрагмент, или 0, если вхождение не найдено. Нумерация символов в 1С начинается с единицы, а не с нуля — это важно учитывать при сравнении с другими языками.
Строка = "Накладная № 12345 от поставщика";
Позиция = СтрНайти(Строка, "12345");
// Позиция = 14
Если СтрНайти(Строка, "поставщик") > 0 Тогда
Сообщить("Подстрока найдена");
КонецЕсли;
Полный синтаксис функции включает дополнительные параметры: СтрНайти(Строка, ПодстрокаПоиска, НаправлениеПоиска, НачальнаяПозиция, НомерВхождения). Направление поиска задаётся значениями НаправлениеПоиска.СНачала или НаправлениеПоиска.СКонца, начальная позиция позволяет искать не с первого символа, а номер вхождения — найти, например, второе или третье вхождение подстроки.
Строка = "а;б;в;а;г";
// Найдём второе вхождение буквы "а"
Позиция = СтрНайти(Строка, "а", НаправлениеПоиска.СНачала, 1, 2);
// Позиция = 7
// Поиск с конца строки
ПозицияСКонца = СтрНайти(Строка, ";", НаправлениеПоиска.СКонца);
// ПозицияСКонца = 8
Функция чувствительна к регистру: поиск «А» и «а» даст разные результаты. Если регистр неважен, перед поиском приведите обе строки к одному регистру функциями ВРег() или НРег().
Устаревшая функция Найти и совместимость
В старых конфигурациях и коде, написанном до платформы 8.3.6, повсеместно встречается функция Найти(Строка, Подстрока). Она работает аналогично базовому варианту СтрНайти: возвращает позицию первого вхождения или 0. Платформа до сих пор поддерживает эту функцию, поэтому старый код продолжает работать.
Позиция = Найти("ООО Ромашка", "Ромашка"); // Позиция = 5
Различие в том, что у Найти() нет параметров направления поиска, начальной позиции и номера вхождения. Если вы дорабатываете старый модуль и вам нужен расширенный поиск, замените вызов на СтрНайти — сигнатуры первых двух параметров совпадают, поэтому замена безопасна.
При обновлении конфигураций с режимом совместимости ниже 8.3.6 функция СтрНайти может быть недоступна. Проверьте свойство конфигурации «Режим совместимости» перед использованием новых функций платформы.
Поиск без учёта регистра и с дополнительными условиями
Стандартной функции поиска без учёта регистра в платформе нет, поэтому задача решается приведением регистра. Сравнивать нужно обе строки — и исходную, и искомую:
Строка = "Счёт-Фактура № 100";
Подстрока = "счёт-фактура";
Если СтрНайти(НРег(Строка), НРег(Подстрока)) > 0 Тогда
Сообщить("Найдено без учёта регистра");
КонецЕсли;
Помните, что позиция, полученная после преобразования регистра, остаётся корректной, поскольку НРег() и ВРег() не меняют длину строки. Но если дальше нужно извлечь найденный фрагмент функцией Сред(), применяйте её к исходной строке, а не к преобразованной.
Для проверки, начинается ли строка с определённого префикса или заканчивается суффиксом, в платформе есть отдельные функции СтрНачинаетсяС() и СтрЗаканчиваетсяНа(). Они возвращают булево и читаются лучше, чем сравнение позиции с единицей:
Если СтрНачинаетсяС(НомерДокумента, "00-") Тогда
// Обработка номеров с префиксом
КонецЕсли;
При разборе строк с разделителями (CSV, адреса, ФИО) удобнее не искать позиции вручную, а использовать СтрРазделить(Строка, ";", Ложь) — функция вернёт массив частей. Третий параметр Ложь отбрасывает пустые элементы.
Поиск значения в данных базы через запрос
Когда искать нужно не в переменной, а в полях справочников или документов, используйте язык запросов. Оператор ПОДОБНО (LIKE) позволяет найти записи, где строковое поле содержит заданный фрагмент:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка,
| Номенклатура.Наименование КАК Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Наименование ПОДОБНО &Шаблон";
Запрос.УстановитьПараметр("Шаблон", "%кабель%");
Результат = Запрос.Выполнить().Выгрузить();
Символ процента % означает любую последовательность символов любой длины, подчёркивание _ — ровно один произвольный символ. Шаблон "%кабель%" найдёт «Кабель ВВГ 3х2.5», «Провод-кабель» и любые другие наименования, содержащие это слово.
У оператора ПОДОБНО есть важное ограничение: поиск с шаблоном, начинающимся с %, не использует индексы и при больших объёмах данных выполняется медленно. Для регулярного полнотекстового поиска по наименованиям, описаниям и комментариям правильнее включить полнотекстовый поиск данных в настройках информационной базы.
Поиск значения в таблице значений и табличной части
Таблица значений — не строка, но задача «найти значение» часто относится именно к ней. Для поиска по одной колонке используется метод Найти(Значение, ИмяКолонки), который возвращает первую найденную строку или Неопределено:
СтрокаТовара = ТаблицаТоваров.Найти(ИскомыйАртикул, "Артикул");
Если СтрокаТовара = Неопределено Тогда
Сообщить("Артикул не найден");
Иначе
Сообщить("Количество: " + СтрокаТовара.Количество);
КонецЕсли;
Для поиска по нескольким колонкам или когда нужны все совпадения, используйте НайтиСтроки() со структурой отбора. Метод возвращает массив строк:
Отбор = Новый Структура;
Отбор.Вставить("Склад", СкладОтгрузки);
Отбор.Вставить("Отменено", Ложь);
НайденныеСтроки = ТаблицаТоваров.НайтиСтроки(Отбор);
Для Каждого Строка Из НайденныеСтроки Цикл
// Обработка каждой найденной строки
КонецЦикла;
Методы Найти и НайтиСтроки сравнивают значения по точному совпадению. Поиск по части строки («содержит») через них невозможен — для этого придётся перебирать строки циклом и применять СтрНайти к значению колонки.
- 1Переберите таблицу значений циклом Для Каждого
- 2Для каждой строки проверьте условие СтрНайти(Строка.Колонка, Подстрока) > 0
- 3При необходимости приведите оба значения к одному регистру через НРег()
- 4Соберите подходящие строки в массив или отдельную таблицу
- 5Проверьте результат: количество найденных строк должно соответствовать ожиданиям на тестовых данных
Проверка результата и границы применения
Надёжный код поиска всегда проверяет результат до его использования. Для СтрНайти это сравнение с нулём, для Найти в таблице значений — сравнение с Неопределено, для запроса — проверка Результат.Пустой() или количества строк в выгрузке. Пропуск проверки приводит к ошибкам вида «Поле объекта не обнаружено» при обращении к несуществующей строке.
Отдельная ситуация — поиск в строках неограниченной длины и многострочных текстах. СтрНайти корректно работает с любыми длинами, но при обработке очень больших текстов (десятки мегабайт) многократный поиск в цикле может занять заметное время. В таких случаях выносите поиск из цикла или используйте СтрРазделить один раз вместо множества вызовов СтрНайти.
Если задача — не программная обработка, а просто найти значение в списке в пользовательском режиме, используйте встроенные средства формы списка: строку поиска (Ctrl+F), отбор по условию «Содержит» или поле полнотекстового поиска в панели навигации, если оно включено администратором.
Какой способ выбрать в конкретной ситуации
Краткий ориентир: в строковой переменной — СтрНайти, в полях базы данных — запрос с ПОДОБНО или полнотекстовый поиск, в таблице значений — Найти или НайтиСтроки для точного совпадения и цикл со СтрНайти для поиска по вхождению. Выбор между ними определяется тем, где физически находятся данные.
| Где находятся данные | Инструмент | Тип поиска |
|---|---|---|
| Строковая переменная | СтрНайти | Подстрока, позиция вхождения |
| Строковая переменная (префикс/суффикс) | СтрНачинаетсяС, СтрЗаканчиваетсяНа | Проверка начала и конца строки |
| Поля справочников и документов | Запрос с ПОДОБНО | По шаблону с % и _ |
| Тексты большого объёма в базе | Полнотекстовый поиск | По словам с учётом морфологии |
| Таблица значений | Найти, НайтиСтроки | Точное совпадение значения |
| Таблица значений (часть строки) | Цикл + СтрНайти | Вхождение подстроки |
Как выбрать действие
Часто задаваемые вопросы
Чем СтрНайти отличается от Найти?
СтрНайти — современная функция платформы (с версии 8.3.6) с дополнительными параметрами: направление поиска, начальная позиция и номер вхождения. Найти — устаревший вариант, который ищет только первое вхождение с начала строки. Обе возвращают позицию или 0. В новом коде используйте СтрНайти.
Как найти подстроку без учёта регистра?
Приведите обе строки к одному регистру перед поиском: СтрНайти(НРег(Строка), НРег(Подстрока)). Позиция вхождения при этом останется корректной, но извлекать фрагмент функцией Сред() нужно из исходной строки.
Почему запрос с ПОДОБНО работает медленно?
Шаблон, начинающийся с символа %, не позволяет использовать индекс, и СУБД сканирует всю таблицу. Добавьте в запрос другие отборы, ограничивающие выборку, или используйте полнотекстовый поиск, который строит специальный индекс по словам.
Как проверить, что в таблице значений ничего не найдено?
Метод Найти() возвращает Неопределено, если совпадений нет — сравнивайте результат с этим значением. Метод НайтиСтроки() возвращает пустой массив, поэтому проверяйте НайденныеСтроки.Количество() = 0.
Можно ли найти все вхождения подстроки в строке?
Да, вызывайте СтрНайти в цикле, передавая начальную позицию после предыдущего найденного вхождения (позиция плюс длина подстроки), пока функция не вернёт 0. Альтернатива — СтрРазделить по искомой подстроке: количество вхождений равно размеру массива минус один.
Как искать значение в списке в режиме пользователя, без программирования?
Откройте форму списка и используйте поиск по Ctrl+F, команду «Найти» в меню «Ещё» или настройку отбора с условием «Содержит». Если администратор включил полнотекстовый поиск, доступна также строка поиска в верхней панели программы.
Что важно запомнить
В строковых переменных ищите через СтрНайти с проверкой результата на 0, в базе данных — через запрос с ПОДОБНО или полнотекстовый поиск, в таблице значений — через Найти и НайтиСтроки для точного совпадения. Всегда проверяйте результат поиска перед использованием и учитывайте регистр символов.