При разработке запросов в платформе 1С:Предприятие часто возникает задача отфильтровать строковые данные (номера договоров, коды, наименования) по сложному условию: строка должна начинаться с определенного набора символов, но при этом не должна содержать конкретный разделитель (например, косую черту /).
Попытки решить такую задачу с помощью одного универсального шаблона нередко приводят к ошибкам из-за путаницы между возможностями оператора ПОДОБНО и регулярными выражениями.
Проанализируем типичную попытку использовать отрицание внутри шаблона: %[^/]%. Язык запросов 1С действительно поддерживает квадратные скобки [...] и [^...], однако они проверяют условие строго для одного символа в конкретной позиции, а не для всей подстроки.
Шаблон %[^/]% интерпретируется СУБД следующим образом: «в строке должен присутствовать хотя бы один символ, отличный от дроби». Так как в номере вида "АБВ/123" присутствуют буквы и цифры, условие возвращает ИСТИНА, и строка не исключается из результата.
Также ключевое слово СПЕЦСИМВОЛ (ESCAPE) предназначено исключительно для экранирования служебных знаков шаблона (%, _, [, ]), когда их нужно найти в тексте как обычные символы, и не может служить оператором отрицания.
Разберем по шагам правильный подход. Для корректной фильтрации необходимо разделить проверку префикса и проверку наличия нежелательного символа на два независимых условия в секции ГДЕ.
Префикс%.И НЕ и шаблон %/%.Посмотрим на пример реализации запроса:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДоговорыКонтрагентов.Ссылка КАК Договор,
| ДоговорыКонтрагентов.Номер КАК Номер
|ИЗ
| Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов
|ГДЕ
| ДоговорыКонтрагентов.Номер ПОДОБНО &Префикс
| И НЕ ДоговорыКонтрагентов.Номер ПОДОБНО &ШаблонИсключения";
Запрос.УстановитьПараметр("Префикс", ИскомыйПрефикс + "%");
Запрос.УстановитьПараметр("ШаблонИсключения", "%/%");
РезультатЗапроса = Запрос.Выполнить();
Рассмотрим подробнее влияние таких условий на скорость выполнения запроса СУБД:
Номер ПОДОБНО &Префикс + "%" позволяет СУБД выполнять быстрый поиск по индексу (поиск по началу строки). Однако условие с символом процента в начале НЕ Номер ПОДОБНО "%/%" использовать индекс не может и требует сканирования записей.СтрНайти:
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Если СтрНайти(Выборка.Номер, "/") > 0 Тогда
Продолжить;
КонецЕсли;
// Обработка подходящей записи
КонецЦикла;
Такой комбинированный подход снижает нагрузку на СУБД при обработке больших таблиц и гарантирует корректную фильтрацию данных.