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