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