Я не претендую на то, что описанные этой статье механизмы работы СКД и мое понимание соответствует действительности, поэтому готов внести поправки в данную статью, если что-то не так.
Постановка задачи
Требуется написать отчет, который бы позволил сравнить остатки и обороты по двум регистрам: Товары на складах, Партии товаров на складах. Доступными полями отчета являются измерения регистров, начальный, конечный остаток, приход, расход. Периодичность полученных данных может быть произвольной, вплоть до Регистратора.
Как решалась задача
Здесь я опишу основные этапы, через которые я прошел в процессе решения, опишу все грабли на которые наступил и попытаюсь их объяснить. Вы можете пропустить данный раздел и сразу перейти к разделу Выводы, где перечислены пункты, которые требуется выполнить чтобы успешно решить задачу.
В схеме компоновки данных, я добавил единственный Набор данных - запрос с текстом, который описывает Объединение двух запросов:
1. РегистрНакопления.ТоварыНаСкладах.ОстаткиИОбороты
2. РегистрНакопления.ПартииТоваровНаСкладахБухгалтерскийУчет.ОстаткиИОбороты
Полям ресурсов для Товаров на складах и для Партий товаров на складах я дал разные псевдонимы, чтобы в дальнейшем различать эти значения в отчете.
Плюс добавил в каждый запрос поле "Раздел" (я всегда так делаю, чтобы при отладке понять из какого запроса выбираются те или иные данные) - значение этого поля текст: для первого - "1. Товары на складах", для запроса к партиям - "2. Партии товаров на складах" соответственно.
При чем, конструктор СКД определил роли полей(что измерения, а что поля начальных, конечных остатков)
Настроил ресурсы для всех полей. Здесь ничего необычного
Настройки компоновки сделал простыми вложенными группировками по разрезам учета Склад, Номенклатура, Характеристика, Серия. И выбрал все поля ресурсов, кроме начальных остатков.
Смотрю, что получается - вроде, правильно:
Но если добавить группировку по регистратору или детальные записи, то итоги по номенклатуре становятся неправильными:
В чем проблема? Дело в том, что в СКД свой собственный механизм расчета начальных и конечных остатков(информация из видео-курса по СКД Гилева)
Алгоритм расчета итогов по полям остатка описан на ИТС https://its.1c.ru/db/v8310doc#bookmark:dev:TI000000628 (Спасибо Armando)
Упрощенно алгоритм для получения Конечных остатков таков: берем последнюю по хронологии запись в разрезе выбранных измерений и считаем, что значение поля Конечный остаток из нее и есть конечный остаток для группировки. И судя по скриншоту, получается, что последняя запись имеет конечный остаток по Товарам на складах = 0, Партии = 0 - СКД считает, что для Номенклатуры это и есть конечный остаток.
Чтобы это победить, для поля Раздел я добавил роль Измерение, и поскольку, данное поле не планируется выбирать в отчете, а СКД его будет оптимизировать и удалять из запроса - флаг Обязательное. Теперь итоги верные.
Немного красоты
Для того чтобы исключить пустые строки, сообщающие о начальном и конечном остатке на Начало/Конец периода, поле Регистратор можно в запросе заменить на выражение и поставить для этого поля галку Игнорировать значения NULL.
ВЫБОР
КОГДА Регистратор = НЕОПРЕДЕЛЕНО
ТОГДА NULL
ИНАЧЕ Регистратор
КОНЕЦ
В конце я еще дополнил текст запроса описанием характеристик
Выводы
Когда в одном отчете на СКД необходимо корректно показать начальные, конечные остатки нескольких разделов учета следует выполнить следующее:
- В наборе данных запрос используем таблицу ОстаткиИОбороты
- В запросе для каждого раздела учета создаем поле "Раздел". Для каждого запроса объединения, пишем туда уникальное значение. Я так и пишу текстом, например "1. Товары на складах", "2. Партии товаров на складах"
- В запросе выбираем все нужные поля, в т.ч. поле "Раздел"
- В СКД настраиваем роли для полей остатков(это СКД сделает сама)
- Очень важный момент! В СКД для поля "Раздел" ставим роль "Измерение" и галку "Обязательное"
В этом случае, при расчете итогов СКД всегда будет считать, что начальный и конечный остаток различных разделов учета у вас лежат в разных плоскостях(измерениях) и будет рассчитывать его корректно