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

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

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

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

Основная сложность заключается в том, что количество колонок (валют) в каждом периоде может быть разным. В одном месяце это могут быть только USD и EUR, в другом — пять различных валют. Стандартные агрегатные функции типа Сумма(СуммаДокумента) рассчитываются только для текущего контекста (текущей ячейки). Чтобы "заглянуть" в соседние колонки, нам потребуется функция ВычислитьВыражение или её более продвинутый вариант ВычислитьВыражениеСГруппировкойМассив.

Разберем, почему простые варианты с параметрами "Первая" или "Следующая" могут не подойти. Эти параметры жестко привязываются к позиции колонки. Если в январе USD стоит второй по счету, а в феврале — первой, то использование относительных смещений приведет к ошибкам в расчетах. Нам нужно решение, которое будет динамически определять контекст родительской группировки (например, "Период").

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

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

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


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

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

  1. "Сумма(СуммаДокумента)" — это выражение, которое мы хотим вычислить.
  2. "Период" — имя группировки, в рамках которой производится расчет. Указывая здесь период, мы заставляем СКД суммировать данные по всем валютам, входящим в этот период, даже если мы находимся в конкретной колонке валюты.
  3. "Группировка" — область вычисления. Это ключевой параметр, который указывает, что вычисление должно идти по записям текущей группировки.

Если нам нужно вывести в колонке USD сумму всех остальных валют (исключая сам доллар), формула немного усложнится:


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

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

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

Посмотрим на пример, как получить сумму всех валют в текущем периоде:

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

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

Решение 3: Настройка расчета ресурсов по разным группировкам

Выясним еще одну важную деталь: СКД позволяет настраивать расчет одного и того же ресурса по-разному для каждой группировки. Это часто избавляет от необходимости писать длинные конструкции ВЫБОР КОГДА.

Перейдем на вкладку "Ресурсы" и добавим поле СуммаДокумента несколько раз:

  1. Для группировки Валюта пропишем выражение с функцией ВычислитьВыражение, как мы рассматривали выше.
  2. Для группировки Период и Общий итог оставим стандартное Сумма(СуммаДокумента).

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

Решение 4: Преобразование данных на уровне запроса

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

Например, в тексте запроса можно использовать конструкцию:


ВЫБОР 
    КОГДА Таблица.Валюта В (&СписокВажныхВалют) 
    ТОГДА Таблица.Валюта 
    ИНАЧЕ "Прочие валюты" 
КОНЕЦ КАК ВалютаДляОтчета

В этом случае задача сводится к обычному выводу кросс-таблицы, так как группировка по полю ВалютаДляОтчета автоматически схлопнет все второстепенные валюты в одну колонку. Это наиболее производительный метод для больших объемов данных.

Важные нюансы и ограничения

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

Также стоит обратить внимание на параметр "ТипРасчета". В кросс-таблицах для корректной работы ВычислитьВыражение рекомендуется явно указывать значение "Группировка". Это ограничивает область видимости функции текущей строкой (контрагентом) и родительской группировкой колонок (месяцем), не позволяя данным "уплывать" в другие периоды или к другим контрагентам.

Рассмотренные методы позволяют гибко управлять выводом данных в горизонтальных группировках 1С, делая отчеты более информативными и удобными для конечного пользователя.

← На главную