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