Дано:
-Отчет на СКД с кучей независимых друг от друга группировок.
-Форма отчета со страницами и табличными документами результата отчета на них.
Требуется вывести каждую группировку в соответствующий ей табличный документ.
Что я сделал:
На форме отчета сделал свою кнопку "Сформировать". Событием "ПриКомпоновкеРезультата" не удалось воспользоваться, т.к. из этого события нет доступа к табличным документам на форме отчета.
В процедуре вывода отчета используем следующий код:
&НаКлиенте
Процедура СформироватьОтчет(Команда)
СформироватьОтчетНаСервере();
КонецПроцедуры
&НаСервере
Процедура СформироватьОтчетНаСервере()
ОбъектОтчета = РеквизитФормыВЗначение("Отчет");
//Подготавливаем таблицы отчета для вывода
МассивТаблиц = Новый Массив;
МассивТаблиц.Добавить(Таблица1);
МассивТаблиц.Добавить(Таблица2);
МассивТаблиц.Добавить(Таблица3);
МассивТаблиц.Добавить(Таблица4);
МассивТаблиц.Добавить(Таблица5);
МассивТаблиц.Добавить(Таблица6);
МассивТаблиц.Добавить(Таблица7);
МассивТаблиц.Добавить(ТаблицаДополнительно);
Для Каждого Таблица из МассивТаблиц Цикл
Таблица.Очистить();
КонецЦикла;
//Подготавливаем процессоры вывода для каждой таблицы
МассивПроцессоровВыводаТаблиц = Новый Массив;
ПроцессорВывода1 = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода2 = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода3 = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода4 = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода5 = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода6 = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода7 = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВыводаДополнительно = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
МассивПроцессоровВыводаТаблиц.Добавить(ПроцессорВывода1);
МассивПроцессоровВыводаТаблиц.Добавить(ПроцессорВывода2);
МассивПроцессоровВыводаТаблиц.Добавить(ПроцессорВывода3);
МассивПроцессоровВыводаТаблиц.Добавить(ПроцессорВывода4);
МассивПроцессоровВыводаТаблиц.Добавить(ПроцессорВывода5);
МассивПроцессоровВыводаТаблиц.Добавить(ПроцессорВывода6);
МассивПроцессоровВыводаТаблиц.Добавить(ПроцессорВывода7);
МассивПроцессоровВыводаТаблиц.Добавить(ПроцессорВыводаДополнительно);
Итератор = 0;
Для Каждого ПроцессорВывода из МассивПроцессоровВыводаТаблиц Цикл
ПроцессорВывода.ОтображатьПроцентВывода = Ложь;
ПроцессорВывода.УстановитьДокумент(МассивТаблиц[Итератор]);
ПроцессорВывода.НачатьВывод();
Итератор = Итератор + 1;
КонецЦикла;
//Компонуем отчет
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
Настройки = Отчет.КомпоновщикНастроек.ПолучитьНастройки();
СхемаКомпоновкиДанных = ОбъектОтчета.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
//Выводим результат в наши таблицы
Итератор = 0;
Пока Истина Цикл
ЭлементРезультата = ПроцессорКомпоновки.Следующий();
Если ЭлементРезультата = Неопределено Тогда
МассивПроцессоровВыводаТаблиц[Итератор].ЗакончитьВывод();
Прервать;
Иначе
Если ЭлементРезультата.Макеты.Количество() > 0 Тогда
Для Каждого ПроцессорВывода Из МассивПроцессоровВыводаТаблиц Цикл
ПроцессорВывода.ВывестиЭлемент(ЭлементРезультата);
КонецЦикла;
Иначе
//Нужно подобрать условия, когда переходим на следующую страницу
Если ЗначениеЗаполнено(ЭлементРезультата.ЗначенияПараметров) и ЭлементРезультата.ЗначенияПараметров.П1.Значение = "Разрыв" Тогда
МассивПроцессоровВыводаТаблиц[Итератор].ВывестиЭлемент(ЭлементРезультата);
//Выводим конец нашей группировки разрыва страницы
ЭлементРезультата = ПроцессорКомпоновки.Следующий();
МассивПроцессоровВыводаТаблиц[Итератор].ВывестиЭлемент(ЭлементРезультата);
ЭлементРезультата = ПроцессорКомпоновки.Следующий();
МассивПроцессоровВыводаТаблиц[Итератор].ВывестиЭлемент(ЭлементРезультата);
Итератор = Итератор + 1;
Иначе
МассивПроцессоровВыводаТаблиц[Итератор].ВывестиЭлемент(ЭлементРезультата);
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Сначала, запихиваем все табличные документы результата в массив и очищаем эти табличные документы.
Затем готовим процессоры вывода и пихаем их в свой массив. Суть метода в том, чтобы отчет скомпоновать один раз, а вот результат отчета вывести с помощью отдельных процессоров вывода для каждой таблицы. В цикле устанавливаем каждому процессору вывода свой табличный документ и начинаем вывод.
Последним этапом является вывод нашего результата отчета. Он происходит в немного модифицированном типовом цикле вывода.
Важный момент. Первый элемент результата СКД содержит все макеты результата, поэтому его нужно вывести во все табличные документы.
Чтобы определить момент, когда нужно перейти в новую таблицу для вывода следующей группировки я между группировками отчета добавил служебную группировку ПереходВДругуюТаблицу и в параметры отчета СКД новый параметр данных Разрыв, который и вывожу в этой служебной группировке. Это сделано, чтобы однозначно определить, что выводимый элемент отчета является сигналом к переходу на новую страницу. Для служебной группировки сделал условное оформление - Цвет фона, Цвет текста и Цвет границы - белый, чтобы не засорять нам отчет. Кстати, этот же метод можно использовать для вставки разрыва страницы после группировки в результате отчета, если для нашей служебной группировке настроить макет и добавить туда горизонтальный разделитель страницы.