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