При попытке программной установки отбора в объекте ПостроительОтчета разработчики часто сталкиваются с ситуацией, когда отбор в итоговом запросе не срабатывает или остается пустым. Проанализируем основные причины этой проблемы и разберем корректные способы программного управления отборами.
В приведенном коде критическая ошибка заключается в явном отключении использования элемента отбора:
Отбор.Использование = Ложь;
Если свойство Использование имеет значение Ложь, платформа полностью игнорирует данное условие при генерации текста запроса. Для того чтобы отбор вступил в силу, необходимо передать значение Истина:
Отбор.Использование = Истина;
Построитель отчета формирует динамические отборы только для тех полей, которые описаны в секции расширения языка запросов. Если в исходном тексте запроса построителя отсутствует конструкция вида {ГДЕ Таблица.Проект.* КАК Проект}, то программное добавление поля в коллекцию Отбор не приведет к изменению текста запроса.
Также, если текст запроса задается программно прямо перед установкой отборов, необходимо вызвать метод заполнения доступных полей:
Построитель.ЗаполнитьНастройки();
Если требуется последовательно выполнять запрос с разным отбором, нет необходимости каждый раз удалять и снова добавлять элемент отбора в коллекцию. Достаточно найти нужное поле по имени и изменить его свойства. Разберем правильный пример обновления отбора:
Для Каждого Сп Из СписокПроектовОтбор Цикл
ГруппаПроектов = Сп.Значение;
// Находим элемент отбора по имени поля
ЭлементОтбора = Построитель.Отбор.Найти("Проект");
Если ЭлементОтбора = Неопределено Тогда
// Если поле еще не добавлено в отборы, добавляем его
ЭлементОтбора = Построитель.Отбор.Добавить("Проект");
КонецЕсли;
// Включаем использование и задаем параметры
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;
ЭлементОтбора.Значение = ГруппаПроектов;
// Выполняем запрос или формирование отчета
Результат = Построитель.Результат;
// Обработка полученных данных...
КонецЦикла;
Выполнение запросов внутри цикла создает повышенную нагрузку на сервер базы данных. Если задача позволяет получить итоговый результат за один подход, целесообразно заменить цикл одиночным отбором со сравнением ВидСравнения.ВСписке или ВидСравнения.ВИерархии.
Рассмотрим по шагам, как передать весь список значений в отбор построителя:
СписокЗначений с нужными элементами или группами.Построитель.Отбор.ВидСравнения.ВСписке (для точного совпадения) или ВидСравнения.ВИерархии (для отбора с учетом иерархии справочника).Значение передаем подготовленный список.Использование установлено в Истина.Пример реализации отбора по списку значений:
// Формируем список проектов для отбора
СписокПроектов = Новый СписокЗначений;
Для Каждого Элемент Из СписокПроектовОтбор Цикл
СписокПроектов.Добавить(Элемент.Значение);
КонецЦикла;
// Настраиваем отбор в построителе отчета
ЭлементОтбора = Построитель.Отбор.Найти("Проект");
Если ЭлементОтбора = Неопределено Тогда
ЭлементОтбора = Построитель.Отбор.Добавить("Проект");
КонецЕсли;
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке; // или ВидСравнения.ВИерархии
ЭлементОтбора.Значение = СписокПроектов;
// Выполняем построитель один раз
Результат = Построитель.Результат;
Объект ПостроительОтчета является технологией обычного приложения (1С 8.0–8.2). В современных конфигурациях на управляемых формах применяются следующие механизмы:
КомпоновщикНастроек, где элементы добавляются в коллекцию КомпоновщикНастроек.Настройки.Отбор.Элементы.Запрос и передавать список элементов через параметры (Запрос.УстановитьПараметр("Проекты", СписокПроектов)).