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