Как правильно настроить вычисляемое поле в СКД для расчета коэффициента наличия товара по дням?

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

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

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

Причина некорректного расчета в итоговых записях и иерархии

Рассмотрим стандартную формулу, которую обычно пытаются применить в вычисляемом поле или ресурсах СКД для вычисления доли дней с положительным остатком:


Количество(ВычислитьВыражениеСГруппировкойМассив("ОстатокСУчетомНастроек", , "ОстатокСУчетомНастроек>0")) / (РазностьДат(&НачалоПериода, &ОкончаниеПериода, "День") + 1) * 100

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

На детальном уровне элементов номенклатуры такое выражение может возвращать требуемое число элементов массива (количество дней). Однако на уровне родительских групп и иерархии платформа начинает собирать в массив все детальные записи поддерева. В результате функция Количество() считывает общее число элементов по всем вложенным позициям номенклатуры за все дни. Так получается число 82 вместо положенных 9 дней, что при умножении на 100 и делении на 9 дает некорректный результат 911,11%.

Решение: явное указание группировки по периоду

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

Разберем правильный синтаксис выражения ресурса или вычисляемого поля:


Количество(ВычислитьВыражениеСГруппировкойМассив("ОстатокСУчетомНастроек", "Период", "ОстатокСУчетомНастроек>0")) / (РазностьДат(&НачалоПериода, &ОкончаниеПериода, "День") + 1) * 100

Проанализируем параметры функции ВычислитьВыражениеСГруппировкойМассив по шагам:

  1. Первый параметр (Выражение): "ОстатокСУчетомНастроек" — вычисляемый показатель остатка на каждый день.
  2. Второй параметр (Поля группировки): "Период" — указываем группировку по дням. Теперь СКД формирует по одному значению массива на каждый уникальный день периода в рамках текущего контекста отчета.
  3. Третий параметр (Отбор): "ОстатокСУчетомНастроек>0" — в массив попадают только те дни, когда остаток номенклатуры был строго больше нуля.

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

Альтернативный подход: расчет коэффициента на стороне запроса

Использование сложных агрегатных функций вида ВычислитьВыражениеСГруппировкойМассив в вычисляемых полях или ресурсах СКД выполняется в памяти платформы 1С. На больших объемах данных это может привести к снижению производительности отчета.

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

  1. В запросе к виртуальной таблице остатков (или при использовании дополнения периодов) формируем вспомогательное поле наличия:
    
    ВЫБОР 
        КОГДА Остаток > 0 ТОГДА 1 
        ИНАЧЕ 0 
    КОНЕЦ КАК ДеньСНаличием
    
  2. В настройках ресурсов СКД вычисляем процент с помощью простых агрегатных функций, которые легко пересчитываются на любых уровнях группировок: Сумма(ДеньСНаличием) / Количество(Различные Период) * 100

Такой подход обеспечивает высокую скорость работы отчета и исключает ошибки суммирования процентов в иерархических записях.

← На главную