В процессе разработки часто возникает задача анализа текстовых данных, например, проверка наличия ключевого слова в комментарии или наименовании объекта. В 1С:Предприятии существует несколько способов реализации этой задачи, каждый из которых имеет свои нюансы. Проанализируем ситуацию, когда необходимо вывести определенный параметр, если в строке встречается нужная подстрока.
Рассмотрим ситуацию, с которой столкнулся автор темы. Был написан следующий код:
Если СтрНайти(НРег(ДоговорКонтрагента.Комментарий), "прол") Тогда
ОбластьМакета.Параметры.Комментарий = "Пролонгация";
Иначе
// КонецЕсли;
КонецЕсли;
На первый взгляд код выглядит логичным, но он может работать некорректно или вызывать споры среди разработчиков. Выясним причину. Функция СтрНайти возвращает не логическое значение (Истина или Ложь), а число — номер позиции, с которой начинается искомая подстрока. Если подстрока не найдена, функция возвращает 0.
Хотя платформа 1С поддерживает неявное преобразование типов (где 0 интерпретируется как Ложь, а любое другое число — как Истина), хорошим тоном считается явное указание условия. Правильный и надежный вариант выглядит так:
Если СтрНайти(НРег(ДоговорКонтрагента.Комментарий), "прол") > 0 Тогда
ОбластьМакета.Параметры.Комментарий = "Пролонгация";
КонецЕсли;
Начиная с версии платформы 8.3.10, разработчикам доступен более элегантный способ решения этой задачи. Разберем работу функции СтрСодержит. Она специально создана для проверки наличия подстроки и возвращает значение типа Булево.
Посмотрим на пример использования:
Если СтрСодержит(НРег(ДоговорКонтрагента.Комментарий), "прол") Тогда
ОбластьМакета.Параметры.Комментарий = "Пролонгация";
КонецЕсли;
Использование СтрСодержит делает код более читаемым и исключает необходимость задумываться о возвращаемых числах и неявных преобразованиях типов. Мы настоятельно рекомендуем использовать именно этот метод в новых разработках на актуальных версиях платформы.
Важно помнить, что во встроенном языке 1С функции поиска строк чувствительны к регистру. Это означает, что "Прол", "прол" и "ПРОЛ" — это разные строки. Чтобы поиск был универсальным, мы приводим всю строку к нижнему регистру с помощью функции НРег, как показано в примерах выше. Также можно использовать ВРег (верхний регистр) — главное, чтобы и искомый текст, и строка поиска были в одном регистре.
Если нам нужно найти данные не в уже полученном объекте, а непосредственно в базе данных, мы используем язык запросов. Здесь логика поиска отличается. Вместо функций встроенного языка используется оператор ПОДОБНО.
Рассмотрим пример условия в запросе:
ГДЕ
ДоговорКонтрагента.Комментарий ПОДОБНО "%прол%"
В данном случае символ % является спецсимволом, означающим любое количество любых символов. Напишем по шагам, что это значит:
"%прол%" — найдет вхождения в любом месте строки."прол%" — найдет строки, начинающиеся на "прол"."%прол" — найдет строки, заканчивающиеся на "прол".Важный технический момент: использование процента в начале шаблона ("%текст") отключает использование индексов SQL-сервером, что может значительно замедлить выполнение запроса на больших таблицах. Проанализируйте объем ваших данных перед использованием таких условий.
Иногда простого поиска подстроки недостаточно. Например, если нужно найти слово "прол", но исключить "пролил" или "пролез". В таких случаях на помощь приходят регулярные выражения. В 1С они реализуются через COM-объект VBScript.RegExp. При необходимости можно использовать компоненту для организации нечеткого поиска в текстовых данных.
Посмотрим на пример кода для более точного поиска:
RegExp = Новый COMОбъект("VBScript.RegExp");
RegExp.IgnoreCase = Истина; // Игнорировать регистр
RegExp.Global = Истина;
RegExp.Pattern = "\bпрол\w*"; // Ищем слово, начинающееся на "прол"
Если RegExp.Test(ДоговорКонтрагента.Комментарий) Тогда
// Обработка совпадения
КонецЕсли;
Разберем одну из самых частых логических ошибок. Если в качестве искомой подстроки передать пустую строку "", функции СтрНайти и СтрСодержит всегда вернут положительный результат (1 или Истина). Это происходит потому, что математически считается, что пустая строка содержится в начале любой строки.
Чтобы избежать ошибок, всегда проверяйте искомое значение перед поиском:
ИскомоеСлово = "прол";
Если ЗначениеЗаполнено(ИскомоеСлово) И СтрСодержит(Комментарий, ИскомоеСлово) Тогда
// Действие
КонецЕсли;
Если в вашей базе данных хранятся миллионы договоров и вам нужно выполнять поиск по комментариям крайне быстро, стандартные строковые функции в цикле или простые запросы могут не справиться. В 1С реализован механизм Полнотекстового поиска.
Он работает на основе предварительно созданных индексов и позволяет находить данные мгновенно, учитывая морфологию русского языка (поиск по корню слова). Для реализации такого поиска программно используется объект ПолнотекстовыйПоиск. В качестве альтернативы можно воспользоваться инструментом для семантического поиска по справочникам на основе смысла.
Для простых задач во встроенном языке используйте СтрСодержит (на новых платформах) или СтрНайти(...) > 0. Для работы с базой данных — оператор ПОДОБНО в запросах. Всегда помните о регистре символов и проверяйте входные данные на пустоту, чтобы ваш код работал надежно и предсказуемо.