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