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