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