Как вычесть две суммы в отчете СКД и сохранить расшифровку по документам

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке отчетов в Системе компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда необходимо не просто вывести данные из базы, а произвести над ними арифметические операции, например, вычесть одну сумму из другой. На первый взгляд задача кажется тривиальной, однако при добавлении группировок или необходимости сохранить детальные записи для расшифровки, итоги могут начать «удваиваться» или рассчитываться некорректно. В этой статье мы подробно разберем, как правильно реализовать вычитание сумм и настроить ресурсы так, чтобы отчет оставался информативным и точным.

Разбор базовой проблемы: почему суммы не сходятся?

Рассмотрим ситуацию, когда в наборе данных у нас есть два показателя, например, СуммаПрихода и СуммаРасхода. Нам нужно получить их разность. Если мы просто выведем эти поля в детальных записях, проблем не возникнет. Однако, как только мы добавляем группировку по Документу или общие итоги, СКД начинает агрегировать данные. Если формула прописана только на уровне настроек отчета, система может сначала сложить все приходы, затем все расходы, и только в самом конце вычесть их, что не всегда соответствует бизнес-логике, особенно если нужно видеть разность по каждой строке отдельно.

Проанализируем ситуацию, описанную пользователем: при наличии группировки по полю Документ (Док) сумма рассчитывалась неверно. После удаления группировки итог стал правильным, но пропала возможность «провалиться» в документ (расшифровка). Выясним, как оставить документ в отчете и при этом получить верные цифры.

Способ 1. Использование агрегатной функции Максимум для ресурсов

Один из самых быстрых способов решить проблему, когда детальные записи (документы) «ломают» общую сумму, — это изменить функцию агрегации в настройках ресурсов. По умолчанию СКД предлагает функцию Сумма(). Если данные в строках дублируются из-за особенностей соединения таблиц в запросе, использование Сумма приведет к завышению итогов.

Разберем по шагам, как применить функцию Максимум:

  1. Перейдем на закладку Ресурсы в схеме компоновки данных.
  2. Для поля, в котором считается разность (или для самих сумм), в колонке «Выражение» вместо стандартного Сумма(ИмяПоля) пропишем Максимум(ИмяПоля).
  3. Это позволит системе брать только одно максимальное значение для конкретной группировки, не суммируя повторяющиеся записи внутри одного документа.

Важно: этот метод эффективен, когда по одному документу в выборку попадает несколько идентичных строк, которые не должны увеличивать итоговый показатель. Однако для полноценного расчета разности лучше использовать вычисляемые поля.

Способ 2. Создание вычисляемого поля с обработкой NULL

Для того чтобы расчет разности был максимально стабильным, мы рекомендуем создавать Вычисляемое поле. Это позволяет подготовить данные еще до того, как они попадут в механизм расчета итогов.

Проанализируем правильное выражение для вычисляемого поля. Часто при вычитании возникают ошибки, если одно из значений не заполнено (имеет значение NULL). В языке выражений СКД операция Число - NULL всегда дает NULL. Чтобы этого избежать, обязательно используем функцию ЕстьNULL.

Рассмотрим пример выражения в вычисляемом поле:

ЕстьNULL(СуммаНачальныйОстаток, 0) - ЕстьNULL(СуммаРасход, 0)

После создания такого поля на закладке Вычисляемые поля, его необходимо добавить на закладку Ресурсы. Там для него можно указать стандартное выражение Сумма(ВашеВычисляемоеПоле). Теперь СКД будет сначала вычислять разность для каждой строки, а затем корректно складывать эти разности в итогах по группировкам.

Способ 3. Настройка выражений ресурсов для разных группировок

Если нам нужно сохранить расшифровку по документам, но при этом расчет итогов по иерархии должен идти по особому алгоритму, мы можем настроить колонку «Рассчитывать по...» на закладке Ресурсы.

Посмотрим на пример настройки:

Способ 4. Использование функции ВычислитьВыражение

В более сложных случаях, когда нужно вычесть значение из одной группировки из значения другой, или обратиться к итогам вышестоящего уровня, не удаляя текущую детализацию, мы используем мощную функцию ВычислитьВыражение. Рассмотрим пример, как можно получить сумму общего итога в каждой строке детальных записей, чтобы вычислить долю или разность:

Сумма(СуммаОборот) - ВычислитьВыражение("Сумма(СуммаОборот)", "ОбщийИтог")

Этот метод позволяет оставить поле Документ в структуре отчета. Система сначала рассчитает общую сумму по всему отчету, а затем позволит использовать это значение в математических операциях на уровне каждой строки с документом.

Важные рекомендации при работе с остатками

Если ваши суммы являются остатками (начальными или конечными), обычное суммирование через Сумма() в ресурсах приведет к логической ошибке (остатки по времени складывать нельзя). В этом случае проанализируем настройки на закладке Наборы данных:

  1. Найдите поле остатка в списке полей.
  2. В колонке Роль проверьте наличие роли «Остаток».
  3. Убедитесь, что указано имя поля счета и тип остатка (Начальный/Конечный).

При правильной настройке ролей СКД сама поймет, что при группировке по документам нужно показывать значение на момент документа, а в общих итогах — не складывать их за весь период, а выводить актуальный срез.

Таким образом, мы рассмотрели несколько вариантов решения задачи. Выбор конкретного метода зависит от того, насколько сложная структура вашего запроса. Для простых случаев достаточно функции Максимум или ЕстьNULL в вычисляемых полях. Для сложных аналитических отчетов с сохранением детальной расшифровки лучше комбинировать настройки ресурсов и функции вычисления выражений в контексте группировок.

← На главную