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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Анализ проблемы: почему СписокЗначений не работает с обычным параметром

Рассмотрим распространенную ситуацию. Разработчик передает список значений в параметр данных через компоновщик настроек следующим образом:


ПараметрПользователь = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("Пользователь");
ПараметрПользователь.Использование = Истина;
ПараметрПользователь.Значение = СписокПользователей;

Если в тексте запроса СКД условие прописано как строгое равенство ГДЕ Пользователь = &Пользователь, платформа не сможет корректно сопоставить одиночное поле таблицы и объект СписокЗначений. В результате отчет либо выдаст ошибку несоответствия типов, либо вернет данные только по первому элементу списка, либо вовсе сформирует пустой результат.

Способ 1. Настройка параметра запроса СКД на работу со списком

Разберем по шагам, как правильно адаптировать параметр запроса СКД для приема списка значений:

  1. Изменение текста запроса: откроем схему компоновки данных и найдем условие фильтрации. Заменим оператор равенства = на оператор вхождения В:
    
    ВЫБРАТЬ
        Продажи.Ссылка,
        Продажи.Пользователь,
        Продажи.Сумма
    ИЗ
        Документ.Продажи КАК Продажи
    ГДЕ
        Продажи.Пользователь В (&Пользователь)
    
  2. Настройка свойств параметра в схеме: перейдем на вкладку Параметры в схеме компоновки данных. Найдем параметр Пользователь и обязательно установим флажок Доступен список значений. Если этот флаг не установлен, платформа будет интерпретировать параметр как одиночное значение.
  3. Программная передача списка значений: передадим список значений в компоновщик настроек:
    
    ПараметрПользователь = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("Пользователь");
    ПараметрПользователь.Использование = Истина;
    
    Список = Новый СписокЗначений;
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    Пользователи.Ссылка КАК Ссылка
    |ИЗ
    |    Справочник.Пользователи КАК Пользователи
    |ГДЕ
    |    Пользователи.ЭтоГруппа = ЛОЖЬ";
    
    Результат = Запрос.Выполнить().Выгрузить();
    Для Каждого Стр Из Результат Цикл
        Список.Добавить(Стр.Ссылка);
    КонецЦикла;
    
    ПараметрПользователь.Значение = Список;
    

Способ 2. Использование расширения языка запросов СКД для отбора всех значений

Проанализируем задачу, когда пользователю требуется сформировать отчет по всем элементам без необходимости заполнять массив всеми ссылками из базы. Если список огромен, передача тысяч элементов через условие В (&Параметр) создает избыточную нагрузку на СУБД.

Оптимальным решением является использование синтаксиса расширения языка запросов СКД с фигурными скобками:


ВЫБРАТЬ
    Продажи.Ссылка,
    Продажи.Пользователь,
    Продажи.Сумма
ИЗ
    Документ.Продажи КАК Продажи
{ГДЕ
    Продажи.Пользователь В (&Пользователь)}

В этом случае, если отчет формируется по всем пользователям, достаточно просто отключить параметр:


ПараметрПользователь = КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти("Пользователь");
ПараметрПользователь.Использование = Ложь;

СКД автоматически исключит блок ГДЕ из итогового SQL-запроса, и СУБД вернет данные по всем записям без наложения лишних фильтров.

Способ 3. Программная работа через стандартный механизм отборов СКД

Вместо жестко прописанных параметров запроса можно воспользоваться штатной коллекцией отборов компоновщика настроек. Это дает возможность динамически менять виды сравнения (например, использовать иерархический отбор).

Рассмотрим пример создания отбора с видом сравнения ВСписке программно:


ЭлементОтбора = КомпоновщикНастроек.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Пользователь");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.ВСписке; // или ВидСравненияКомпоновкиДанных.ВСпискеПоИерархии
ЭлементОтбора.ПравоеЗначение = СписокПользователей;
ЭлементОтбора.Использование = Истина;

При таком подходе СКД сама добавляет необходимые условия фильтрации в запрос, не требуя жесткого объявления параметров на этапе конструирования схемы.

Важные нюансы работы с пользовательскими настройками

Обратим внимание на частую проблему: если параметр или отбор выведен в область пользовательских настроек на форме отчета, изменение свойства КомпоновщикНастроек.Настройки может быть перезаписано значениями из пользовательских настроек при компоновке макета.

Чтобы значение гарантированно применилось, необходимо находить и модифицировать элемент в коллекции КомпоновщикНастроек.ПользовательскиеНастройки.Элементы по его идентификатору пользовательской настройки, либо очищать пользовательские настройки перед установкой новых значений.

← На главную