Как в запросе 1С найти строки, содержащие спецсимволы?

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

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

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


ГДЕ
    Контрагент.Наименование ПОДОБНО "%!@#$%^&*()_+{}[]|:\";<>?/.,~`%"

Такой запрос не сработает и вызовет синтаксическую ошибку, потому что строка "!@#$%^&..." воспринимается как последовательность символов, а не как набор альтернатив "любой из этих символов". Давайте разберем правильные и эффективные способы решения этой задачи, которые обеспечат быстрый анализ данных в вашей информационной базе.

Решение 1: Надежный метод с использованием оператора «ИЛИ»

Самый простой и, что важно, универсальный способ — это перечислить условия для каждого искомого символа, объединив их логическим оператором ИЛИ. Этот подход будет работать на всех версиях платформы 1С:Предприятие и со всеми поддерживаемыми системами управления базами данных (СУБД).

Логика проста: мы проверяем, содержит ли строка первый спецсимвол, ИЛИ второй, ИЛИ третий, и так далее. Если хотя бы одно из условий истинно, запись попадет в выборку.

Посмотрим на пример:

Составим запрос, который найдет всех контрагентов, в наименовании которых есть символы "!", "@", "#" или "$".


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

В этом примере символ % является метасимволом и означает любую последовательность символов (включая пустую). Конструкция "%!%" означает, что восклицательный знак может находиться в любом месте строки: в начале, в середине или в конце.

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

  1. Надежность и совместимость: Гарантированно работает на всех СУБД (MS SQL, PostgreSQL, Oracle, IBM DB2).
  2. Простота и читаемость: Условие легко понять даже начинающему разработчику.

Недостатки:

  1. Громоздкость: Если нужно проверить 20-30 символов, текст запроса станет очень длинным и его будет неудобно поддерживать.

Решение 2: Компактный метод с использованием набора символов «[...]»

Язык запросов 1С поддерживает более изящный синтаксис для поиска любого символа из заданного набора. Для этого используются квадратные скобки [...]. Внутри скобок перечисляются все символы, которые мы хотим найти. Если вам требуется автоматизировать подобные фильтры в отчетах, можно использовать расширение для отборов на соответствие шаблону списком.

Давайте перепишем наш запрос с использованием этой конструкции:


ВЫБРАТЬ
    Контрагенты.Ссылка,
    Контрагенты.Наименование
ИЗ
    Справочник.Контрагенты КАК Контрагенты
ГДЕ
    Контрагенты.Наименование ПОДОБНО "%[!@#$%^&*()_+{}\[\]|:"";<>?/.,~`]%"

Разберем синтаксис подробнее:

Важные нюансы и экранирование:

Некоторые символы внутри квадратных скобок могут иметь специальное значение. Важно знать, как их правильно использовать.

Предупреждение о совместимости:

Несмотря на свою элегантность, этот метод имеет серьезный недостаток. Конструкция [...] не поддерживается в СУБД IBM DB2. Если ваше прикладное решение должно работать с этой СУБД, использование данного синтаксиса приведет к ошибкам. В таких случаях следует использовать первый, более надежный метод с оператором ИЛИ.

Альтернативный подход: Фильтрация после выполнения запроса

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


// Этот подход НЕ РЕКОМЕНДУЕТСЯ для больших объемов данных!
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |    Контрагенты.Наименование
    |ИЗ
    |    Справочник.Контрагенты КАК Контрагенты";

Результат = Запрос.Выполнить().Выгрузить();
НужныеСтроки = Новый Массив;

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

Почему этот метод плох для фильтрации?

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

Выводы

Мы рассмотрели три способа поиска строк со спецсимволами. Подведем итог:

  1. Для максимальной надежности и переносимости кода между разными СУБД используйте конструкцию с перечислением условий ПОДОБНО через оператор ИЛИ.
  2. Для краткости и удобства кода, если вы уверены, что ваше решение не будет использоваться с IBM DB2, применяйте синтаксис с квадратными скобками [...].
  3. Избегайте фильтрации данных в цикле после запроса, если есть возможность установить фильтр в самом запросе. Если же вам требуется найти похожие записи с учетом возможных опечаток, лучше использовать специализированный поиск по схожести наименования.
← На главную