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