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