Как использовать оператор ПОДОБНО с параметрами и представлениями в запросах 1С?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке отчетов и запросов в системе 1С:Предприятие программисты часто сталкиваются с необходимостью текстового сопоставления данных. Типичный сценарий — проверка вхождения одной строки в другую с использованием оператора ПОДОБНО (аналога SQL-оператора LIKE). Однако попытки гибко настроить это сопоставление внутри самого запроса (например, привести ссылку к строке или использовать функцию представления) часто приводят к ошибкам синтаксического контроля платформы.

В этой статье мы подробно разберем, почему возникают ошибки вида «Неверные параметры ПОДОБНО», опровергнем популярные заблуждения с форумов и рассмотрим действительно работающие и эффективные методики решения этой задачи, особенно в контексте Системы компоновки данных (СКД).

Анализ проблемы: почему стандартный подход вызывает ошибку?

Рассмотрим типичную ситуацию. Разработчик пытается написать в запросе следующее условие:


ГДЕ
    ВТ.Наименование ПОДОБНО ПРЕДСТАВЛЕНИЕ(&МойСправочник)

Или его вариацию:


ГДЕ
    ВТ.Наименование ПОДОБНО ВЫРАЗИТЬ(&МойСправочник КАК СТРОКА(10))

При попытке сохранения или выполнения такого запроса система незамедлительно выдаст ошибку. Давайте выясним причину такого поведения платформы. Согласно официальным стандартам разработки 1С (в частности, стандарту std726 «Особенности использования в запросах оператора ПОДОБНО»), синтаксис данного оператора строго ограничен:


<Выражение> [НЕ] ПОДОБНО <Литерал типа СТРОКА> [СПЕЦСИМВОЛ <Литерал типа СТРОКА>]

Это означает, что в правой части оператора ПОДОБНО (после самого ключевого слова) допускается использовать исключительно константный строковый литерал (например, "%Иванов%") или одиночный параметр запроса (например, &ШаблонИмени). Любые попытки вычислить строку «на лету» внутри запроса с помощью конкатенации (оператора +), использования функций типа ВЫРАЗИТЬ, ПОДСТРОКА или ПРЕДСТАВЛЕНИЕ в правой части оператора приведут к ошибке разбора запроса.

Важное предупреждение: на многих форумах (и в сообщении 7 данной ветки) предлагается якобы «работающее» решение:


ГДЕ ВТ.Наименование ПОДОБНО "%" + Выразить(&МойСправочник как Справочник.Номенклатура).Наименование + "%"

Проанализировав данную конструкцию, мы должны со всей ответственностью заявить: это решение синтаксически неверно и работать не будет! Платформа 1С не умеет динамически конкатенировать шаблоны поиска непосредственно внутри оператора ПОДОБНО в SQL-запросе.

---

Решение 1. Формирование параметра на стороне встроенного языка (Классический метод)

Если вы выполняете запрос из кода на встроенном языке 1С, самым простым и правильным решением будет перенос операции формирования шаблона поиска из запроса в код подготовки параметров. Рассмотрим этот процесс по шагам.

Шаг 1. В тексте запроса мы оставляем чистый и понятный параметр:


ВЫБРАТЬ
    Таблица.Ссылка КАК Ссылка,
    Таблица.Наименование КАК Наименование
ИЗ
    Справочник.Номенклатура КАК Таблица
ГДЕ
    Таблица.Наименование ПОДОБНО &ШаблонПоиска

Шаг 2. Перед запуском запроса мы формируем значение этого параметра во встроенном языке, добавляя необходимые метасимволы (например, знак процента % для поиска по подстроке):


Запрос = Новый Запрос;
Запрос.Текст = ПолучитьТекстЗапроса(); // Загружаем наш текст запроса

// Получаем строковое представление или реквизит справочника
ТекстДляПоиска = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(&МойСправочник, "Наименование");

