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