Как реализовать поиск точного слова в запросе 1С, избегая вхождения в другие слова?

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

При работе с текстовыми данными в 1С программисты часто сталкиваются с задачей поиска конкретного слова (лексемы) в строке. Стандартный подход с использованием оператора ПОДОБНО и маски %Текст% не всегда эффективен, так как он находит вхождения части слова в более длинные конструкции. Например, при поиске аббревиатуры "АБС" система выдаст и "Датчик АБС" (что правильно), и "Топливный абсорбер" (что является ложным срабатыванием). Рассмотрим детально, как решить эту задачу различными методами, начиная от классических запросов и заканчивая современными возможностями платформы.

Метод 1. Использование оператора ПОДОБНО с перебором вариантов

Разберем классический подход. Проблема оператора ПОДОБНО в том, что он не понимает границ слова. Чтобы выделить именно слово "АБС", нам нужно убедиться, что оно окружено либо пробелами, либо знаками препинания, либо находится в самом начале или конце строки. Проанализируем ситуацию и составим комбинированное условие.

Для корректного поиска слова "АБС" в тексте нам придется описать все возможные позиции этого слова. Рассмотрим пример кода запроса:


ВЫБРАТЬ
    Номенклатура.Ссылка КАК Ссылка,
    Номенклатура.Наименование КАК Наименование
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    (Номенклатура.Наименование ПОДОБНО "АБС %"
    ИЛИ Номенклатура.Наименование ПОДОБНО "% АБС %"
    ИЛИ Номенклатура.Наименование ПОДОБНО "% АБС"
    ИЛИ Номенклатура.Наименование = "АБС")

Важный нюанс: Этот метод не учитывает знаки препинания, такие как скобки или тире. Если в базе есть позиция "Тормозные (АБС) колодки", вышеуказанный запрос ее не найдет. Чтобы расширить поиск, нам пришлось бы добавлять условия для каждого спецсимвола, что крайне неэффективно и тяжело читаемо.

Метод 2. Искусственное расширение строки пробелами

Выясним причину, по которой предыдущий метод кажется громоздким. Нам приходится отдельно обрабатывать начало и конец строки. Существует изящный "хак", позволяющий упростить условие. Мы можем программно добавить пробелы к проверяемому полю прямо в тексте запроса. Проанализируем этот подход:


ВЫБРАТЬ
    Номенклатура.Ссылка
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    " " + Номенклатура.Наименование + " " ПОДОБНО "% АБС %"

Добавляя пробел в начало и в конец наименования, мы гарантируем, что искомое слово "АБС" всегда будет окружено пробелами, даже если оно стояло в самом начале или в самом конце оригинальной строки. Однако помните, что такая конструкция полностью отключает использование индексов СУБД, так как мы применяем функцию к индексируемому полю. На больших таблицах это приведет к значительному замедлению работы.

Метод 3. Полнотекстовый поиск (ППД)

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


СписокСсылок = Новый Массив;
СтрокаПоиска = """АБС"""; // Используем кавычки для поиска точного слова
РезультатПоиска = ПолнотекстовыйПоиск.СоздатьСписок(СтрокаПоиска, 100);
РезультатПоиска.ПерваяЧасть();

Для Каждого СтрокаРезультата Из РезультатПоиска Цикл
    Если ТипЗнч(СтрокаРезультата.Значение) = Тип("СправочникСсылка.Номенклатура") Тогда
        СписокСсылок.Добавить(СтрокаРезультата.Значение);
    КонецЕсли;
КонецЦикла;

Преимущества метода:

  1. Высокая скорость работы благодаря предварительно подготовленным индексам.
  2. Автоматическая обработка разделителей (скобки, точки, запятые).
  3. Возможность поиска с учетом морфологии (если требуется).

Недостатки: поиск зависит от актуальности индекса. Если товар был создан секунду назад, он не попадет в результат, пока не отработает регламентное задание по обновлению индекса ППД.

Метод 4. Регулярные выражения (Платформа 8.3.24 и выше)

Рассмотрим долгожданное обновление платформы. Начиная с версии 8.3.24, в языке запросов появился оператор СООТВЕТСТВУЕТ (в англоязычном варианте MATCHES). Это позволяет использовать всю мощь регулярных выражений (RegExp) непосредственно на уровне СУБД.

Для поиска слова "АБС" как отдельной единицы в регулярных выражениях используется метасимвол границы слова \b. Разберем, как это выглядит в коде:


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	Номенклатура.Ссылка
    |ИЗ
    |	Справочник.Номенклатура КАК Номенклатура
    |ГДЕ
    |	Номенклатура.Наименование СООТВЕТСТВУЕТ &ШаблонПоиска";

Запрос.УстановитьПараметр("ШаблонПоиска", ".*\bАБС\b.*");

Этот метод является наиболее современным и надежным. Он автоматически учитывает любые символы, не являющиеся буквами или цифрами, как границы слова.

Метод 5. Постобработка через RegExp (для старых платформ)

Если ваша платформа ниже версии 8.3.24, а использовать ППД невозможно, рекомендуется применить двухэтапную фильтрацию. На первом этапе мы выбираем данные "широким" запросом, а на втором — уточняем результат с помощью объекта VBScript.RegExp.

Проанализируем алгоритм:

  1. Выполняем запрос с условием ПОДОБНО "%АБС%". Это быстро отсечет 99% ненужных данных.
  2. Выгружаем результат в таблицу значений.
  3. В цикле проверяем каждое наименование регулярным выражением.

РегВыражение = Новый COMОбъект("VBScript.RegExp");
РегВыражение.IgnoreCase = Истина;
РегВыражение.Global = Ложь;
РегВыражение.Pattern = "\bАБС\b";

ТаблицаРезультатов = Запрос.Выполнить().Выгрузить();
ИндексСтроки = 0;
Пока ИндексСтроки < ТаблицаРезультатов.Количество() Цикл
    Строка = ТаблицаРезультатов[ИндексСтроки];
    Если НЕ РегВыражение.Test(Строка.Наименование) Тогда
        ТаблицаРезультатов.Удалить(Строка);
    Иначе
        ИндексСтроки = ИндексСтроки + 1;
    КонецЕсли;
КонецЦикла;

Такой комбинированный подход позволяет сохранить производительность системы и добиться идеальной точности поиска.

Рекомендации по выбору метода

Выясним, какой метод лучше в конкретной ситуации. Если вы работаете на современной платформе 8.3.24+, всегда используйте СООТВЕТСТВУЕТ. Это стандарт индустрии. Если база большая (сотни тысяч позиций номенклатуры) и поиск выполняется часто, настройте Полнотекстовый поиск. Для разовых задач в небольших базах вполне подойдет метод с добавлением пробелов в условии ПОДОБНО, несмотря на его неоптимальность.

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

← На главную