При написании запросов в системе 1С:Предприятие программисты часто сталкиваются с необходимостью динамического изменения возвращаемого значения в зависимости от того, содержит ли строковое поле определенную подстроку. Для этого используется комбинация операторов ВЫБОР и ПОДОБНО. Однако на практике новички часто допускают синтаксические ошибки, которые приводят к неработоспособности запроса. В этой статье мы подробно разберем, как правильно реализовать такой выбор, проанализируем типичные ошибки и рассмотрим продвинутые приемы работы с текстовыми данными в запросах.
Для начала выясним причину, по которой запрос автора темы не работал. В языке запросов 1С существует две принципиально разные формы конструкции ВЫБОР. Ошибка заключалась в попытке смешать их синтаксис.
1. Простой выбор (выбранное выражение)
Этот вариант используется для прямого сравнения конкретного поля с набором значений. Его структура выглядит так:
ВЫБОР Поле
КОГДА Значение1 ТОГДА Результат1
КОГДА Значение2 ТОГДА Результат2
ИНАЧЕ РезультатИначе
КОНЕЦ
Важно понимать: в этой форме 1С автоматически подставляет проверку на равенство (Поле = Значение1). Оператор ПОДОБНО здесь использовать технически невозможно, так как синтаксис ожидает конкретное значение для сравнения, а не логическое условие.
2. Универсальный выбор (поисковое условие)
Именно этот вариант нам необходим для решения задачи. Здесь после ключевого слова КОГДА пишется полноценное логическое условие. Рассмотрим правильную структуру:
ВЫБОР
КОГДА Поле ПОДОБНО "%Текст%" ТОГДА Результат1
ИНАЧЕ Поле
КОНЕЦ
В данном случае после КОГДА может стоять любое выражение, результатом которого является логический тип (Истина/Ложь), включая ПОДОБНО, В ИЕРАРХИИ, ЕСТЬ NULL и другие.
Проанализируем ситуацию на конкретном примере. Допустим, нам нужно выбрать наименования справочника "Типы активов", и если в названии встречается корень "Тел", заменить его на фиксированную строку.
Правильный код запроса будет выглядеть следующим образом:
ВЫБРАТЬ
ВЫБОР
КОГДА itilprofТипыАктивов.Наименование ПОДОБНО "%Тел%"
ТОГДА "НеТел!!!!212"
ИНАЧЕ itilprofТипыАктивов.Наименование
КОНЕЦ КАК Поле1
ИЗ
Справочник.itilprofТипыАктивов КАК itilprofТипыАктивов
Разберем по шагам, почему этот вариант работает:
ВЫБОР, перейдя к универсальной форме.КОГДА ... ПОДОБНО ..., которая возвращает булево значение.ИНАЧЕ, чтобы сохранить исходное значение, если условие не выполнилось.Рассмотрим подробнее вторую ошибку, которую часто совершают разработчики — попытку конкатенации строк внутри самого запроса. В Сообщении 1 автор пытался написать "%" + "Тел" + "%".
Запомните: язык запросов 1С не поддерживает оператор сложения строк (+). Если вам нужно собрать маску поиска динамически, у вас есть два пути:
Способ А: Прямое указание в запросе
Если искомая часть строки заранее известна и неизменна, пишите ее целиком в кавычках: "%ВашТекст%".
Способ Б: Использование параметров (рекомендуемый)
Если подстрока поиска вводится пользователем или вычисляется в коде, необходимо подготовить маску заранее в переменной 1С и передать ее как параметр.
Пример в коде 1С:
ТекстПоиска = "Тел";
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВЫБОР
| КОГДА Т.Наименование ПОДОБНО &МаскаПоиска
| ТОГДА ""Найдено""
| ИНАЧЕ ""Не найдено""
| КОНЕЦ КАК Статус
|ИЗ
| Справочник.Номенклатура КАК Т";
// Формируем маску на стороне встроенного языка
Запрос.УстановитьПараметр("МаскаПоиска", "%" + ТекстПоиска + "%");
Результат = Запрос.Выполнить();
Выясним, какие еще символы можно использовать в маске поиска, чтобы сделать ваши запросы более гибкими:
% (процент): заменяет любую последовательность произвольных символов любой длины._ (подчеркивание): заменяет ровно один любой символ. Это полезно, когда важна длина строки.[ ] (квадратные скобки): позволяют искать любой одиночный символ из указанного набора. Например, ПОДОБНО "Тов[ар]" найдет "Това" или "Товр".[^] (отрицание): найдет любой символ, кроме тех, что указаны в скобках.Использование ключевого слова СПЕЦСИМВОЛ (ESCAPE):
Проанализируем ситуацию, когда вам нужно найти в тексте сам символ процента. Если вы напишете ПОДОБНО "%100%%", запрос отработает некорректно. Для этого используется экранирование:
// Ищем строки, содержащие "100%"
КОГДА Номенклатура.Наименование ПОДОБНО "%100#%" СПЕЦСИМВОЛ "#"
Здесь символ # указывает системе, что следующий за ним символ процента нужно воспринимать как обычный текст, а не как служебную команду запроса.
Рассмотрим важный аспект — скорость выполнения. Использование ПОДОБНО в конструкции ВЫБОР может существенно замедлить работу системы, если не соблюдать правила индексации.
Когда вы ставите процент в начале маски ("%Текст"), СУБД (SQL Server, PostgreSQL) не может использовать индексы. Ей приходится выполнять полное сканирование таблицы (Full Scan), то есть прочитывать каждую запись в базе. Если в справочнике 1 000 000 записей, такой ВЫБОР будет "тормозить" весь отчет.
Советы по оптимизации:
ПОДОБНО в динамических списках по полям, которые не индексированы."Текст%". В этом случае индексы будут работать, и запрос выполнится мгновенно.ПОДОБНО регистронезависим, но на Linux/PostgreSQL поведение может зависеть от настроек базы.Напоследок разберем ситуацию с составными типами данных. Оператор ПОДОБНО предназначен только для строк. Если ваше поле itilprofТипыАктивов.Наименование имеет составной тип (например, Строка и Число), запрос может выдать ошибку.
Чтобы обезопасить себя, используйте приведение типов:
ВЫБОР
КОГДА ВЫРАЗИТЬ(Т.Поле КАК СТРОКА(100)) ПОДОБНО "%Тест%"
ТОГДА ...
Функция ВЫРАЗИТЬ гарантирует, что к оператору сравнения попадет именно строковое значение, что предотвратит аварийное завершение запроса.
Таким образом, мы выяснили, что ключ к успеху кроется в выборе правильной формы конструкции ВЫБОР и грамотной подготовке строковых параметров. Используйте универсальную форму ВЫБОР КОГДА ..., и ваши условия с оператором ПОДОБНО будут работать корректно и эффективно.