Как в отчете на СКД программно обработать расшифровку и открыть другой отчет с параметрами?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке аналитических отчетов в 1С на базе Системы компоновки данных (СКД) часто возникает задача: при двойном клике на ячейку отчета открыть другой (детализирующий) отчет, передав в него значения группировок текущей строки и колонки (например, конкретную статью расхода и собственника). В типовом механизме СКД это работает автоматически, однако при ручном формировании отчета или необходимости нестандартного поведения разработчики сталкиваются с тем, что расшифровка возвращает лишь числовой идентификатор либо не срабатывает вовсе. Разберем по шагам, как правильно настроить программное формирование отчета и обработать событие расшифровки на управляемых формах.

Шаг 1. Программное формирование отчета и инициализация данных расшифровки

Главная причина, по которой расшифровка не работает при ручной компоновке макета, заключается в отсутствии инициализации объекта ДанныеРасшифровкиКомпоновкиДанных. Чтобы платформа связала ячейки табличного документа с исходными полями и группировками, этот объект необходимо передать и в компоновщик макета, и в процессор компоновки данных.

Рассмотрим серверную процедуру формирования отчета, где результат помещается в поле табличного документа на форме, а адрес данных расшифровки сохраняется во временном хранилище:


&НаСервере
Процедура СформироватьОтчетНаСервере()
    
    // Получаем схему компоновки данных
    СхемаКомпоновкиДанных = Отчеты.АР_ОтчетПоРасходам.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
    
    // Получаем актуальные настройки из компоновщика
    Настройки = Отчет.КомпоновщикНастроек.ПолучитьНастройки();
    
    // Создаем объект для сбора информации о расшифровке
    ДанныеРасшифровки = Новый ДанныеРасшифровкиКомпоновкиДанных;
    
    // Инициализируем компоновщик макета
    КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
    МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки, ДанныеРасшифровки);
    
    // Инициализируем процессор компоновки
    ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, , ДанныеРасшифровки);
    
    // Очищаем табличный документ на форме и настраиваем вывод
    ТабДок = Элементы.Результат;
    ТабДок.Очистить();
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ТабДок);
    ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
    
    // Сохраняем данные расшифровки во временное хранилище и записываем адрес в реквизит формы
    АдресХранилищаДанныхРасшифровки = ПоместитьВоВременноеХранилище(ДанныеРасшифровки, УникальныйИдентификатор);
    
    // Важно: связываем расширение формы отчета с данными расшифровки
    ДанныеРасшифровки = АдресХранилищаДанныхРасшифровки;
    
КонецПроцедуры

Обратим внимание на важный нюанс: объект ДанныеРасшифровкиКомпоновкиДанных существует только на стороне сервера. Для того чтобы клиентская форма знала о контексте расшифровки, мы сохраняем его адрес во временном хранилище и привязываем к стандартному реквизиту расширения формы ДанныеРасшифровки или отдельному реквизиту формы АдресХранилищаДанныхРасшифровки (тип Строка).

Шаг 2. Настройка поля табличного документа на форме

Проанализируем распространенную ошибку, из-за которой событие расшифровки не срабатывает при двойном клике: если у поля табличного документа свойство ТолькоПросмотр установлено в значение Ложь, двойной клик активирует режим редактирования текста в ячейке. Для корректной работы расшифровки необходимо убедиться, что для табличного документа включен режим только для чтения:

  1. В свойствах элемента формы Результат устанавливаем флаг ТолькоПросмотр в значение Истина.
  2. В палитре свойств элемента в событии ОбработкаРасшифровки указываем имя клиентского обработчика, например РезультатОбработкаРасшифровки.

Шаг 3. Извлечение значений группировок по идентификатору расшифровки

В обработчик РезультатОбработкаРасшифровки платформа передает параметр Расшифровка — это числовой идентификатор элемента в коллекции ДанныеРасшифровки.Элементы. Чтобы получить значения полей, находящихся на пересечении строк и колонок (например, группировку по собственнику и статью расхода), необходимо на сервере обойти родителей текущего элемента расшифровки.

Посмотрим на реализацию клиентской и серверной части:


&НаКлиенте
Процедура РезультатОбработкаРасшифровки(Элемент, Расшифровка, СтандартнаяОбработка)
    
    Если Расшифровка = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Отключаем стандартное контекстное меню расшифровки
    СтандартнаяОбработка = Ложь;
    
    // Получаем структуру со значениями полей на сервере
    ПараметрыРасшифровки = ПолучитьПараметрыРасшифровкиНаСервере(Расшифровка);
    
    // Открываем детализирующий отчет
    ОткрытьДетализирующийОтчет(ПараметрыРасшифровки);
    
КонецПроцедуры

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

&НаСервере
Процедура ОбойтиРодителейРасшифровки(Родитель, Результат)
    
    Если ТипЗнч(Родитель) = Тип("ЭлементРасшифровкиКомпоновкиДанныхГруппировка") Тогда
        Для Каждого Поле Из Родитель.ПолучитьПоля() Цикл
            Если Не Результат.Свойство(Поле.Поле) Тогда
                Результат.Вставить(Поле.Поле, Поле.Значение);
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
    
    Для Каждого Вышестоящий Из Родитель.ПолучитьРодителей() Цикл
        ОбойтиРодителейРасшифровки(Вышестоящий, Результат);
    КонецЦикла;
    
КонецПроцедуры

Шаг 4. Открытие второго отчета с переданными параметрами

Когда параметры из ячейки получены в структуру (например, получены поля Собственник и Расход), остается открыть форму второго отчета. В платформе 1С 8.3 для отчетов на СКД предусмотрен механизм автоматической установки отборов через стандартную структуру параметров формы Отбор.

Рассмотрим клиентскую процедуру открытия второго отчета:


&НаКлиенте
Процедура ОткрытьДетализирующийОтчет(ПараметрыРасшифровки)
    
    // Формируем структуру отбора для подчиненного отчета
    СтруктураОтбора = Новый Структура;
    
    Если ПараметрыРасшифровки.Свойство("Собственник") И ЗначениеЗаполнено(ПараметрыРасшифровки.Собственник) Тогда
        СтруктураОтбора.Вставить("Собственник", ПараметрыРасшифровки.Собственник);
    КонецЕсли;
    
    Если ПараметрыРасшифровки.Свойство("Расход") И ЗначениеЗаполнено(ПараметрыРасшифровки.Расход) Тогда
        СтруктураОтбора.Вставить("Расход", ПараметрыРасшифровки.Расход);
    КонецЕсли;
    
    // Передаем параметры в форму целевого отчета
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("Отбор", СтруктураОтбора);
    ПараметрыФормы.Вставить("СформироватьПриОткрытии", Истина);
    
    // Открываем основную форму второго отчета
    ОткрытьФорму("Отчет.АР_ДетализацияРасходов.Форма", ПараметрыФормы, ЭтотОбъект);
    
КонецПроцедуры

Если в схеме компоновки второго отчета присутствуют доступные поля отбора с именами Собственник и Расход, платформа автоматически применит переданные значения в компоновщике настроек и сформирует отчет при открытии благодаря параметру СформироватьПриОткрытии = Истина.

Таким образом, сочетание правильной инициализации ДанныеРасшифровкиКомпоновкиДанных, сохранения адреса во временном хранилище и обхода родителей элементов расшифровки позволяет организовать плавный и гибкий переход между отчетами любой сложности на управляемых формах.

← На главную