При разработке отчетов в системе компоновки данных (СКД) часто возникает задача обратиться к конкретной строке внутри группы — например, получить значение второй строки периода или предыдущего документа. Для этого разработчики используют встроенную функцию языка выражений СКД ВычислитьВыражение() со смещениями вида "Первая(2)".
Однако при неправильной настройке контекста вычисления вместо второй детальной строки отчёт возвращает значение первой строки следующей группировки. Проанализируем, почему так происходит, и разберём правильные способы решения этой задачи.
Разберем механику работы функции. Выражение со смещением выглядит следующим образом:
ВычислитьВыражение("Период", , , "Первая(2)", "Первая(2)")
Главная причина, по которой сдвиг происходит по группировкам, а не по детальным записям, заключается в контексте расчета и значении параметра ТипРасчета:
ВычислитьВыражение() написано на вкладке ресурсов, СКД вычисляет его для итоговой (групповой) записи. В этом контексте указатели смещения ("Первая(2)", "Предыдущая", "Следующая") перемещаются по соседним веткам итогов того же уровня, а не по детальным записям внутри одной группы."Группировка" платформа выполняет вычисление относительно текущей групповой записи. Параметр "ОбщийИтог" производит расчет по всем записям, но логика смещения фиксируется относительно всего набора данных.Если требуется вывести значение второй строки непосредственно в таблице детальных записей, перенесём выражение из ресурсов на вкладку «Вычисляемые поля».
Рассмотрим порядок действий:
ПериодВторойСтроки).ВычислитьВыражение("Период", , , "Первая(2)", "Первая(2)")
Выясним, как поступить, если значение второй детальной строки необходимо вывести в строке итогов группировки (в ресурсах). Прямое применение смещения "Первая(2)" в ресурсах не сработает из-за группового контекста. В этом случае используем комбинацию агрегатной функции работы с массивами и функции извлечения элемента.
Для поля ресурса зададим следующее выражение:
ПолучитьЭлемент(ВычислитьВыражениеСГруппировкойМассив("Период", "Период"), 2)
Рассмотрим, как работает эта конструкция:
ВычислитьВыражениеСГруппировкойМассив() собирает все значения поля Период нижестоящих детальных записей текущей группы в массив.ПолучитьЭлемент(..., 2) извлекает из сформированного массива значение со вторым индексом.Проанализируем альтернативный подход, который не зависит от нюансов функций языка выражений СКД. Нумерацию строк можно выполнить непосредственно в тексте запроса с помощью оконной функции.
Добавим в запрос набора данных нумерацию внутри группы:
ВЫБРАТЬ
Т.Ссылка КАК Документ,
Т.Номенклатура КАК Номенклатура,
Т.Количество КАК Количество,
ROW_NUMBER() OVER (PARTITION BY Т.Ссылка ОБРАБОТКА ПО Т.Номенклатура) КАК НомерСтроки
ИЗ
Документ.РеализацияТоваровУслуг.Товары КАК Т
После этого на вкладке «Ресурсы» вычисление значения для 2-й строки сводится к простому условию:
Максимум(Выбор Когда НомерСтроки = 2 Тогда Номенклатура Иначе Неопределено Конец)
При использовании смещений в СКД обратите внимание на следующие важные нюансы:
"Первая(2)" строго ориентируется на порядок строк. Если пользователь изменит сортировку отчета в настройках, без явного задания параметра сортировки внутри ВычислитьВыражение() вернется другая строка.NULL (или пустое значение). Учитывайте это при формировании печатных форм и вычислениях.ВычислитьВыражение(), нельзя использовать в отборах по детальным записям, иначе компоновщик данных выдаст ошибку вычисления выражения.