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