При работе с системой компоновки данных (СКД) в 1С, особенно когда используется Пользовательская СКД для расширения возможностей отчетов на стороне клиента, часто возникает задача вывести в отчете не просто абсолютные значения, но и относительные, например, долю конкретной строки в общем итоге (для удобной визуализации таких данных есть панель инструментов для создания интерфейсов на основе СКД).
Давайте проанализируем ситуацию. СКД обрабатывает данные последовательно. Сначала выполняется запрос, который получает плоский набор данных. Для быстрой отладки таких запросов и проверки данных на лету часто применяется Консоль запросов УФ с поддержкой СКД и временных таблиц — для этого подойдёт набор инструментов для отладки запросов и СКД. Затем система обрабатывает этот набор, группирует записи и вычисляет итоги. Когда формируется строка для конкретной номенклатуры, СКД "знает" только данные этой строки. Общий итог по колонке "Сумма" будет известен только после того, как все строки будут обработаны.
Если в вычисляемом поле мы напишем выражение вроде Сумма / Сумма(Сумма), это не сработает, так как функция Сумма() в этом контексте будет относиться только к текущей записи, а не ко всему набору данных. Нам нужен инструмент, который может "заглянуть вперед" и получить итоговое значение, которое будет рассчитано позже.
Для решения подобных задач в языке выражений СКД существует специальная функция — Вычислить(). Она позволяет получить значение выражения, рассчитанное для определенной группировки отчета, например, для родительской группы или для общего итога. Это именно то, что нам нужно. При разработке сложных выражений и схем полезно иметь под рукой такие инструменты, как Консоль запросов для управляемых форм, которая позволяет детально разбирать структуру запроса и схемы.
Синтаксис функции:
Вычислить(Выражение, Группировка, ТипРасчета)
Рассмотрим ее параметры подробнее:
<strong>Выражение</strong> — это строка, содержащая вычисляемое выражение. Как правило, здесь используются агрегатные функции, такие как Сумма(), Количество(), Среднее() и т.д. Например, "Сумма(Выручка)".<strong>Группировка</strong> — строка с именем группировки, для которой нужно рассчитать выражение. Это может быть имя конкретной группировки из настроек отчета (например, "Контрагент") или одно из системных значений. Для нашей задачи ключевое значение — "ОбщийИтог". Оно указывает, что нужно взять итог по всему отчету.<strong>ТипРасчета</strong> — необязательный параметр, который уточняет, как рассчитывать итоги относительно указанной группировки. В большинстве случаев при использовании "ОбщийИтог" его можно опустить.Разберем по шагам, как применить эту функцию на практике для расчета доли каждой строки в общей сумме (для этого можно использовать готовый отчет ABC-анализа номенклатуры по выручке и прибыли).
Переходим к настройке СКД. Откройте схему компоновки данных вашего отчета. Нам нужна вкладка "Вычисляемые поля".
Создаем новое поле. Нажмите "Добавить" и создайте новое вычисляемое поле. Зададим ему путь данных (имя), например, ПроцентОтИтога, и заголовок, который увидит пользователь, — "Процент от итога". В ситуациях, когда стандартных настроек недостаточно, может потребоваться программное изменение заголовка группировки отчета, но для нашей задачи хватит штатных средств.
Пишем выражение для расчета. В поле "Выражение" необходимо написать формулу, которая будет использовать нашу сумму по строке и общий итог, полученный с помощью функции Вычислить(). Важно также предусмотреть защиту от деления на ноль: если общий итог равен нулю, то и процент должен быть равен нулю.
Для этого идеально подходит конструкция Выбор ... КонецВыбора.
Выбор
Когда Вычислить("Сумма(Сумма)", "ОбщийИтог") > 0
Тогда Сумма / Вычислить("Сумма(Сумма)", "ОбщийИтог") * 100
Иначе 0
КонецВыбора
Давайте детально разберем этот код:
Выбор Когда ... — это аналог оператора If...Then...Else. Мы проверяем условие.Вычислить("Сумма(Сумма)", "ОбщийИтог") > 0 — это наше условие. Здесь мы получаем общий итог по полю "Сумма" для всего отчета и проверяем, больше ли он нуля. Это и есть защита от ошибки деления на ноль.Тогда Сумма / Вычислить("Сумма(Сумма)", "ОбщийИтог") * 100 — эта часть выполняется, если условие истинно. Мы берем значение поля Сумма для текущей детальной записи и делим его на общий итог, который мы получили с помощью Вычислить(). Умножаем на 100 для получения процентного значения.Иначе 0 — если общий итог равен нулю, то результатом выражения будет 0.КонецВыбора — завершение конструкции.После создания этого поля его необходимо добавить в "Выбранные поля" на вкладке "Настройки", чтобы оно появилось в отчете. Также не забудьте настроить для него формат, чтобы значение отображалось с нужным количеством знаков после запятой и символом "%".
Функцию Вычислить() можно использовать не только в вычисляемых полях, но и непосредственно при настройке ресурсов. Этот способ полезен, если вы проводите оптимизацию отчетов с набором данных - объект или используете сложные схемы компоновки, где процент должен корректно рассчитываться на разных уровнях итогов.
Порядок действий:
Перейдите на вкладка "Ресурсы" в схеме компоновки данных.
Добавьте новый ресурс. Назовем его, например, ДоляВПродажах.
В поле "Выражение" укажите формулу. Формула будет очень похожа, но с одним отличием: так как мы находимся в контексте ресурса, нам нужно использовать агрегатную функцию для значения текущей группировки.
Выбор
Когда Вычислить(Сумма(Сумма), "ОбщийИтог") > 0
Тогда Сумма(Сумма) * 100 / Вычислить(Сумма(Сумма), "ОбщийИтог")
Иначе 0
КонецВыбора
Обратите внимание, что здесь мы используем Сумма(Сумма) как для числителя, так и внутри функции Вычислить(). Это позволяет корректно рассчитывать долю не только для детальных записей, но и для промежуточных итогов (например, долю продаж по группе номенклатуры в общем объеме).
Сравнение подходов:
Функция Вычислить() еще более универсальна. Вместо `"ОбщийИтог"` вы можете указать имя конкретной группировки. Это позволяет рассчитывать процент не от общего итога, а от итога по родительской группе. В некоторых архитектурных решениях для этого могут даже использоваться две разных схемы в отчете СКД, чтобы разделить логику подготовки данных и их визуализации.
Предположим, у вас есть отчет с группировками "Контрагент" -> "Номенклатура". И вы хотите для каждой номенклатуры посчитать ее долю в продажах по текущему контрагенту — для автоматизации таких расчетов подойдёт отчет для анализа ассортимента с расчетом долей на СКД.
Для этого в выражении нужно будет указать имя родительской группировки:
Выбор
Когда Вычислить("Сумма(Сумма)", "Контрагент") > 0
Тогда Сумма / Вычислить("Сумма(Сумма)", "Контрагент") * 100
Иначе 0
КонецВыбора
Таким образом, функция Вычислить() является мощным и гибким инструментом, который позволяет решать широкий круг задач по расчету относительных показателей в системе компоновки данных, эффективно обходя ограничения последовательной обработки данных.