Как правильно рассчитать итоги для вычисляемых полей в СКД, если они выводятся некорректно?

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

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

Проблема математической логики: Сумма дробей против Дроби сумм

Давайте проанализируем ситуацию, с которой столкнулся автор темы. Основная ошибка заключается в непонимании того, как СКД применяет формулу ресурса к итоговой строке. Рассмотрим классический пример расчета средней цены или себестоимости отклонения.

Если в поле Ресурсы вы указываете формулу вида:

Сумма(Стоимость) / Сумма(Количество) * Сумма(Отклонение)

СКД для итоговой строки выполнит следующие действия:

  1. Сложит всю стоимость по всем строкам.
  2. Сложит все количество по всем строкам.
  3. Сложит все отклонения.
  4. Разделит полученную огромную сумму стоимости на общую сумму количества и умножит на общее отклонение.

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

(A1/B1) + (A2/B2) != (A1+A2) / (B1+B2)

Способ 1: Суммирование выражения в ресурсах

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

Рассмотрим пример правильной формулы для ресурса:


Сумма(Выбор Когда КоличествоФ = 0 Тогда 0 Иначе Стоимость / Количество * ((КоличествоФ / КоличествоУпаковок) - КоличествоП) * КоличествоУпаковок Конец)

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

Способ 2: Разделение формул для разных уровней группировок

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

Разберем алгоритм действий:

  1. Добавьте ваше поле в список ресурсов.
  2. В колонке Выражение напишите формулу для детальных записей (например, расчет себестоимости конкретной позиции).
  3. В колонке Рассчитывать по... выберите все ваши группировки, кроме Общего итога.
  4. Добавьте это же поле в ресурсы еще раз.
  5. В выражении для второго ресурса напишите просто: Сумма(ИмяВашегоПоля).
  6. В колонке Рассчитывать по... установите флажок только на Общий итог.

Благодаря этому приему в строках будет работать сложная логика с делением и условиями, а в самом низу отчета СКД просто сложит все числа, которые она вывела выше.

Почему не стоит обращаться к вычисляемым полям из ресурсов?

В сообщениях форума прозвучала важная мысль: не стоит в формулах ресурсов ссылаться на другие вычисляемые поля. Почему это считается плохой практикой? Дело в порядке расчета.

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

Вместо:

Сумма(МоеВычисляемоеПолеЦена * МоеВычисляемоеПолеКолво)

Используйте:

Сумма(Цена * Количество)

Это гарантирует предсказуемость результата и упрощает отладку отчета.

Обработка NULL и деления на ноль

Часто итоги «плывут» из-за наличия пустых значений (NULL) в исходных данных. Если в формуле участвует поле, которое в некоторых строках не заполнено, весь результат выражения для этой строки может стать NULL, и сумма в итоге будет меньше ожидаемой.

Проанализируем пример безопасного выражения в СКД:


Сумма(ЕстьNull(Стоимость, 0)) / Выбор Когда Сумма(ЕстьNull(Количество, 0)) = 0 Тогда 1 Иначе Сумма(ЕстьNull(Количество, 0)) Конец

Важные моменты:

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

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

Пример использования в ресурсах:

Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(Цена)", "Номенклатура"))

Эта функция позволяет сначала собрать данные (например, максимальные цены) в массив по определенной группировке, а затем применить к этому массиву агрегатную функцию (например, сложить их). Это незаменимый инструмент для сложных аналитических отчетов, где стандартные итоги не справляются.

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

← На главную