При разработке отчетов на системе компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда итоговые суммы в ресурсах начинают умножаться на два, три или более. Это происходит в тот момент, когда мы пытаемся получить дополнительную аналитику из табличных частей документов, соединяя их с виртуальными таблицами оборотов регистров. Разберем подробно, почему так происходит, и как правильно спроектировать запрос в конфигурации «Управление производственным предприятием» (УПП).
Проанализируем ситуацию: в запросе используется левое соединение виртуальной таблицы Хозрасчетный.Обороты с табличными частями документов, такими как ПоступлениеТоваровУслуг.Товары или ПлатежноеПоручениеИсходящее.РасшифровкаПлатежа. Выясним причину некорректных итогов.
Когда СУБД выполняет соединение, она создает строку для каждой пары записей, удовлетворяющих условию. Если в регистре бухгалтерии на один документ-регистратор приходится одна запись по обороту (например, 10 000 рублей), а в самом документе в табличной части «Товары» содержится три строки с разными номенклатурными позициями, то в результате соединения мы получим три строки. В каждой из этих трех строк будет указана полная сумма оборота — 10 000 рублей. В итоге СКД, суммируя ресурс «СуммаПоступления», выдаст 30 000 рублей вместо положенных десяти. Это классическое «декартово произведение», возникающее при связи «один ко многим».
Рассмотрим самый правильный путь для получения аналитики в бухгалтерских отчетах. В большинстве случаев такие данные, как «Статья затрат», «Статья ДДС» или «Счет учета», уже содержатся в самом регистре бухгалтерии в виде субконто. Обращение к документу напрямую — это избыточная операция, которая не только приводит к ошибкам в суммах, но и существенно замедляет отчет.
Посмотрим, как изменить подход к получению данных:
Субконто1 (или Субконто2) из таблицы оборотов.СчетДт и СчетКт.Проанализируем пример того, как должен выглядеть запрос без обращения к документам:
ВЫБРАТЬ
ХозрасчетныйОбороты.Регистратор КАК Документ,
ХозрасчетныйОбороты.СуммаОборотДт КАК Оплата,
ХозрасчетныйОбороты.СуммаОборотКт КАК СуммаПоступления,
ВЫРАЗИТЬ(ХозрасчетныйОбороты.Субконто1 КАК Справочник.СтатьиДвиженияДенежныхСредств) КАК СтатьяДДС
ИЗ
РегистрБухгалтерии.Хозрасчетный.Обороты(&НачалоПериода, &КонецПериода, Авто, Счет В ИЕРАРХИИ (&Счет60), , Организация = &Организация, , ) КАК ХозрасчетныйОбороты
Если мы работаем в конфигурации УПП, то использование только регистра бухгалтерии для сложных отчетов не всегда оправдано. В этой конфигурации реализован механизм параллельного учета. Посмотрим на альтернативные источники данных, которые уже содержат всю необходимую аналитику в плоском виде без необходимости соединений с документами:
Использование этих регистров исключает дублирование, так как структура их записей соответствует детальной аналитике документов.
Если ситуация безвыходная и данные можно взять только из табличной части (например, специфический реквизит, которого нет в субконто), нам необходимо предварительно подготовить данные. Разберем этот алгоритм по шагам:
ПоступлениеТоваровУслуг.Товары).Ссылка. Если нам нужно вытащить статью затрат, а в документе их несколько, придется использовать агрегатные функции (например, МАКСИМУМ) или смириться с тем, что мы берем «первую попавшуюся» аналитику для всего документа.Хозрасчетный.Обороты с нашей временной таблицей.Пример структуры такого запроса:
ВЫБРАТЬ
Товары.Ссылка КАК Ссылка,
МАКСИМУМ(Товары.СтатьяЗатрат) КАК СтатьяЗатрат
ПОМЕСТИТЬ ВТ_АналитикаДокументов
ИЗ
Документ.ПоступлениеТоваровУслуг.Товары КАК Товары
СГРУППИРОВАТЬ ПО
Товары.Ссылка;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
ХозрасчетныйОбороты.Регистратор,
ХозрасчетныйОбороты.СуммаОборотКт,
ВТ_АналитикаДокументов.СтатьяЗатрат
ИЗ
РегистрБухгалтерии.Хозрасчетный.Обороты(...) КАК ХозрасчетныйОбороты
ЛЕВОЕ СОЕДИНЕНИЕ ВТ_АналитикаДокументов КАК ВТ_АналитикаДокументов
ПО ХозрасчетныйОбороты.Регистратор = ВТ_АналитикаДокументов.Ссылка
Рассмотрим еще один мощный инструмент компоновки данных. Вместо того чтобы пытаться написать один сложный запрос, мы можем создать два отдельных Набора данных - запрос.
В первом наборе данных мы получаем суммы из регистра бухгалтерии. Во втором наборе данных мы выбираем аналитику из табличных частей документов. После этого перейдем на закладку «Связи наборов данных» и свяжем их по полю Регистратор (в первом наборе) и Ссылка (во втором).
Важный нюанс: В настройках связи СКД позволяет указать параметры. СКД умеет корректно обрабатывать такие связи: она сначала получит итоговые суммы, а затем «подтянет» к ним аналитику, не дублируя при этом числовые показатели в итогах. Это наиболее «чистый» способ с точки зрения архитектуры самой системы компоновки данных.
Подводя итог, проанализируем основные правила предотвращения дублей в отчетах:
Субконто — в 90% случаев данные уже там.Соблюдение этих принципов позволит создавать надежные и быстрые отчеты, которые будут показывать корректные финансовые данные независимо от количества строк в документах.