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