При разработке отчетов в Системе компоновки данных (СКД) часто возникает задача сопоставления текущих показателей с предыдущими периодами. Например, нам нужно вывести детальные продажи по партнерам и рядом с каждой датой продажи показать дату предыдущей сделки этого же контрагента. Для решения подобных задач в СКД предусмотрена мощная функция ВычислитьВыражение. Однако при её настройке разработчики часто сталкиваются с тем, что функция возвращает пустое значение или рассчитывает данные некорректно без учета иерархии группировок. В этой статье мы подробно разберем, почему возникает эта проблема и как правильно настроить расчет.
Рассмотрим типичную ситуацию. У нас есть запрос к оборотному регистру накопления «Продажи», который выбирает два основных поля: Партнер (контрагент) и Период (дата продажи). Нам требуется получить дату предыдущей продажи для каждого партнера. Разработчик интуитивно пытается решить эту задачу через создание нового вычисляемого поля на одноименной вкладке СКД, прописывая следующую формулу:
ВычислитьВыражение("Период", "Партнер",, "Предыдущая", "Предыдущая")
После запуска отчета колонка с результатом оказывается абсолютно пустой. Если же убрать из параметров функции группировку по партнеру, данные начинают рассчитываться, но неверно: система выдает предыдущую дату по всему списку документов без привязки к конкретному клиенту. Выясним причину такого поведения компоновщика данных.
Дело в том, что расчет данных в СКД происходит в несколько строго разграниченных этапов:
Партнер. Программа физически не может определить, какая строка является предыдущей в контексте конкретного контрагента.Таким образом, использование функций смещения, таких как ВычислитьВыражение с указанием контекста группировок, на вкладке «Вычисляемые поля» является грубой методологической ошибкой. Все подобные вычисления должны производиться строго в Ресурсах отчета.
Разберем по шагам, как перенести вычисления в ресурсы и правильно составить структуру отчета, чтобы даты продаж рассчитывались корректно для каждого партнера.
Для того чтобы функция могла сопоставлять периоды внутри контрагентов, нам необходимо задать четкую иерархическую структуру в настройках схемы компоновки данных. Нам понадобится следующая вложенность группировок:
Партнер.Период. Именно на уровне этой детальной группировки периодов и будет происходить расчет нашего показателя.Перейдем на вкладку «Ресурсы» схемы компоновки данных. Нам нужно объявить наше поле ПредыдущаяДатаПродажи ресурсом, но рассчитывать его только для определенных уровней отчета.
Период под другим именем).ВычислитьВыражение("Период", "Период", , "Предыдущая", "Предыдущая")
Период. Это критически важно, так как расчет должен выполняться в контексте детальных дат продаж.Давайте проанализируем параметры функции, которую мы указали в ресурсах:
"Период" — первый параметр. Это поле, значение которого мы хотим получить из другой строки."Период" — второй параметр. Указывает имя группировки, в рамках которой осуществляется поиск. Поскольку расчет идет внутри родительской группировки Партнер, СКД автоматически изолирует вычисления. Это значит, что поиск предыдущей строки по группировке Период никогда не выйдет за границы текущего контрагента."Предыдущая" определяют смещение выборки — мы берем ровно одну предыдущую запись.Настроив базовый расчет, мы можем столкнуться с ситуацией, когда пользователь решит изменить сортировку в отчете (например, выведет даты по убыванию). В этом случае логика работы функции может нарушиться, и вместо «Предыдущей» даты мы получим «Следующую» по хронологии. Чтобы гарантировать стабильность отчета при любых действиях пользователя, настоятельно рекомендуется использовать шестой параметр функции ВычислитьВыражение — Сортировка.
Пропишем в ресурсах более надежный вариант формулы:
ВычислитьВыражение("Период", "Период", , "Предыдущая", "Предыдущая", "Период Возр")
Указав в конце "Период Возр", мы жестко указываем системе компоновки данных, что перед вычислением предыдущего значения всю выборку внутри группировки необходимо принудительно отсортировать по возрастанию даты. Это гарантирует правильный результат независимо от настроек интерфейса отчета.
Также стоит учесть, что для самой первой продажи каждого партнера предыдущей даты не существует в базе данных. В этом случае функция вернет значение Null. Чтобы отчет выглядел более профессионально, мы можем обработать это граничное значение с помощью условного выражения:
Выбор
Когда ВычислитьВыражение("Период", "Период", , "Предыдущая", "Предыдущая", "Период Возр") Есть Null
Тогда "Первая продажа"
Иначе ВычислитьВыражение("Период", "Период", , "Предыдущая", "Предыдущая", "Период Возр")
Конец
Для корректного вычисления временных показателей со смещением (таких как предыдущая дата, прирост, скользящий итог) в СКД помните три основных правила:
ВычислитьВыражение, чтобы избежать ошибок при изменении порядка вывода строк пользователем.