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