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