ВычислитьВыражение и ВычислитьВыражениеСГруппировкойМассив в СКД 1С 8.3: синтаксис и примеры ресурсов
В языке выражений СКД 1С 8.3 есть три функции для расчёта показателей в произвольном контексте: ВычислитьВыражение (обращается к родительской группировке, "ОбщийИтог" или соседним записям через параметры Начало и Конец), ВычислитьВыражениеСГруппировкойМассив (сворачивает данные по указанным полям в Массив для расчёта «агрегата от агрегата», например Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(Цена)", "Номенклатура"))) и ВычислитьВыражениеСГруппировкойТаблицаЗначений (формирует свёрнутую ТаблицаЗначений с несколькими колонками для обработки функциями СКД или глобального общего модуля).
Функция Вычислить(Выражение, Группировка, ТипРасчета) оставлена в платформе только для обратной совместимости — во всех новых отчётах на закладках «Ресурсы» и «Пользовательские поля» используйте ВычислитьВыражение и его группирующие варианты.
Когда в ресурсах СКД не хватает обычных агрегатов и какую функцию выбрать
По умолчанию выражение на закладке «Ресурсы» конструктора схемы компоновки данных вычисляется «снизу вверх» по всем детальным записям, попавшим в текущую группировку. Этого механизма недостаточно в трёх типовых сценариях:
- Нужно выйти за пределы текущей строки — разделить оборот строки на общий итог отчёта, на итог родительской группировки или сравнить показатель с предыдущим месяцем.
- Нужен агрегат от агрегата — например, на уровне позиции номенклатуры берётся
Максимум(ПлановаяЦена)илиСреднее(Ставка), а на уровне склада и в общем итоге требуется получить сумму этих максимумов. Прямая записьСумма(Максимум(ПлановаяЦена))в СКД вызывает ошибку компоновки макета: «Использование вложенных агрегатных функций не допускается». - Нужна многоколоночная промежуточная таблица — требуется агрегировать данные в разбивке по аналитике, отсортировать их, соединить в строку через разделитель или передать в функцию общего модуля.
| Функция языка выражений СКД | Что возвращает | Типовые задачи в отчётах 1С 8.3 |
|---|---|---|
ВычислитьВыражение |
Произвольный тип (результат вычисления строкового выражения) | Доля строки от "ОбщийИтог", родительской группировки или "Иерархия"; нарастающий итог ("Первая".."Текущая"); остаток и дельта к предыдущей записи ("Предыдущая") или соседней колонке кросс-таблицы. |
ВычислитьВыражениеСГруппировкойМассив |
Массив вычисленных значений по уникальным комбинациям полей группировки |
Сумма максимумов/минимумов по подгруппам (Сумма(ВычислитьВыражениеСГруппировкойМассив(...))), исключение задвоения плановых показателей документа при соединении с табличной частью, подсчёт среднего чека по документам. |
ВычислитьВыражениеСГруппировкойТаблицаЗначений |
ТаблицаЗначений, где каждая строка — результат группировки по указанным полям |
Сборка сводной таблицы с псевдонимами колонок (КАК) для последующей передачи в Упорядочить, ПолучитьЧасть, СоединитьСтроки или во внешнюю экспортную функцию глобального общего модуля. |
Полный синтаксис и все 8 параметров функции ВычислитьВыражение
Функция ВычислитьВыражение (EvalExpression) вычисляет строковое выражение в контексте заданной группировки и заданного интервала записей. Она учитывает отбор группировок, но не учитывает иерархические отборы и не может вызываться для группировки в собственном групповом отборе этой же группировки.
ВычислитьВыражение(
Выражение,
Группировка,
ТипВычисления,
Начало,
Конец,
Порядок,
ИерархическийПорядок,
ОбработкаОдинаковыхЗначенийПолейПорядка
)
"Сумма(СуммаОборот)"."" (текущая), "ОбщийИтог" или имя родительской группировки из настроек."ОбщийИтог", "Группировка", "ГруппировкаНеРесурса" или "Иерархия"."Первая", "Последняя", "Предыдущая", "Следующая", "Текущая", "ОграничивающееЗначение(...)".Начало).Возр, Убыв, Автоупорядочивание."Отдельно" (по умолчанию) или "Вместе".Разберём допустимые строковые значения ключевых параметров управления контекстом и окном записей:
- Группировка: пустая строка
""(или пропущенный параметр) выполняет расчёт в контексте текущей группировки;"ОбщийИтог"— в контексте всего отчёта; любое другое имя (например,"Склад") ищет вышестоящую родительскую группировку с таким свойством «Имя» в структуре настроек. В кросс-таблице доступны спецзначения"Строка"и"Колонка". - ТипВычисления (в части документации также именуется
ТипРасчета):"ОбщийИтог"— выражение рассчитывается по всем записям указанной группировки (именно этот режим нужен, когда в параметреГруппировкаоставлена пустая строка, а нужно получить итог всей текущей ветки или смещение внутри неё);"Группировка"— значение вычисляется для текущей групповой записи указанной группировки;"Иерархия"— значение рассчитывается для родительской иерархической записи (если текущая строка находится внутри группы справочника) либо для всей группировки, если родителя нет (используется для поля «% в группе иерархии»);"ГруппировкаНеРесурса"— служебный режим для группировок по ресурсам: возвращает значение первой групповой записи исходной группировки.
- Начало и Конец задают окно записей для агрегатных функций и точку чтения детальных полей:
"Первая"("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"
)
)
"Максимум(ПлановаяЦена)")."Номенклатура, Характеристика").&Параметры).В отличие от ВычислитьВыражение, где второй параметр ссылается на имя группировки в структуре настроек отчёта, во втором параметре ВычислитьВыражениеСГруппировкойМассив перечисляются имена полей данных через запятую (например, "ЗаказКлиента" или "Склад, Номенклатура"). Даже если пользователь в режиме «1С:Предприятие» уберёт группировку по заказам из структуры отчёта, формула всё равно корректно свернёт детальные записи по полю ЗаказКлиента в памяти.
Два классических практических примера использования:
- Исключение дублей суммы документа при соединении с табличной частью. Если запрос соединяет шапку заказа (где хранится
СуммаДоставки) со строками товаров, обычный ресурсСумма(СуммаДоставки)умножит доставку на число строк в заказе. ФормулаСумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(СуммаДоставки)", "ЗаказКлиента"))сначала возьмёт одно значение доставки на каждый уникальный заказ, а затем сложит их по менеджеру, подразделению и в общем итоге. - Сумма только положительных остатков по складам. Четвёртый параметр
ОтборГруппировокработает после группировки:Сумма(ВычислитьВыражениеСГруппировкойМассив("Сумма(КоличествоОстаток)", "Номенклатура, Склад", , "Сумма(КоличествоОстаток) > 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С
Старт
Популярный выборДля индивидуального использования
- Сборка и проверка отчётов СКД (.erf)
-
≈ 100 задач Подробнее про лимиты
- Техническая поддержка
Лайт
Для ознакомления с возможностями
- Полный набор инструментов без урезаний
- Без ввода карты
Ранний доступ
Популярный выборТестирование продукта в режиме разработки
- Формирование панелей и виджетов в чате
- Поддержка таблиц и популярных типов диаграмм
- Приоритетный сбор обратной связи по развитию продукта
Продвинутый
Для интенсивного использования или команд
- Сборка и проверка отчётов СКД (.erf)
-
≈ 300 задач Подробнее про лимиты
- Техническая поддержка