Как в запросе 1С выбрать строки с определенным префиксом, исключив строки с указанным символом?

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

При разработке запросов в платформе 1С:Предприятие часто возникает задача отфильтровать строковые данные (номера договоров, коды, наименования) по сложному условию: строка должна начинаться с определенного набора символов, но при этом не должна содержать конкретный разделитель (например, косую черту /).

Попытки решить такую задачу с помощью одного универсального шаблона нередко приводят к ошибкам из-за путаницы между возможностями оператора ПОДОБНО и регулярными выражениями.

Разбор распространенной ошибки: почему не работает шаблон с отрицанием

Проанализируем типичную попытку использовать отрицание внутри шаблона: %[^/]%. Язык запросов 1С действительно поддерживает квадратные скобки [...] и [^...], однако они проверяют условие строго для одного символа в конкретной позиции, а не для всей подстроки.

Шаблон %[^/]% интерпретируется СУБД следующим образом: «в строке должен присутствовать хотя бы один символ, отличный от дроби». Так как в номере вида "АБВ/123" присутствуют буквы и цифры, условие возвращает ИСТИНА, и строка не исключается из результата.

Также ключевое слово СПЕЦСИМВОЛ (ESCAPE) предназначено исключительно для экранирования служебных знаков шаблона (%, _, [, ]), когда их нужно найти в тексте как обычные символы, и не может служить оператором отрицания.

Решение: разделение условий с помощью логического оператора И НЕ

Разберем по шагам правильный подход. Для корректной фильтрации необходимо разделить проверку префикса и проверку наличия нежелательного символа на два независимых условия в секции ГДЕ.

  1. В первом условии проверяем начало строки с помощью шаблона Префикс%.
  2. Во втором условии отсекаем строки, содержащие символ дроби, через связку И НЕ и шаблон %/%.

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


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

Запрос.УстановитьПараметр("Префикс", ИскомыйПрефикс + "%");
Запрос.УстановитьПараметр("ШаблонИсключения", "%/%");

РезультатЗапроса = Запрос.Выполнить();

Особенности производительности и оптимизация

Рассмотрим подробнее влияние таких условий на скорость выполнения запроса СУБД:

  1. Использование индексов: Условие Номер ПОДОБНО &Префикс + "%" позволяет СУБД выполнять быстрый поиск по индексу (поиск по началу строки). Однако условие с символом процента в начале НЕ Номер ПОДОБНО "%/%" использовать индекс не может и требует сканирования записей.
  2. Постобработка во встроенном языке: Если первое условие по префиксу возвращает относительно небольшую выборку, имеет смысл исключить условие с отрицанием из запроса и выполнить быструю фильтрацию на встроенном языке с помощью функции СтрНайти:

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    Если СтрНайти(Выборка.Номер, "/") > 0 Тогда
        Продолжить;
    КонецЕсли;
    
    // Обработка подходящей записи
КонецЦикла;

Такой комбинированный подход снижает нагрузку на СУБД при обработке больших таблиц и гарантирует корректную фильтрацию данных.

← На главную