// Формируем шаблон с процентами с двух сторон для поиска вхождения
ШаблонСтроки = "%" + ТекстДляПоиска + "%";

Запрос.УстановитьПараметр("ШаблонПоиска", ШаблонСтроки);
Выборка = Запрос.Выполнить().Выбрать();

Этот метод полностью соответствует стандартам платформы, легко читается и не вызывает проблем при компиляции запроса СУБД.

---

Решение 2. Использование возможностей СКД (Рекомендуемый метод для отчетов)

Если вы разрабатываете отчет на базе Системы компоновки данных (СКД), то вам нет необходимости писать дополнительный код на встроенном языке. СКД предоставляет великолепные декларативные механизмы решения этой проблемы.

Вариант А. Выражения параметров СКД

Мы можем перенести логику «склеивания» строки шаблона непосредственно в настройки параметров схемы компоновки данных. Выполним следующие действия:

  1. В тексте запроса СКД пишем условие с чистым параметром: ГДЕ ВТ.Наименование ПОДОБНО &ШаблонИмени.
  2. Переходим на вкладку «Параметры» в конструкторе схемы компоновки данных.
  3. Находим наш параметр &ШаблонИмени и устанавливаем для него флаг «Ограничение доступности» (чтобы пользователь не вводил его вручную).
  4. В колонке «Выражение» для этого параметра пишем формулу: "%" + Выразить(&МойСправочник, "Справочник.Номенклатура").Наименование + "%" (или просто "%" + ПРЕДСТАВЛЕНИЕ(&МойСправочник) + "%").

При генерации отчета СКД сама вычислит это выражение на сервере приложений, сформирует готовую строку (например, "%Товар%") и корректно передаст ее в параметры SQL-запроса.

Вариант Б. Использование стандартных отборов СКД

Еще более изящный способ — отказаться от жесткого кодирования секции ГДЕ в запросе и доверить это механизму компоновки:

  1. Оставляем запрос без условий фильтрации по наименованию.
  2. В настройках СКД (на вкладке «Отбор» в пользовательских настройках или настройках по умолчанию) добавляем новый элемент отбора.
  3. В качестве левого значения выбираем поле Наименование.
  4. Вид сравнения устанавливаем в положение «Содержит» (что эквивалентно ПОДОБНО "%...%").
  5. В качестве правого значения выбираем реквизит нашего параметра: &МойСправочник.Наименование.

Платформа автоматически сформирует оптимальный SQL-запрос, выполнив безопасное приведение типов и экранирование спецсимволов.

---

Решение 3. Реализация через левое или внутреннее соединение

Бывают ситуации, когда вам нужно решить задачу исключительно в рамках одного запроса без привлечения кода и СКД. В этом случае на помощь приходит связывание таблиц. Мы можем соединить нашу исходную таблицу со справочником по условию равенства ссылки, а затем сопоставить наименования.

Рассмотрим пример внутреннего соединения:


ВЫБРАТЬ
    ВТ.Ссылка КАК Ссылка,
    ВТ.Наименование КАК Наименование
ИЗ
    ВременнаяТаблица КАК ВТ
    ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК СпрНоменклатура
        ПО СпрНоменклатура.Ссылка = &МойСправочник
        И ВТ.Наименование ПОДОБНО "%" + СпрНоменклатура.Наименование + "%"

Обратите внимание: в секции ПО (или ГДЕ при связи таблиц) СУБД некоторых конфигураций позволяет выполнять операции сопоставления полей, однако этот метод имеет серьезные недостатки с точки зрения производительности.

---

Важные нюансы производительности и безопасности СУБД

При работе с текстовым поиском и оператором ПОДОБНО крайне важно помнить о физическом устройстве баз данных:

Подводя итог, отметим, что наиболее гибким, безопасным и современным методом решения задачи сопоставления строк по параметру-ссылке является использование выражений параметров в СКД. Это разделяет логику формирования условий поиска и само выполнение запроса к базе данных, обеспечивая стабильную работу вашего приложения.

← На главную