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