Как сделать параметры в СКД необязательными для заполнения

Программист IT и автоматизация бизнеса
← На главную

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

Причина проблемы: Почему 1С требует заполнения параметров

Когда мы прописываем условие в тексте запроса, например, ГДЕ ЗаказПокупателя.Статус В (&СтатусыЗаказов), платформа ожидает, что в переменную &СтатусыЗаказов будет передано конкретное значение или список. Если пользователь оставляет поле пустым, SQL-запрос не может быть корректно сформирован, что приводит к системной ошибке. Нам же нужно добиться поведения, при котором фрагмент запроса с условием просто исчезает, если параметр не задан.

Решение 1: Использование фигурных скобок {} в тексте запроса

Основной и самый эффективный способ сделать параметр необязательным — это использование синтаксиса фигурных скобок, которые предназначены специально для расширения языка запросов в интересах компоновки данных. Рассмотрим, как правильно оформить условия.

Проанализируем ситуацию, когда у нас есть два фильтра: по периоду отгрузки и по статусам заказов. Если мы запишем их обычным способом через И, оба станут обязательными. Чтобы сделать их независимыми и необязательными, применим следующую конструкцию в параметрах виртуальной таблицы или в секции ГДЕ:


{(ЗаказПокупателя.ДатаОтгрузки МЕЖДУ &НачалоПериодаОтгрузки И &КонецПериодаОтгрузки), 
 (ЗаказПокупателя.Status В (&СтатусыЗаказов))}

Разберем по шагам, как это работает:

  1. Механизм парсинга: Когда СКД готовит итоговый запрос к базе данных, она проверяет свойство Использование у каждого параметра. Если параметр не заполнен (и у него не стоит флаг "Всегда"), компоновщик просто удаляет весь текст, находящийся внутри соответствующих фигурных скобок.
  2. Разделители: Обратите внимание на запятую между условиями в скобках. Это позволяет системе обрабатывать каждое условие независимо. Если не заполнен только период — удалится первая часть, если не заполнены статусы — вторая. Если не заполнено ничего — весь блок условий будет проигнорирован.
  3. Синтаксис условий: Внутри скобок можно использовать стандартные операторы сравнения, такие как МЕЖДУ, В, =, > и другие.

Решение 2: Настройка на закладке «Компоновка данных»

Если вы предпочитаете использовать визуальный конструктор, те же действия можно выполнить на закладке Компоновка данных в конструкторе запроса. Рассмотрим этот метод подробнее:

Перейдите на закладку Таблицы, выберите нужную (например, виртуальную таблицу остатков или оборотов) и откройте её параметры. Вместо обычного прописывания условий в стандартных полях, перейдите на вкладку Условия внутри настроек компоновки этой таблицы. Здесь вы можете добавить поля, которые превратятся в необязательные фильтры. Платформа сама обернет их в фигурные скобки в итоговом тексте запроса.

Важный момент: если вы используете параметры в тексте запроса напрямую (через амперсанд &), убедитесь, что на закладке Параметры в схеме СКД для них установлено свойство Использование в значение Авто. Если установить Всегда, то даже наличие фигурных скобок не спасет от ошибки при незаполненном значении.

Решение 3: Обработка пустых значений через выражения СКД

Иногда требуется более сложная логика: например, если дата не указана, нужно брать "начало времен" или "конец времен". В этом случае мы можем не использовать фигурные скобки, а поработать с колонкой Выражение на закладке Параметры.

Проанализируем пример для параметра &КонецПериода. Мы можем прописать выражение, которое подставит максимально возможную дату, если пользователь ничего не выбрал:


ВЫБОР 
    КОГДА &КонецПериода = ДатаВремя(1, 1, 1) 
    ТОГДА ДатаВремя(3999, 12, 31, 23, 59, 59) 
    ИНАЧЕ &КонецПериода 
КОНЕЦ

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

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

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

Для удобства пользователя рекомендуется:

Профессиональные хитрости и оптимизация

Рассмотрим несколько нюансов, которые помогут сделать ваши отчеты быстрее и стабильнее:

  1. Виртуальные таблицы: Всегда старайтесь помещать необязательные условия внутрь параметров виртуальных таблиц (в фигурных скобках), а не в секцию ГДЕ. Это критически важно для производительности, так как 1С сможет отсечь лишние данные на уровне индексов, а не перебирать всю выборку в памяти.
  2. Пустые ссылки: Будьте осторожны с параметрами ссылочного типа. Если пользователь выбрал в поле "Пустую ссылку" (например, строку "Объект не обнаружен" или просто очистил выбор до состояния "Пустой справочник"), система может считать параметр заполненным. Чтобы этого избежать, внутри условий СКД можно добавить проверку ЗНАЧЕНИЕ(Справочник.СтатусыЗаказов.ПустаяСсылка).
  3. Программное управление: В некоторых случаях, если логика очень сложная, можно управлять использованием параметров в модуле объекта отчета через КомпоновщикНастроек.Настройки.ПараметрыДанных. У каждого параметра есть свойство Использование, которое можно устанавливать в Ложь программно перед генерацией макета.

Таким образом, использование фигурных скобок {} является наиболее грамотным и "чистым" способом реализации необязательных фильтров в 1С. Это избавляет от необходимости писать сложный код обработки пустых значений и позволяет платформе максимально эффективно оптимизировать SQL-запросы.

← На главную