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