Как рассчитать ресурсы в СКД с учетом значений вышестоящих уровней группировки?

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

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

Анализ проблемы: почему стандартное суммирование не подходит

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

Попытки использовать простое условие через Уровень() часто приводят к тому, что на подчиненных уровнях возвращается NULL или некорректное значение, так как контекст вышестоящей группировки недоступен напрямую в простом выражении ресурса.

Решение через функцию ВычислитьВыражение

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

Допустим, наш ресурс называется ОсталосьПроизвести. Нам нужно, чтобы на подчиненных уровнях система проверяла значение этого же ресурса у родителя. Общая схема выражения в поле «Ресурсы» будет выглядеть следующим образом:


ВЫБОР 
    КОГДА ВычислитьВыражение("Сумма(ОсталосьПроизвести)", "ИмяВышестоящейГруппировки", "Группировка") = 0 
    ТОГДА 0 
    ИНАЧЕ Сумма(ОсталосьПроизвести) 
КОНЕЦ

Разберем параметры функции ВычислитьВыражение, которые мы использовали:

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

Реализация каскадного условия для нескольких уровней

Если уровней вложенности много и условие должно проверяться на каждом из них (например, Уровень 3 зависит от Уровня 2, который в свою очередь зависит от Уровня 1), логику следует сделать более универсальной. Рассмотрим пример, где мы проверяем «нулевой» остаток на конкретном уровне:


ВЫБОР 
    КОГДА СистемныеПоля.Уровень = 1 ТОГДА 
        Сумма(ОсталосьПроизвести)
    КОГДА СистемныеПоля.Уровень = 2 ТОГДА 
        ВЫБОР 
            КОГДА ВычислитьВыражение("Сумма(ОсталосьПроизвести)", "ГруппировкаУровень1", "Группировка") = 0 
            ТОГДА 0 
            ИНАЧЕ Сумма(ОсталосьПроизвести) 
        КОНЕЦ
    КОГДА СистемныеПоля.Уровень = 3 ТОГДА
        ВЫБОР 
            КОГДА ВычислитьВыражение("Сумма(ОсталосьПроизвести)", "ГруппировкаУровень2", "Группировка") = 0 
            ТОГДА 0 
            ИНАЧЕ Сумма(ОсталосьПроизвести) 
        КОНЕЦ
ИНАЧЕ 0
КОНЕЦ

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

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

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

Проанализируем пример такого подхода:


ВЫБОР 
    КОГДА "0" В ВычислитьВыражениеСГруппировкойМассив("Строка(Сумма(ОсталосьПроизвести))", "Иерархия")
    ТОГДА 0 
    ИНАЧЕ Сумма(ОсталосьПроизвести) 
КОНЕЦ

Здесь мы преобразуем суммы в строки для упрощения поиска в массиве (так как поиск в массивах СКД иногда капризен к типам данных). Если в цепочке родителей хотя бы один уровень имеет итоговый остаток 0, то и текущий уровень принудительно обнуляется.

Настройка вычисляемых полей для упрощения логики

Иногда удобнее вынести часть логики в Вычисляемые поля. Посмотрим, как это сделать. Мы можем создать поле НужноПроизвестиНаВерхнемУровне и прописать в его выражении:

ВычислитьВыражение("Сумма(ОсталосьПроизвести)", "Группировка1", "Группировка")

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

Типичные ошибки при реализации

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

← На главную