Как получить значение параметров отчета при расшифровке в СКД

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

При разработке отчетов на базе Системы компоновки данных (СКД) часто возникает ситуация, когда стандартной расшифровки недостаточно. Например, когда пользователь нажимает на определенную номенклатуру в отчете «Остатки на складах», нам нужно открыть детальный отчет или форму, учитывая не только саму номенклатуру, но и выбранный в шапке отчета Склад или Период. В этом материале мы подробно разберем, как программно перехватить параметры отчета в момент клика по ячейке и использовать их для дальнейших действий.

Зачем это нужно?

По умолчанию механизм расшифровки 1С передает только контекст текущей строки. Если склад выведен в группировку выше или выбран в параметрах и не отображается в строке, система может «забыть» о нем при открытии дочерней формы. Чтобы отчет-расшифровка сформировался корректно, нам необходимо передать в него полные настройки исходного отчета.

Рассмотрим несколько способов решения этой задачи: от использования стандартного объекта ДанныеРасшифровки до передачи контекста через ДополнительныеПараметры.

Способ 1. Получение параметров через объект ДанныеРасшифровки

Это самый надежный способ, так как он позволяет извлечь именно те значения параметров, с которыми был реально сформирован отчет (даже если пользователь изменил значения на форме, но не нажал кнопку «Сформировать»).

Проанализируем работу в обработчике события РезультатОбработкаРасшифровки. В этом методе нам доступен идентификатор расшифровки, по которому мы можем получить все данные компоновки. Посмотрим на пример кода:


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

КонецПроцедуры

Важный нюанс: параметры могут находиться не в основной коллекции ПараметрыДанных, а в ПользовательскиеНастройки. Для получения итогового значения, которое видит пользователь, рекомендуется использовать метод КомпоновщикНастроек.ПолучитьНастройки(), который объединяет все слои настроек в один объект.

Способ 2. Использование Компоновщика настроек формы

Если расшифровка выполняется в модуле формы того же отчета, мы можем обратиться к КомпоновщикуНастроек напрямую. Это проще, но нужно учитывать, что значения в компоновщике могут отличаться от тех, что были применены при формировании, если пользователь успел их отредактировать «на лету».

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

  1. Обращаемся к свойству Отчет.КомпоновщикНастроек.
  2. Проверяем наличие значения в пользовательских настройках (так как чаще всего параметры выносятся именно туда).
  3. Если там пусто, берем значение из основных настроек.

// Пример получения значения параметра "ДатаОтчета"
ИмяПараметра = "ДатаОтчета";
ПараметрОбъект = Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы.Найти(ИмяПараметра);

// Проверяем, не переопределено ли значение пользователем
Если ПараметрОбъект.Использование Тогда
    ТекущаяДатаОтчета = ПараметрОбъект.Значение;
КонецЕсли;

Способ 3. Передача через ДополнительныеПараметры (Управляемые формы)

Этот метод часто используется, когда нужно передать контекст между разными процедурами (например, из обработки нажатия в процедуру завершения выбора действия). Мы можем «насовать» (как выразились участники форума) нужные нам данные в структуру ДополнительныеПараметры.

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


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

В процедуре завершения мы сможем легко извлечь эти данные:


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

Способ 4. Получение значения из иерархии группировок

Бывает так, что параметр «Склад» не просто задан в шапке, а является одной из группировок отчета. В этом случае, если пользователь кликнул на «Номенклатуру», которая находится внутри группировки «Склад», мы можем программно подняться вверх по дереву расшифровки.

Проанализируем ситуацию: каждый элемент расшифровки имеет родителя. Мы можем перебирать родителей до тех пор, пока не найдем поле с именем Склад.


// Фрагмент серверного кода для анализа структуры расшифровки
Данные = ПолучитьИзВременногоХранилища(ДанныеРасшифровки);
ТекущийЭлемент = Данные.Элементы[Расшифровка];

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

Резюме

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

Используя эти методы, вы сможете создавать гибкие и интерактивные отчеты, которые ведут себя предсказуемо и предоставляют пользователю именно ту информацию, которую он ожидает увидеть при детализации данных.

← На главную