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