При написании сложных запросов в платформе 1С:Предприятие разработчики нередко сталкиваются с ошибкой «Несовместимые типы (Выразить)» при попытке ограничить или преобразовать данные в секции ГДЕ. Разберем по шагам, почему возникает эта ошибка, как работает функция ВЫРАЗИТЬ и как правильно построить условие с оператором ПОДОБНО.
Проанализируем две ключевые синтаксические ошибки, которые часто допускаются в запросах:
ВЫРАЗИТЬ. В отличие от конструкции CAST в классическом SQL, функция ВЫРАЗИТЬ в языке запросов 1С не умеет преобразовывать один базовый тип данных в другой (например, ссылку в строку или число в строку). Она предназначена исключительно для ограничения длины строк/чисел неограниченной длины или для приведения составного типа данных к конкретному типу. Выражение ВЫРАЗИТЬ(Компьютеры.Родитель КАК СТРОКА(64)) является синтаксически неверным, так как поле Родитель является ссылкой на справочник, а не строкой.ВЫРАЗИТЬ к параметрам запроса. Конструкция вида ВЫРАЗИТЬ(&Параметр КАК ...) вызывает ошибку платформы. Тип параметра определяется в момент его передачи во встроенном языке с помощью метода УстановитьПараметр(), поэтому приведение типа параметра внутри текста запроса недопустимо и не требуется.Рассмотрим, как правильно получить строковое представление объекта для поиска. Чтобы проверить текстовое описание родителя, необходимо обращаться напрямую к его строковому реквизиту — чаще всего это Наименование или Код:
И НЕ Компьютеры.Родитель.Наименование ПОДОБНО &Исключение
Если реквизит Наименование имеет стандартный строковый тип с ограниченной длиной, применять к нему функцию ВЫРАЗИТЬ не требуется вовсе.
Выясним причину частой ошибки при формировании подстроки поиска. В языке запросов 1С конкатенация строк с параметрами в секции ГДЕ (например, ПОДОБНО "%" + &Исключение + "%") не поддерживается синтаксисом.
Посмотрим на правильный подход: спецсимволы маски поиска % (любое количество символов) и _ (один произвольный символ) необходимо добавлять в значение параметра во встроенном языке до выполнения запроса.
// Формируем текст запроса
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Компьютеры.Ссылка КАК СерийныйНомер,
| Компьютеры.Контрагент КАК Контрагент
|ИЗ
| Справочник.Компьютеры КАК Компьютеры
|ГДЕ
| НЕ Компьютеры.Родитель.Наименование ПОДОБНО &Исключение";
// Передаем параметр со спецсимволами поиска
СтрокаПоиска = "ТестоваяГруппа";
Запрос.УстановитьПараметр("Исключение", "%" + СтрокаПоиска + "%");
РезультатЗапроса = Запрос.Выполнить();
Разберем альтернативный вариант решения, если задача заключается в исключении элементов определенной папки. Поиск по подстроке наименования с маской в начале (%Текст%) приводит к полному сканированию таблицы СУБД (Full Table Scan) и снижает производительность системы.
Если требуется исключить группу справочника и всех ее потомков, гораздо эффективнее использовать проверку иерархии через оператор В ИЕРАРХИИ:
ГДЕ
НЕ Компьютеры.Ссылка В ИЕРАРХИИ (&ИсключаемаяГруппа)
Такой отбор задействует индексы базы данных и выполняется значительно быстрее, чем строковое сравнение через ПОДОБНО.