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