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