Как ограничить выбор элементов справочника в отчете на СКД в зависимости от периода?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Ограничения стандартного механизма СКД

Проанализируем, почему задачу сложно решить только стандартными настройками схемы без написания кода:

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

Разберем основные архитектурные решения этой задачи.

Способ 1. Добавление собственной формы отчета и обработка события выбора

Это наиболее гибкий и рекомендуемый подход для внешних и встроенных отчетов. Добавление собственной формы не требует отказа от возможностей СКД, так как платформа автоматически подключает стандартные механизмы компоновки.

Рассмотрим по шагам реализацию через перехват события выбора:

  1. Создадим основную управляемую форму отчета. По умолчанию платформа добавит расширение отчета и свяжет стандартную команду СкомпоноватьРезультат.
  2. В таблице пользовательских настроек или у отдельного поля ввода параметра справочника назначим обработчик события НачалоВыбора (или ПередНачаломВыбора).
  3. В обработчике отключим стандартную обработку, обратимся на сервер для получения списка ссылок за выбранный период и откроем форму выбора с готовым отбором.

Посмотрим на пример кода в модуле формы отчета:


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

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

Способ 2. Динамическая установка доступных значений при изменении периода

Если требуется, чтобы пользователь выбирал элементы из выпадающего списка без открытия модального окна формы выбора, можно использовать метод УстановитьДоступныеЗначения у настроек компоновщика.

Разберем алгоритм реализации:

  1. В форме отчета создаем обработчик ПриИзменении для поля стандартного периода.
  2. При смене дат периода выполняем серверную процедуру, которая выбирает актуальные ссылки запросом.
  3. Формируем объект СписокЗначений и программно передаем его в коллекцию доступных значений параметра компоновщика.

Посмотрим на пример заполнения доступных значений:


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

Способ 3. Использование связей параметров выбора и расширения формы справочника

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

Разберем по шагам данный вариант:

  1. В схеме компоновки данных на вкладке Параметры для целевого параметра справочника заполняем свойство Связи параметров выбора: передаем в качестве параметров даты стандартного периода.
  2. В расширение конфигурации заимствуем форму выбора справочника (или используем общую форму).
  3. В процедуре ПриСозданииНаСервере формы выбора проверяем наличие переданных параметров отчета.
  4. Если параметры периода переданы, выполняем запрос к регистру и накладываем программный отбор на динамический список формы:

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

Таким образом, для получения гибкого управления отбором рекомендуется добавить форму в отчет и обработать событие НачалоВыбора, а при невозможности менять форму отчета — задействовать механизм связей параметров выбора в сочетании с расширением формы справочника.

← На главную