Как передать настройки и отбор СКД из документа в отчет в 1С

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

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

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

Выясним причину проблемы и особенности работы компоновщика

В платформе 1С:Предприятие 8 на управляемых формах элемент КомпоновщикНастроекКомпоновкиДанных содержит несколько слоев настроек:

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

Простая попытка загрузить настройки через метод Форма.Отчет.КомпоновщикНастроек.ЗагрузитьНастройки() перед вызовом Форма.Открыть() часто приводит к тому, что настройки сбрасываются при инициализации формы платформой. Если же передавать отборы через фиксированные настройки при наличии совпадений по полям, система выдаст ошибку о пересечении элементов.

Способ 1. Передача отбора через параметр формы «ФиксированныеНастройки»

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

Разберем пример кода, где из формы документа получается текущий отбор и передается в параметры открытия формы отчета:


&НаСервере
Функция ПолучитьНастройкиОтбора()
    // Получаем объект НастройкиКомпоновкиДанных из реквизита формы
    Возврат Отбор.ПолучитьНастройки(); 
КонецФункции

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

При таком подходе платформа автоматически подмешивает переданные настройки к отчету. Однако следует учитывать: если в самом отчете по умолчанию уже активирован отбор по тому же полю (например, Номенклатура), платформа вызовет исключение из-за пересечения отборов.

Способ 2. Программный обход и изменение элементов отбора компоновщика

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

Процедура ищет необходимое поле компоновки в отборе отчета. Если оно уже существует — обновляет вид сравнения и значение, если нет — добавляет новый элемент отбора:


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

КонецПроцедуры

Рассмотрим применение этой функции при открытии формы отчета:


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

Важные рекомендации по работе с отборами СКД

  1. Учитывайте пользовательские настройки: Если реквизит выведен на панель быстрых настроек отчета, изменения в КомпоновщикНастроек.Настройки.Отбор могут перекрываться значениями из КомпоновщикНастроек.ПользовательскиеНастройки. В таких случаях нужно также синхронизировать значение в коллекции пользовательских настроек по идентификатору или наименованию параметра.
  2. Избегайте дублирования: Ошибка «Пересекаются элементы отбора» чаще всего решается путем отключения (Использование = Ложь) или удаления аналогичного отбора в схеме отчета перед применением фиксированных настроек.
  3. Работайте с иерархией: При проверке элементов отбора помните, что в отбор могут входить группы элементов (ГруппаЭлементовОтбораКомпоновкиДанных с условиями «И», «ИЛИ»). Для их корректной обработки требуется рекурсивный обход.
← На главную