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