Как в отчете 1С на базе СКД правильно рассчитать произведение количества на объем номенклатуры с корректными итогами?

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

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

Разберем причину возникновения проблемы «задваивания» данных

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

Проблема проявляется в следующих случаях:

  1. Множественные движения: Если по одной номенклатуре было 10 поступлений, система может ошибочно суммировать объем 10 раз, если формула настроена без учета группировки.
  2. Иерархия складов: При выводе итогов по складу система должна сложить объемы всех товаров на этом складе. Если ресурс определен неверно, расчет на уровне склада может выдать астрономические цифры, так как он будет повторно перемножать суммарное количество на объемы в каждой подстроке.
  3. Пустые значения: Если у части номенклатуры объем не заполнен (равен NULL), результат умножения всей строки может стать пустым, что исказит общий итог по складу.

Вариант 1: Использование вычисляемых полей и настройка ресурсов

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

Пошаговый алгоритм действий:

  1. Перейдем на закладку «Вычисляемые поля».
  2. Добавим новое поле с заголовком «Общий объем» и выражением Количество * ЕСТЬNULL(Номенклатура.Объем, 0).
  3. Теперь самое важное — настройка на закладке «Ресурсы». Если мы просто выберем функцию Сумма() для этого поля, риск дублей сохраняется.

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

Вариант 2: Продвинутые формулы ресурсов СКД

Если простая сумма не дает нужного результата, воспользуемся мощным механизмом функций СКД. Для корректного расчета итогов по иерархии (Номенклатура -> Склад -> Итог) рекомендуется использовать функции ВычислитьВыражениеСГруппировкойМассив. Это позволит системе сначала вычислить произведение на уровне номенклатуры, а затем просуммировать полученные результаты для более высоких уровней.

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


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

Проанализируем эту конструкцию:

Вариант 3: Решение через пользовательские поля

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

Выполним следующие шаги:

  1. В настройках отчета перейдем в раздел «Пользовательские поля».
  2. Создадим поле типа «Поле-выражение».
  3. В детальных записях укажем: [Количество] * [Номенклатура.Объем].
  4. В итогах укажим ту же формулу или просто Сумма([Количество] * [Номенклатура.Объем]).

Важный нюанс: Чтобы данные не задваивались при использовании пользовательских полей, убедитесь, что в ресурсах основного отчета поле Объем не выбрано как ресурс само по себе, иначе СКД попытается суммировать объемы до перемножения.

Вариант 4: Расчет на уровне запроса (Наиболее надежный)

Профессиональные разработчики предпочитают переносить логику расчетов в Текст запроса. Это исключает двусмысленность интерпретации формул механизмом СКД. Посмотрим на пример модификации запроса в наборе данных:


ВЫБРАТЬ
    ЗапасыОстатки.Склад КАК Склад,
    ЗапасыОстатки.Номенклатура КАК Номенклатура,
    ЗапасыОстатки.КоличествоОстаток КАК Количество,
    ЗапасыОстатки.Номенклатура.Объем КАК ЕдиничныйОбъем,
    ВЫРАЗИТЬ(ЗапасыОстатки.КоличествоОстаток * ЗапасыОстатки.Номенклатура.Объем КАК ЧИСЛО(15, 3)) КАК СуммарныйОбъем
ИЗ
    РегистрНакопления.Запасы.Остатки(&Период, ) КАК ЗапасыОстатки

После добавления поля СуммарныйОбъем в запрос, в СКД нам остается только:

  1. На закладке «Поля» убедиться, что поле появилось.
  2. На закладке «Ресурсы» добавить СуммарныйОбъем и применить к нему простую функцию Сумма(СуммарныйОбъем).

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

Особенности учета в УНФ: Единицы измерения и Характеристики

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

Подведение итогов

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

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

← На главную