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