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