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