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