Как использовать ПОДОБНО в 1С: шаблоны, экранирование и скорость
Содержание
Оператор ПОДОБНО в 1С проверяет строку на соответствие шаблону прямо в запросе: Контрагенты.Наименование ПОДОБНО "%банк%" вернёт всех контрагентов, в названии которых есть слово «банк». В шаблоне % заменяет любое число символов, _ — ровно один символ, [...] — один символ из списка. Это аналог LIKE из SQL, и платформа при выполнении запроса переводит его в LIKE конкретной СУБД.
Выбор простой. Нужен поиск по началу, концу или вхождению строки в запросе — берите ПОДОБНО. Нужно проверить строку в модуле, уже после выборки, — ПОДОБНО там не работает
, используйте СтрНайти(), СтрНачинаетсяС() или регулярные выражения. Нужен поиск по смыслу во всей базе — полнотекстовый поиск.
Синтаксис ПОДОБНО в языке запросов
Общая форма условия:
<Выражение> ПОДОБНО <Шаблон> [СПЕЦСИМВОЛ <Символ>]
- 📌 Выражение — поле строкового типа:
Наименование,Номердокумента,ИНН,Комментарий. - 📌 Шаблон — строковый литерал в кавычках или параметр запроса (
&Шаблон). - 📌 СПЕЦСИМВОЛ — необязательная часть. Задаёт символ экранирования, если в искомом тексте есть
%,_или скобки.
Отрицание пишется через НЕ: НЕ Товары.Артикул ПОДОБНО "ТЕСТ%". Ключевое слово можно писать и по-английски: LIKE и ESCAPE — запрос на английском синтаксисе работает так же.
Результат условия — ИСТИНА или ЛОЖЬ. Поэтому ПОДОБНО ставят не только в ГДЕ, но и в ВЫБОР КОГДА:
ВЫБОР
КОГДА Контрагенты.Наименование ПОДОБНО "ИП %"
ТОГДА "Предприниматель"
ИНАЧЕ "Организация"
КОНЕЦ КАК ВидЛица
В конструкторе запроса оператор вводят на вкладке «Условия»: отметьте флажок произвольного условия и впишите выражение вручную.
Сравнивается строка целиком. Шаблон "банк" без процентов найдёт только значения, равные «банк» полностью, — это обычное равенство, только медленнее.
Символы шаблона: процент, подчёркивание и квадратные скобки
В шаблоне ПОДОБНО четыре служебные конструкции. Всё остальное сравнивается как есть.
| Символ | Что означает | Шаблон | Подходит | Не подходит |
|---|---|---|---|---|
% | любое число любых символов, в том числе ноль | "ООО%" | ООО Ромашка, ООО | АО ООО |
_ | ровно один любой символ | "А_-01" | АБ-01, А7-01 | А-01, АБВ-01 |
[...] | один символ из списка или диапазона | "[АБ]%" | Альфа, Бета | Вега |
[^...] | один символ, которого нет в списке | "[^0-9]%" | Счёт 15 | 15 счёт |
Диапазон внутри скобок пишется через дефис: [0-9], [А-Я], [A-Z]. Можно смешивать: [0-9A-F] — одна шестнадцатеричная цифра.
Знаки ? и * в 1С шаблонами не являются. Это привычка из Windows и Excel. Шаблон "Ива*" ищет строку, которая буквально заканчивается звёздочкой.
Сколько раз символ повторяется, шаблоном не задать: квантификаторов вроде {10} нет. Десять цифр подряд пишут десятью скобками [0-9] или проверяют длину отдельно.
Примеры запросов с ПОДОБНО на практике
Начинается с, содержит, заканчивается на
// Контрагенты-ИП
ГДЕ Контрагенты.Наименование ПОДОБНО "ИП %"
// Номенклатура, в названии которой есть «кабель»
ГДЕ Номенклатура.Наименование ПОДОБНО "%кабель%"
// Документы с номером, оканчивающимся на 15
ГДЕ Реализация.Номер ПОДОБНО "%15"
Проверка формата: поиск «грязных» ИНН
Классическая задача перед сдачей отчётности — найти контрагентов с мусором в ИНН. Шаблон ловит любую нецифру в любом месте:
ВЫБРАТЬ
Контрагенты.Ссылка,
Контрагенты.ИНН
ИЗ
Справочник.Контрагенты КАК Контрагенты
ГДЕ
Контрагенты.ИНН ПОДОБНО "%[^0-9]%"
Так находятся пробелы, буквы «О» вместо нуля, точки и дефисы. Обратная проверка — строго десять цифр у юрлица:
ГДЕ НЕ Контрагенты.ИНН ПОДОБНО "[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"
И НЕ Контрагенты.ИНН ПОДОБНО "[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"
Запрос вернёт тех, у кого ИНН не 10 и не 12 цифр.
Поиск по реквизиту ссылки
С самой ссылкой ПОДОБНО не работает — нужна строка. Обращайтесь к реквизиту через точку:
ГДЕ Реализация.Контрагент.Наименование ПОДОБНО "%Ромашка%"
Разыменование Контрагент.Наименование добавляет соединение с таблицей справочника. На больших журналах это заметно, об этом ниже.
Несколько вариантов в одном условии
Отдельного «ИЛИ внутри шаблона» нет. Варианты объединяют обычным ИЛИ:
ГДЕ Номенклатура.Наименование ПОДОБНО "%кабель%"
ИЛИ Номенклатура.Наименование ПОДОБНО "%провод%"
Шаблон из параметра
Строку поиска почти всегда вводит пользователь. Шаблон собирают в коде и передают параметром:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка,
| Номенклатура.Наименование
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Наименование ПОДОБНО &Шаблон";
Запрос.УстановитьПараметр("Шаблон", "%" + СтрокаПоиска + "%");
Выборка = Запрос.Выполнить().Выбрать();
Такой код рабочий, но с дырой: если пользователь введёт 50% или [1], шаблон поведёт себя не так, как он ждёт. Лечится экранированием.
Поиск по нескольким словам в любом порядке
Пользователь вводит «кабель медный», а в справочнике товар называется «Медный кабель ВВГ 3х2,5». Один шаблон "%кабель медный%" его не найдёт. Решение — разбить ввод на слова и на каждое слово поставить своё условие через И:
Слова = СтрРазделить(СокрЛП(СтрокаПоиска), " ", Ложь);
Условия = Новый Массив;
Запрос = Новый Запрос;
Для Индекс = 0 По Слова.ВГраница() Цикл
ИмяПараметра = "Слово" + Формат(Индекс, "ЧН=0; ЧГ=0");
Условия.Добавить("Номенклатура.Наименование ПОДОБНО &" + ИмяПараметра + " СПЕЦСИМВОЛ ""~""");
Запрос.УстановитьПараметр(ИмяПараметра, "%" + ЭкранироватьДляПодобно(Слова[Индекс]) + "%");
КонецЦикла;
Дальше условия склеивают через СтрСоединить(Условия, " И ") и подставляют в ГДЕ. Проверку на пустой массив Слова сделайте до сборки запроса, иначе получится ГДЕ без условий. Функция ЭкранироватьДляПодобно описана в следующем разделе.
Экранирование спецсимволов через СПЕЦСИМВОЛ
Задача: найти товары со скидкой «50%» в названии. Шаблон "%50%%" не поможет — третий процент тоже станет «любыми символами». Нужно сказать платформе, что этот процент — обычный символ.
Для этого выбирают символ экранирования, которого точно нет в данных (чаще всего ~), и ставят его перед служебным знаком:
ГДЕ Номенклатура.Наименование ПОДОБНО "%50~%%" СПЕЦСИМВОЛ "~"
Читается так: любые символы, затем «50%», затем любые символы.
Функция экранирования для пользовательского ввода
Экранировать нужно пять знаков: %, _, [, ], ^ — и сам символ экранирования. Его заменяют первым, иначе удвоятся уже вставленные тильды:
Функция ЭкранироватьДляПодобно(Знач Строка, Знач СпецСимвол = "~")
Результат = СтрЗаменить(Строка, СпецСимвол, СпецСимвол + СпецСимвол);
Для Каждого Символ Из СтрРазделить("%,_,[,],^", ",") Цикл
Результат = СтрЗаменить(Результат, Символ, СпецСимвол + Символ);
КонецЦикла;
Возврат Результат;
КонецФункции
И её использование. В тексте запроса внутри строки кавычки удваиваются:
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Наименование ПОДОБНО &Шаблон СПЕЦСИМВОЛ ""~""";
Запрос.УстановитьПараметр("Шаблон", "%" + ЭкранироватьДляПодобно(СокрЛП(СтрокаПоиска)) + "%");
Проверим на примере. Пользователь ввёл 50%_А. Функция вернёт 50~%~_А, шаблон станет %50~%~_А% — ищется буквальная подстрока «50%_А».
Не подставляйте строку поиска в текст запроса склейкой ("... ПОДОБНО ""%" + СтрокаПоиска + "%"""). Кавычка во вводе сломает запрос. Параметр защищает от этого и упрощает чтение кода.
Почему запрос с ПОДОБНО тормозит и как ускорить
Скорость ПОДОБНО зависит от того, где стоит первый %.
| Шаблон | Как СУБД ищет | Скорость на большой таблице |
|---|---|---|
"ООО%" — начало строки | может пройти по индексу, как по алфавитному указателю | быстро |
"%банк%" — вхождение | перебирает все строки таблицы | медленно |
"%15" — конец строки | перебирает все строки | медленно |
Шаблон с ведущим процентом на справочнике в 2 000 элементов незаметен. На регистре в миллионы записей это полное сканирование, и запрос может идти минуты.
Что помогает:
- 🔎 Сначала сузить, потом искать. Поставьте в
ГДЕбыстрые условия — период, организацию, вид номенклатуры — иПОДОБНОпоследним. Оптимизатор СУБД обычно применит индексные условия первыми. - 📂 Искать в справочнике, а не в журнале. Вместо
Реализация.Контрагент.Наименование ПОДОБНО "%Ромашка%"сначала найдите ссылки контрагентов во временной таблице, потом отберите документы поКонтрагент В (ВЫБРАТЬ Ссылка ИЗ ВТ_Контрагенты). - ✂️ Предлагать поиск по началу. Для подбора в формах часто хватает шаблона
Строка + "%". Пользователь вводит «Ром» — получает «Ромашка» быстро. - 🗂️ Индексировать реквизит. Поиск по началу строки выигрывает, только если у реквизита в конфигураторе задано свойство «Индексировать». Для доработки типовой конфигурации это делают через расширение или с согласования с тем, кто ведёт обновления.
- 📄 Ограничивать выборку.
ВЫБРАТЬ ПЕРВЫЕ 50в окне подбора избавляет от выгрузки тысяч строк на клиент.
Индекс на строку неограниченной длины не строится. Поиск Комментарий ПОДОБНО "%...%" по большим документам всегда идёт перебором.
ПОДОБНО в файловой базе, MS SQL и PostgreSQL
Платформа стремится, чтобы один и тот же запрос давал одинаковый результат на любой СУБД. Разработчику не нужно переписывать шаблон при переносе базы. Различия в основном в скорости и мелочах.
- 💾 Файловая база. Запрос выполняет сама платформа. На небольших базах поиск с ведущим
%проходит быстро, на базах в десятки гигабайт начинает ощутимо тормозить. - 🗄️ MS SQL Server.
ПОДОБНОпереводится вLIKE. Регистр при стандартной сортировке базы (для 1С обычно выбирают регистронезависимую кириллическую) не учитывается. Поиск по началу строки использует индекс. - 🐘 PostgreSQL. В сборках для 1С строки хранятся в специальных типах, которые сравниваются без учёта регистра, так что «Банк» и «банк» находятся одинаково. Ведущий
%так же приводит к перебору таблицы.
Не создавайте индексы и расширения вроде триграммного поиска прямо в СУБД, в обход конфигурации. Платформа о них не знает: при реструктуризации их удалит, а в случае сбоя такую базу сложнее поддерживать.
Есть нюанс со строками фиксированной длины. Если у реквизита в конфигураторе указана фиксированная допустимая длина, короткое значение дополняется пробелами до полной. Шаблон «заканчивается на» "%01" может не найти такое значение. Если подозреваете этот случай, проверьте свойство реквизита или добавьте % в конец шаблона.
Чем заменить ПОДОБНО: строковые функции и другие способы
В тексте запроса
Кроме ПОДОБНО, в языке запросов давно есть ПОДСТРОКА(Строка, Начало, Длина). В платформе 8.3.20 и новее добавились функции для строк: ДЛИНАСТРОКИ, СТРНАЙТИ, ЛЕВ, ПРАВ, ВРЕГ, НРЕГ, СОКРЛП и другие. Если платформа не ниже этой версии, часть задач решается точнее:
- длина ИНН —
ДЛИНАСТРОКИ(Контрагенты.ИНН) В (10, 12); - позиция подстроки —
СТРНАЙТИ(Наименование, "банк") > 0.
Для простой проверки вхождения ПОДОБНО по-прежнему короче и работает на любой версии 8.3.
Числа и даты ПОДОБНО не принимает, а привести число к строке в запросе нельзя: ВЫРАЗИТЬ(Число КАК Строка) выдаст ошибку. Такие отборы делают сравнением (МЕЖДУ, >=) или после выборки в коде.
Во встроенном языке
Внутри модуля оператора ПОДОБНО нет. Строку проверяют функциями:
| Задача | Функция |
|---|---|
| Содержит подстроку | СтрНайти(Строка, "банк") > 0 |
| Начинается с | СтрНачинаетсяС(Строка, "ООО") |
| Заканчивается на | СтрЗаканчиваетсяНа(Строка, "-01") |
| Сложный формат | СтрСоответствуетШаблону(Строка, Шаблон) — регулярное выражение, с платформы 8.3.23 |
Учтите: СтрНайти и СтрНачинаетсяС чувствительны к регистру. Чтобы найти «Банк» и «банк», приведите обе строки к одному виду через ВРег().
В отчётах и динамических списках
В системе компоновки данных отдельный запрос писать не нужно. У отбора есть виды сравнения «Содержит», «Начинается с» и «Подобно» — платформа сама соберёт условие. Для поиска по всем данным базы есть полнотекстовый поиск. Его включают в администрировании, и индекс нужно регулярно обновлять регламентным заданием.