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

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

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

Проблема использования конкатенации прямо в тексте запроса

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

ГДЕ Контрагент.Наименование ПОДОБНО &Наименование + "%"

Проанализируем, почему такой подход может не сработать или вызвать ошибку. Во-первых, система компоновки данных — это не просто транслятор запроса, а сложный механизм, который самостоятельно управляет параметрами. Во-вторых, выполнение строковых операций (склеивания) непосредственно в секции ГДЕ может привести к ошибкам на стороне СУБД (например, MS SQL Server или PostgreSQL), особенно если типы данных параметра и поля в таблице различаются (например, неограниченная строка и строка фиксированной длины). На некоторых версиях платформы, например 8.3.18, это может вызывать исключение.

Решение 1: Использование выражения на закладке «Параметры»

Самым правильным и надежным способом в СКД является вынос логики формирования маски поиска в настройки параметров компоновки. Давайте разберем этот метод по шагам:

  1. Перейдем на закладку Параметры в схеме компоновки данных.
  2. Найдем параметр &Наименование, который заполняет пользователь.
  3. Для этого параметра (или для вспомогательного скрытого параметра) в колонке Выражение пропишем код на встроенном языке 1С:

"%" + &Наименование + "%"

В тексте самого запроса при этом мы оставляем максимально простую конструкцию:

ГДЕ Контрагент.Наименование ПОДОБНО &Наименование

Почему это работает лучше? Когда мы используем колонку Выражение, вычисление строки происходит средствами встроенного языка 1С до того, как запрос будет отправлен на сервер базы данных. В СУБД передается уже готовая строка маски (например, "%Газпром%"), что исключает конфликты типов при конкатенации в SQL-запросе.

Решение 2: Работа с необязательными условиями и фигурными скобками

Часто требуется, чтобы условие поиска применялось только тогда, когда пользователь действительно заполнил поле поиска. Рассмотрим ситуацию, когда мы используем расширение языка запросов СКД — фигурные скобки. Проанализируем пример кода:

{ГДЕ (Контрагенты.Наименование ПОДОБНО &Наименование)}

Если мы просто подставим &Наименование, и пользователь его не заполнит, СКД может исключить это условие из итогового запроса. Однако, если у нас настроено выражение "%" + &Наименование + "%", параметр технически всегда будет заполнен (как минимум, символами процента). Чтобы отчет не "тормозил", пытаясь найти все записи по маске "%%", мы можем усложнить выражение в параметрах:


ВЫБОР 
    КОГДА &Наименование = "" ИЛИ &Наименование ЕСТЬ NULL 
    ТОГДА "" 
    ИНАЧЕ "%" + СократитьП(&Наименование) + "%" 
КОНЕЦ

Такой подход позволяет корректно обрабатывать пустые значения и автоматически удалять лишние пробелы, которые пользователь мог случайно ввести.

Влияние на производительность: Поиск по началу vs Поиск по вхождению

Разберем важный технический аспект — использование индексов СУБД (SARGability). Посмотрим на два варианта формирования маски:

Рекомендуем всегда уточнять у бизнес-аналитиков, действительно ли им нужен поиск «везде» или достаточно поиска «с начала строки».

Обработка спецсимволов и конструкция СПЕЦСИМВОЛ (ESCAPE)

Выясним причину, по которой поиск может выдавать неверные результаты, если в названии контрагента встречаются сами символы %, _ или [. Например, нам нужно найти строку "Скидка 10%". Если мы просто передадим ее в ПОДОБНО, символ % будет воспринят как маска любого количества символов.

Для решения этой задачи в языке запросов предусмотрено ключевое слово СПЕЦСИМВОЛ. Рассмотрим пример реализации:

  1. В выражении параметра СКД заменим служебные символы, добавив перед ними экранирующий знак (например, #):
  2. СтрЗаменить(СтрЗаменить(&Наименование, "%", "#%"), "_", "#_") + "%"
  3. В тексте запроса укажем:
  4. ГДЕ Контрагент.Наименование ПОДОБНО &Наименование СПЕЦСИМВОЛ "#"

Это гарантирует, что введенные пользователем знаки процента будут восприняты как обычный текст, а не как команды поиска.

Особенности платформы и типов данных

Проанализируем ситуацию с ошибками на новых версиях платформы (8.3.18 и выше). Одной из частых причин сбоев является тип параметра Строка (неограниченной длины). В SQL-запросах такие поля часто транслируются в типы типа NVARCHAR(MAX) или TEXT, которые имеют ограничения на использование в некоторых операциях сравнения и конкатенации.

Практический совет: Всегда устанавливайте для строковых параметров поиска фиксированную длину (например, 150 или 250 символов) на вкладке параметров СКД. Это упрощает работу оптимизатора запросов СУБД и предотвращает ошибки несовместимости типов.

Регистрозависимость и СУБД

Посмотрим на поведение отчета в разных средах. Если ваша база работает на PostgreSQL, поиск через ПОДОБНО может быть чувствителен к регистру (в отличие от MS SQL Server, где настройки базы обычно позволяют искать без учета регистра). Чтобы сделать поиск универсальным, приводите обе части условия к одному регистру:

ГДЕ ВРЕГ(Контрагент.Наименование) ПОДОБНО &НаименованиеВРегистре

При этом в выражении параметра &НаименованиеВРегистре обязательно используйте функцию ВРЕГ():

ВРЕГ("%" + СократитьП(&Наименование) + "%")

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

← На главную