Как реализовать зависимый выбор в отборах СКД при отсутствии прямой связи в метаданных?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Промышленность, строительство и АПК
← На главную

В разработке отчетов на базе Системы компоновки данных (СКД) часто возникает задача создания зависимых фильтров. Классический пример: при выборе организации в списке договоров должны отображаться только договора этой организации. Однако ситуация усложняется, когда нам нужно связать поля, которые не имеют прямой связи в структуре метаданных. Например, необходимо отфильтровать список «Объектов», основываясь на выбранном «Договоре», при этом в справочнике Объекты нет реквизита Договор, а связь между ними существует только косвенно — через документы Реализация.

Разберем подробно, как решить эту задачу, используя стандартные и программные механизмы платформы «1С:Предприятие 8».

Метод 1. Настройка связей параметров выбора в схеме СКД

Это наиболее «чистый» способ с точки зрения архитектуры компоновки данных. Даже если в справочнике-приемнике нет нужного реквизита, мы можем передать значение одного отбора в параметры выбора другого. Проанализируем, как это настроить:

  1. Откроем схему компоновки данных и перейдем на закладку «Наборы данных».
  2. Найдем в списке полей наше поле Объект.
  3. В колонке «Параметры выбора» или «Связи параметров выбора» нажмем на кнопку выбора.
  4. В появившемся окне укажем связь: в качестве параметра выберем имя, которое мы будем ловить в форме выбора (например, Отбор.Договор), а в качестве выражения — поле компоновки Договор.

Важный нюанс: Чтобы этот механизм заработал для справочника, у которого нет физической связи с договором, нам потребуется дополнительно обработать этот параметр в модуле менеджера справочника Объекты.

Метод 2. Использование события ОбработкаПолученияДанныхВыбора

Поскольку платформа не может автоматически отфильтровать справочник Объекты по договору (так как поле отсутствует), нам нужно помочь ей программно. Рассмотрим реализацию в модуле менеджера справочника Объекты:


Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка)
    
    Если Параметры.Свойство("Договор") И ЗначениеЗаполнено(Параметры.Договор) Тогда
        СтандартнаяОбработка = Ложь;
        
        Запрос = Новый Запрос;
        Запрос.Текст = 
            "ВЫБРАТЬ РАЗЛИЧНЫЕ
            |    РеализацияТоваровУслуг.ОбъектСтроительства КАК Объект
            |ИЗ
            |    Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
            |ГДЕ
            |    РеализацияТоваровУслуг.ДоговорКонтрагента = &Договор";
        
        Запрос.УстановитьПараметр("Договор", Параметры.Договор);
        СписокОбъектов = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Объект");
        
        // Формируем данные выбора на основе найденных объектов
        ДанныеВыбора = Новый СписокЗначений;
        ДанныеВыбора.ЗагрузитьЗначения(СписокОбъектов);
    КонецЕсли;
    
КонецПроцедуры

Этот метод позволяет динамически формировать список доступных объектов в момент, когда пользователь нажимает кнопку выбора в отчете.

Метод 3. Программная установка параметров в форме отчета

Если у вашего отчета есть форма, мы можем управлять поведением отборов через события элементов формы. Рассмотрим ситуацию, когда пользователь меняет значение договора в настройках отчета. Нам нужно обновить условия выбора для поля объекта.

Выясним алгоритм действий:

  1. В событии ПриИзменении поля отбора, отвечающего за Договор, мы получаем текущее значение.
  2. Находим в пользовательских настройках компоновки поле Объект.
  3. Устанавливаем для него свойство ПараметрыВыбора.

Пример программного кода для формы:


&НаКлиенте
Процедура ОтборДоговорПриИзменении(Элемент)
    
    ТекущийДоговор = Элемент.Родитель.ТекущиеДанные.Значение;
    
    // Передаем структуру параметров в элемент формы, отвечающий за выбор объекта
    НовыйПараметр = Новый ПараметрВыбора("Отбор.Ссылка", ПолучитьМассивОбъектовПоДоговору(ТекущийДоговор));
    МассивПараметров = Новый Массив;
    МассивПараметров.Добавить(НовыйПараметр);
    
    // Устанавливаем параметры выбора для поля Объект
    Элементы.КомпоновщикНастроекПользовательскиеНастройкиЗначение.ПараметрыВыбора = Новый ФиксированныйМассив(МассивПараметров);
    
КонецПроцедуры

Метод 4. Перехват компоновки в ПриКомпоновкеРезультата

Проанализируем ситуацию, когда нам нужно гарантировать корректность данных в самом запросе СКД, независимо от того, что выбрал пользователь. В модуле отчета можно использовать процедуру ПриКомпоновкеРезультата.

Здесь мы можем программно прочитать установленный пользователем отбор по договору, выполнить запрос к документам реализации и принудительно добавить в настройки компоновщика отбор по списку найденных объектов. Это исключит попадание в отчет «чужих» объектов, даже если пользователь ввел их вручную.

Использование механизма характеристик

Существует еще один продвинутый способ «связать несвязуемое» внутри СКД. Мы можем виртуально добавить реквизит Договор к справочнику Объекты через механизм Характеристик. Для этого в настройках типа объекта в СКД указывается запрос, который сопоставляет объекты и договора (например, по данным регистра или документов). После этого платформа начнет видеть Договор как «дочернее» поле Объекта, и стандартные связи параметров выбора заработают автоматически без написания кода в модулях менеджера.

Резюмируем: Для реализации отбора в отборе при отсутствии прямых ссылок в метаданных лучше всего сочетать настройку «Связи параметров выбора» в схеме СКД с обработкой этих параметров в модуле менеджера справочника через ОбработкаПолученияДанныхВыбора. Это обеспечит интуитивно понятную работу интерфейса для пользователя.

← На главную