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