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