Как в СКД рассчитать процент от общего итога в вычисляемом поле?

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

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

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

Давайте проанализируем ситуацию. СКД обрабатывает данные последовательно. Сначала выполняется запрос, который получает плоский набор данных. Для быстрой отладки таких запросов и проверки данных на лету часто применяется Консоль запросов УФ с поддержкой СКД и временных таблиц — для этого подойдёт набор инструментов для отладки запросов и СКД. Затем система обрабатывает этот набор, группирует записи и вычисляет итоги. Когда формируется строка для конкретной номенклатуры, СКД "знает" только данные этой строки. Общий итог по колонке "Сумма" будет известен только после того, как все строки будут обработаны.

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

Решение через функцию `Вычислить()`

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

Синтаксис функции:

Вычислить(Выражение, Группировка, ТипРасчета)

Рассмотрим ее параметры подробнее:

Практический пример: создаем вычисляемое поле "Процент от итога"

Разберем по шагам, как применить эту функцию на практике для расчета доли каждой строки в общей сумме.

  1. Переходим к настройке СКД. Откройте схему компоновки данных вашего отчета. Нам нужна вкладка "Вычисляемые поля".

  2. Создаем новое поле. Нажмите "Добавить" и создайте новое вычисляемое поле. Зададим ему путь данных (имя), например, ПроцентОтИтога, и заголовок, который увидит пользователь, — "Процент от итога". В ситуациях, когда стандартных настроек недостаточно, может потребоваться программное изменение заголовка группировки отчета, но для нашей задачи хватит штатных средств.

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

    Для этого идеально подходит конструкция Выбор ... КонецВыбора.

    
    Выбор
        Когда Вычислить("Сумма(Сумма)", "ОбщийИтог") > 0
            Тогда Сумма / Вычислить("Сумма(Сумма)", "ОбщийИтог") * 100
        Иначе 0
    КонецВыбора
    

Давайте детально разберем этот код:

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

Альтернативный подход: настройка выражения для ресурса

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

Порядок действий:

  1. Перейдите на вкладка "Ресурсы" в схеме компоновки данных.

  2. Добавьте новый ресурс. Назовем его, например, ДоляВПродажах.

  3. В поле "Выражение" укажите формулу. Формула будет очень похожа, но с одним отличием: так как мы находимся в контексте ресурса, нам нужно использовать агрегатную функцию для значения текущей группировки.

    
    Выбор
        Когда Вычислить(Сумма(Сумма), "ОбщийИтог") > 0
            Тогда Сумма(Сумма) * 100 / Вычислить(Сумма(Сумма), "ОбщийИтог")
        Иначе 0
    КонецВыбора
    

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

Сравнение подходов:

Расчет процента от итога по группе

Функция Вычислить() еще более универсальна. Вместо `"ОбщийИтог"` вы можете указать имя конкретной группировки. Это позволяет рассчитывать процент не от общего итога, а от итога по родительской группе. В некоторых архитектурных решениях для этого могут даже использоваться две разных схемы в отчете СКД, чтобы разделить логику подготовки данных и их визуализации.

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

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


Выбор
    Когда Вычислить("Сумма(Сумма)", "Контрагент") > 0
        Тогда Сумма / Вычислить("Сумма(Сумма)", "Контрагент") * 100
    Иначе 0
КонецВыбора

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

← На главную