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