СКД в 1С

ВычислитьВыражение и ВычислитьВыражениеСГруппировкойМассив в СКД 1С 8.3: синтаксис и примеры ресурсов

Коротко

В языке выражений СКД 1С 8.3 есть три функции для расчёта показателей в произвольном контексте: ВычислитьВыражение (обращается к родительской группировке, "ОбщийИтог" или соседним записям через параметры Начало и Конец), ВычислитьВыражениеСГруппировкойМассив (сворачивает данные по указанным полям в Массив для расчёта «агрегата от агрегата», например Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(Цена)", "Номенклатура"))) и ВычислитьВыражениеСГруппировкойТаблицаЗначений (формирует свёрнутую ТаблицаЗначений с несколькими колонками для обработки функциями СКД или глобального общего модуля).

Функция Вычислить(Выражение, Группировка, ТипРасчета) оставлена в платформе только для обратной совместимости — во всех новых отчётах на закладках «Ресурсы» и «Пользовательские поля» используйте ВычислитьВыражение и его группирующие варианты.

Когда в ресурсах СКД не хватает обычных агрегатов и какую функцию выбрать

По умолчанию выражение на закладке «Ресурсы» конструктора схемы компоновки данных вычисляется «снизу вверх» по всем детальным записям, попавшим в текущую группировку. Этого механизма недостаточно в трёх типовых сценариях:

  • Нужно выйти за пределы текущей строки — разделить оборот строки на общий итог отчёта, на итог родительской группировки или сравнить показатель с предыдущим месяцем.
  • Нужен агрегат от агрегата — например, на уровне позиции номенклатуры берётся Максимум(ПлановаяЦена) или Среднее(Ставка), а на уровне склада и в общем итоге требуется получить сумму этих максимумов. Прямая запись Сумма(Максимум(ПлановаяЦена)) в СКД вызывает ошибку компоновки макета: «Использование вложенных агрегатных функций не допускается».
  • Нужна многоколоночная промежуточная таблица — требуется агрегировать данные в разбивке по аналитике, отсортировать их, соединить в строку через разделитель или передать в функцию общего модуля.
Функция языка выражений СКД Что возвращает Типовые задачи в отчётах 1С 8.3
ВычислитьВыражение Произвольный тип (результат вычисления строкового выражения) Доля строки от "ОбщийИтог", родительской группировки или "Иерархия"; нарастающий итог ("Первая".."Текущая"); остаток и дельта к предыдущей записи ("Предыдущая") или соседней колонке кросс-таблицы.
ВычислитьВыражениеСГруппировкойМассив Массив вычисленных значений по уникальным комбинациям полей группировки Сумма максимумов/минимумов по подгруппам (Сумма(ВычислитьВыражениеСГруппировкойМассив(...))), исключение задвоения плановых показателей документа при соединении с табличной частью, подсчёт среднего чека по документам.
ВычислитьВыражениеСГруппировкойТаблицаЗначений ТаблицаЗначений, где каждая строка — результат группировки по указанным полям Сборка сводной таблицы с псевдонимами колонок (КАК) для последующей передачи в Упорядочить, ПолучитьЧасть, СоединитьСтроки или во внешнюю экспортную функцию глобального общего модуля.

Полный синтаксис и все 8 параметров функции ВычислитьВыражение

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

ВычислитьВыражение(
    Выражение,
    Группировка,
    ТипВычисления,
    Начало,
    Конец,
    Порядок,
    ИерархическийПорядок,
    ОбработкаОдинаковыхЗначенийПолейПорядка
)
ВычислитьВыражение (EvalExpression)
ВыражениеСтрока — формула на языке выражений СКД, например "Сумма(СуммаОборот)".
ГруппировкаСтрока — "" (текущая), "ОбщийИтог" или имя родительской группировки из настроек.
ТипВычисленияСтрока — "ОбщийИтог", "Группировка", "ГруппировкаНеРесурса" или "Иерархия".
НачалоСтрока — начальная запись интервала: "Первая", "Последняя", "Предыдущая", "Следующая", "Текущая", "ОграничивающееЗначение(...)".
КонецСтрока — конечная запись интервала (те же значения, что и для параметра Начало).
Порядок (Сортировка)Строка — поля сортировки через запятую с модификаторами Возр, Убыв, Автоупорядочивание.
ИерархическийПорядок (ИерархическаяСортировка)Строка — выражение упорядочивания иерархических записей.
ОбработкаОдинаковыхЗначенийПолейПорядкаСтрока — "Отдельно" (по умолчанию) или "Вместе".
→ Произвольный (или NULL)

Разберём допустимые строковые значения ключевых параметров управления контекстом и окном записей:

  • Группировка: пустая строка "" (или пропущенный параметр) выполняет расчёт в контексте текущей группировки; "ОбщийИтог" — в контексте всего отчёта; любое другое имя (например, "Склад") ищет вышестоящую родительскую группировку с таким свойством «Имя» в структуре настроек. В кросс-таблице доступны спецзначения "Строка" и "Колонка".
  • ТипВычисления (в части документации также именуется ТипРасчета):
    • "ОбщийИтог" — выражение рассчитывается по всем записям указанной группировки (именно этот режим нужен, когда в параметре Группировка оставлена пустая строка, а нужно получить итог всей текущей ветки или смещение внутри неё);
    • "Группировка" — значение вычисляется для текущей групповой записи указанной группировки;
    • "Иерархия" — значение рассчитывается для родительской иерархической записи (если текущая строка находится внутри группы справочника) либо для всей группировки, если родителя нет (используется для поля «% в группе иерархии»);
    • "ГруппировкаНеРесурса" — служебный режим для группировок по ресурсам: возвращает значение первой групповой записи исходной группировки.
  • Начало и Конец задают окно записей для агрегатных функций и точку чтения детальных полей:
    • "Первая" ("First") и "Последняя" ("Last") — первая или последняя запись группировки. В скобках можно передать целое число больше нуля, например "Первая(3)" — третья запись от начала;
    • "Предыдущая" ("Previous") и "Следующая" ("Next") — сдвиг относительно текущей строки. Поддерживают смещение в скобках: "Предыдущая(2)" — на две записи назад. Если для параметра Начало сдвиг "Предыдущая(3)" выходит за левую границу, берётся первая запись; если для параметра Конец сдвиг назад выходит за границу — считается, что записей нет;
    • "Текущая" ("Current") — текущая запись группировки (для итоговой строки группировки возвращает первую запись);
    • "ОграничивающееЗначение(Выражение)" ("BoundaryValue(...)") — поиск границы по первому полю упорядочивания (в Начало берётся первая запись со значением >=, в Конец — последняя запись со значением <=).
  • ОбработкаОдинаковыхЗначенийПолейПорядка (в справке платформы также ОбработкаОдинаковыхЗначенийПорядка): при значении "Отдельно" ("Separately", по умолчанию) предыдущая и следующая записи определяются на основании значений выражений упорядочивания, и каждая запись обрабатывается индивидуально (например, из двух строк за одну дату в "Текущая" попадёт только одна текущая строка). При значении "Вместе" ("Together") используется последовательность упорядоченных записей с объединением строк с одинаковым значением поля порядка (например, одной датой) в общий фрагмент; при этом указывать числовое смещение в скобках для позиций "Первая", "Последняя", "Предыдущая", "Следующая" запрещено.

Практика ВычислитьВыражение: доля от группировки, нарастающий итог и сдвиг к предыдущей записи

Ниже приведены четыре рабочие формулы для закладки «Ресурсы», закрывающие 90% аналитических задач с окнами и итогами верхнего уровня.

// 1. Доля (процент) текущей строки от Общего итога отчёта:
Сумма(СуммаОборот) * 100 / ВычислитьВыражение("Сумма(СуммаОборот)", "ОбщийИтог")

// 2. Доля в родительской группе иерархии справочника (или во всей группировке):
Сумма(СуммаОборот) * 100 / ВычислитьВыражение("Сумма(СуммаОборот)", "", "Иерархия")

// 3. Нарастающий итог с первой по текущую запись внутри текущей группировки:
ВычислитьВыражение("Сумма(СуммаОборот)", "", "ОбщийИтог", "Первая", "Текущая")

// 4. Отклонение (прирост) показателя относительно предыдущей строки (например, месяца):
Сумма(СуммаОборот) - ЕстьNull(
    ВычислитьВыражение("Сумма(СуммаОборот)", "", "ОбщийИтог", "Предыдущая", "Предыдущая", "Период Возр"),
    0
)

Обратите внимание на третий и четвёртый примеры: когда вторым параметром передана пустая строка "" (текущая группировка), третьим параметром обязательно указывают "ОбщийИтог". Это говорит процессору компоновки рассматривать всю последовательность записей текущей группировки, внутри которой параметры "Первая", "Текущая" и "Предыдущая" выделяют нужный срез. Для первой строки группировки записи "Предыдущая" не существует, поэтому функция возвращает NULL — оборачивание в ЕстьNull(..., 0) предотвращает пропажу числа при вычитании.

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

Функция ВычислитьВыражениеСГруппировкойМассив (EvalExpressionWithGroupArray) выполняет виртуальную группировку детальных записей в памяти по полям из второго параметра, вычисляет для каждой группы выражение из первого параметра и возвращает Массив полученных результатов. Так как стандартные агрегатные функции СКД (Сумма, Максимум, Минимум, Среднее, Количество) умеют принимать на вход Массив, эта связка легально решает задачу вложенной агрегации.

// Ресурс «Сумма максимумов по номенклатуре»:
Сумма(
    ВычислитьВыражениеСГруппировкойМассив(
        "Максимум(ПлановаяЦена)",
        "Номенклатура",
        "НЕ ПометкаУдаления",
        "Сумма(КоличествоОборот) > 0"
    )
)
ВычислитьВыражениеСГруппировкойМассив
ВыражениеСтрока — выражение, вычисляемое для каждой группы (например, "Максимум(ПлановаяЦена)").
ПоляГруппировки (ВыраженияПолейГруппировки)Строка — выражения полей группировки через запятую (например, "Номенклатура, Характеристика").
ОтборЭлементов (ОтборЗаписей)Строка — фильтр детальных записей до группировки (агрегатные функции здесь запрещены!).
ОтборГруппировокСтрока — фильтр свёрнутых групповых записей (аналог HAVING, поддерживает агрегаты и &Параметры).
→ Массив

В отличие от ВычислитьВыражение, где второй параметр ссылается на имя группировки в структуре настроек отчёта, во втором параметре ВычислитьВыражениеСГруппировкойМассив перечисляются имена полей данных через запятую (например, "ЗаказКлиента" или "Склад, Номенклатура"). Даже если пользователь в режиме «1С:Предприятие» уберёт группировку по заказам из структуры отчёта, формула всё равно корректно свернёт детальные записи по полю ЗаказКлиента в памяти.

Два классических практических примера использования:

  1. Исключение дублей суммы документа при соединении с табличной частью. Если запрос соединяет шапку заказа (где хранится СуммаДоставки) со строками товаров, обычный ресурс Сумма(СуммаДоставки) умножит доставку на число строк в заказе. Формула Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(СуммаДоставки)", "ЗаказКлиента")) сначала возьмёт одно значение доставки на каждый уникальный заказ, а затем сложит их по менеджеру, подразделению и в общем итоге.
  2. Сумма только положительных остатков по складам. Четвёртый параметр ОтборГруппировок работает после группировки: Сумма(ВычислитьВыражениеСГруппировкойМассив("Сумма(КоличествоОстаток)", "Номенклатура, Склад", , "Сумма(КоличествоОстаток) > 0")) просуммирует остатки только тех ячеек «Номенклатура + Склад», где итог больше нуля, отсекая отрицательные зависшие остатки.
Ошибки с вложенными кавычками в аргументах ВычислитьВыражениеСГруппировкойМассив и неправильная настройка колонки «Рассчитывать по…» на вкладке «Ресурсы» часто выясняются только при проверке итогов. В ИИ Консоли отчётов 1С агент сам изучает структуру вашей базы, настраивает формулы ресурсов в схеме компоновки данных, сверяет итоговые суммы проверочными запросами к базе и собирает готовый отчёт .erf.

ВычислитьВыражениеСГруппировкойТаблицаЗначений: работа с несколькими колонками и общими модулями

Когда в результате виртуальной группировки нужно получить не одно число, а сразу несколько показателей (например, контрагента, сумму продаж, себестоимость и дату последней отгрузки), используют ВычислитьВыражениеСГруппировкойТаблицаЗначений (EvalExpressionWithGroupValueTable). Набор параметров у неё точно такой же, но в первом аргументе Выражение можно перечислить несколько выражений через запятую и задать имена колонок через ключевое слово КАК.

// 1. Вывод топ-списка контрагентов с оборотами в одну ячейку через перевод строки:
СоединитьСтроки(
    ПолучитьЧасть(
        Упорядочить(
            ВычислитьВыражениеСГруппировкойТаблицаЗначений(
                "Представление(Контрагент) КАК Имя, Сумма(СуммаОборот) КАК Оборот",
                "Контрагент",
                "ЗначениеЗаполнено(Контрагент)",
                "Сумма(СуммаОборот) >= &МинПорог"
            ),
            "Оборот Убыв"
        ),
        "Имя, Оборот"
    ),
    " / ",
    ": "
)

// 2. Передача свёрнутой ТаблицыЗначений в функцию глобального общего модуля:
РасчетРейтингаСКД.РассчитатьВзвешенныйИндекс(
    ВычислитьВыражениеСГруппировкойТаблицаЗначений(
        "Номенклатура КАК Товар, Сумма(Количество) КАК Кол, Сумма(Выручка) КАК Сумма",
        "Номенклатура"
    )
)
ВычислитьВыражениеСГруппировкойТаблицаЗначений
ВыражениеСтрока — список выражений через запятую с необязательным КАК ИмяКолонки.
ПоляГруппировкиСтрока — поля группировки через запятую (например, "Контрагент, Договор").
ОтборЭлементовСтрока — условие отбора детальных записей (без агрегатных функций).
ОтборГруппировокСтрока — условие отбора свёрнутых строк таблицы (допускает агрегаты).
→ ТаблицаЗначений

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

Защита выражений от NULL и деления на ноль

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

// Безопасный расчёт доли (%) в группировке с защитой от NULL и деления на 0:
ВЫБОР
    КОГДА ЕстьNull(ВычислитьВыражение("Сумма(СуммаОборот)", "Склад"), 0) = 0
        ТОГДА 0
    ИНАЧЕ Сумма(СуммаОборот) * 100
        / ВычислитьВыражение("Сумма(СуммаОборот)", "Склад")
КОНЕЦ

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

Всегда оборачивайте знаменатель дроби в ВЫБОР КОГДА ЕстьNull(..., 0) = 0 ТОГДА 0 ИНАЧЕ ... КОНЕЦ. Если внутри строкового аргумента ВычислитьВыражение* вам нужно использовать строковый литерал (например, "Число(15,2)" в функции Выразить или тип периода "Месяц" в НачалоПериода), кавычки внутри строки обязательно удваиваются: ""Месяц"".

Вместо ручной отладки экранирования кавычек и условий с ЕстьNull можно поручить задачу ИИ Консоли отчётов 1С: достаточно написать в чате «посчитай долю продаж каждого товара от склада и нарастающий итог по месяцам без деления на ноль», и агент автоматически соберёт валидную схему СКД и проверит расчёт на данных вашей базы.

Частые ошибки при работе с ВычислитьВыражение и группировками

  • Ошибка «Использование вложенных агрегатных функций не допускается». Возникает при попытке написать в ресурсе Сумма(Максимум(Поле)) или применить агрегат в ресурсе к вычисляемому полю, в котором уже написана агрегатная функция. Замените конструкцию на Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(Поле)", "ПолеГруппировки")).
  • Пустой результат ВычислитьВыражение при обращении к родительской группировке по имени. Второй параметр ВычислитьВыражение("Сумма(Сумма)", "Склад") ищет не имя поля набора данных, а строковое Имя группировки, заданное на закладке «Настройки» в структуре отчёта. Если свойство «Имя» у группировки не заполнено, функция вернёт NULL.
  • Перепутаны второй параметр в ВычислитьВыражение и в ВычислитьВыражениеСГруппировкойМассив. У первой функции второй параметр — это имя группировки из настроек (или "ОбщийИтог"), а у второй — список полей данных через запятую (например, "Контрагент, Договор").
  • Агрегатная функция в третьем параметре ОтборЭлементов. В ВычислитьВыражениеСГруппировкойМассив и ВычислитьВыражениеСГруппировкойТаблицаЗначений третий параметр фильтрует детальные строки до группировки. Если написать туда "Сумма(Оборот) > 1000", при компоновке возникнет ошибка выполнения — перенесите это условие в четвёртый параметр ОтборГруппировок.
  • Использование ВычислитьВыражение в групповом отборе той же группировки. Платформа запрещает вызывать ВычислитьВыражение для группировки внутри её собственного отбора группировки (например, ВычислитьВыражение("Сумма(СуммаОборот)", , "ОбщийИтог") > 1000), однако такое выражение допустимо в иерархическом отборе или условном оформлении.
  • Указание смещения в скобках при ОбработкаОдинаковыхЗначенийПолейПорядка = "Вместе". Если восьмой параметр ВычислитьВыражение установлен в "Вместе", использовать смещения вида "Предыдущая(2)" или "Первая(3)" в параметрах Начало и Конец нельзя.
  • Неэкранированные кавычки или пробелы в именах полей внутри строкового выражения. Строковые литералы внутри первого аргумента нужно писать с двойными кавычками (""Год""), а имена полей с пробелами — заключать в квадратные скобки (например, "Сумма([Количество Оборот])").

Частые вопросы по функциям ВычислитьВыражение в СКД

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

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

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

Напрямую вложить одну агрегатную функцию в другую нельзя — платформа выдаст ошибку «Использование вложенных агрегатных функций не допускается». Для решения задачи на закладке «Ресурсы» используйте связку внешней агрегатной функции и группировки в массив: Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(Цена)", "Номенклатура")). Внутренняя функция соберёт массив максимальных цен по каждой номенклатуре, а внешняя функция Сумма сложит элементы этого массива для вышестоящих группировок и общего итога.

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

Добавьте ресурс с выражением ВычислитьВыражение("Сумма(СуммаОборот)", "", "ОбщийИтог", "Первая", "Текущая"). Здесь пустая строка во втором параметре указывает на текущую группировку, третий параметр "ОбщийИтог" включает расчёт по всем записям этой группировки, а параметры Начало = "Первая" и Конец = "Текущая" ограничивают суммирование диапазоном от первой строки до текущей включительно.

Тарифы

ИИ Консоль отчётов 1С

Лайт

Бесплатно

Для ознакомления с возможностями

  • Все функции бесплатно на 2 дня +2 дня за подписку на Telegram или Max
  • Полный набор инструментов без урезаний
  • Без ввода карты

Ранний доступ

Популярный выбор
Бесплатно

Тестирование продукта в режиме разработки

  • Формирование панелей и виджетов в чате
  • Поддержка таблиц и популярных типов диаграмм
  • Приоритетный сбор обратной связи по развитию продукта