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