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