Вычисляемые поля в СКД 1С: синтаксис выражений, функции и группировки
Вычисляемые поля в СКД задаются на закладке «Вычисляемые поля» схемы компоновки:
ПутьКДанным — имя поля в настройках, Выражение — формула,
Заголовок и ТипЗначения — представление и тип.
Программно это коллекция Схема.ВычисляемыеПоля
(ВычисляемыеПоляСхемыКомпоновкиДанных).
В выражении вычисляемого поля можно использовать только поля наборов данных,
параметры схемы и функции языка выражений СКД. Вычисляемое поле считается
для каждой детальной записи, а агрегат по группировке — это уже
ресурс (ПоляИтога) или функция
ВычислитьВыражение(). Путать их — источник большинства ошибок с «неправильными процентами».
Где задаются вычисляемые поля СКД
В конструкторе схемы компоновки данных есть отдельная закладка «Вычисляемые поля». Каждая строка —
один объект ВычисляемоеПолеСхемыКомпоновкиДанных со свойствами:
ПутьКДанным— имя, под которым поле фигурирует в настройках и других выражениях СКД. Без пробелов и точек.Выражение— формула расчёта; в ней допустимы только поля наборов данных.Заголовок— текст в пользовательских настройках и в результате компоновки.ТипЗначения—ОписаниеТипов; задавайте явно, если тип неочевиден.ВыражениеПредставления— чем поле выводится в результат (отдельно от значения).ОграничениеИспользования— где поле нельзя применять (отбор, группировка, порядок).
Ключевое отличие от полей запроса: вычисляемое поле СКД рассчитывает процессор компоновки уже после выборки данных. В SQL-запрос оно не попадает, индексы по нему не работают, но зато в нём доступны функции СКД, которых в языке запросов нет.
Синтаксис выражений СКД в вычисляемом поле
Язык выражений СКД синтаксически близок к языку запросов: те же операторы сравнения,
И/ИЛИ/НЕ, конструкция ВЫБОР … КОГДА … ТОГДА … ИНАЧЕ … КОНЕЦ,
литералы ЗНАЧЕНИЕ(Справочник.Валюты.Рубль) и ДАТАВРЕМЯ(2024, 1, 1).
// Категория заказа по сумме
ВЫБОР
КОГДА СуммаДокумента >= 1000000 ТОГДА "A"
КОГДА СуммаДокумента >= 100000 ТОГДА "B"
ИНАЧЕ "C"
КОНЕЦ
В выражении можно разыменовывать реквизиты через точку от поля-ссылки набора данных
(Номенклатура.ЕдиницаИзмерения.Наименование) и обращаться к параметрам схемы через
&ИмяПараметра:
// Просрочка на дату отчёта
ВЫБОР
КОГДА СрокОплаты < &ДатаОтчёта ТОГДА РАЗНОСТЬДАТ(СрокОплаты, &ДатаОтчёта, ДЕНЬ)
ИНАЧЕ 0
КОНЕЦ
Чего в выражении вычисляемого поля нет: соединений, вложенных запросов, временных таблиц и обращения к другим вычисляемым полям как к «уже посчитанным колонкам таблицы». Если нужна вторая таблица — это уровень набора данных или связи наборов, а не вычисляемого поля.
Какие функции доступны в выражениях СКД
В выражениях СКД доступны три группы функций, и различать их важно.
-
Функции языка запросов — работают в вычисляемом поле как обычно:
ЕСТЬNULL,ПОДСТРОКА,ГОД,МЕСЯЦ,НАЧАЛОПЕРИОДА,КОНЕЦПЕРИОДА,РАЗНОСТЬДАТ,ВЫРАЗИТЬ,ПРЕДСТАВЛЕНИЕ,ССЫЛКА. -
Агрегатные функции —
Сумма,Количество,Максимум,Минимум,Среднее. В вычисляемом поле они осмысленны только внутриВычислитьВыражение(): само вычисляемое поле считается построчно, агрегировать ему нечего. -
Функции компоновки данных —
ВычислитьВыражение,ВычислитьВыражениеСГруппировкойМассив,ВычислитьВыражениеСГруппировкойТаблицаЗначений,Уровень,НомерПоПорядку,ПорядковыйНомерВГруппировке. В языке запросов их нет.
Функции общих модулей конфигурации в выражениях СКД тоже вызываются, но только когда компоновка
инициализирована с разрешением внешних функций: у метода
ПроцессорКомпоновкиДанных.Инициализировать() за это отвечает параметр
<ВозможностьИспользованияВнешнихФункций>.
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , , Истина);
Результат = Новый ТабличныйДокумент;
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(Результат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Вычисление по группировкам: ВычислитьВыражение
Самая частая задача, ради которой берут вычисляемые поля СКД, — доля строки в итоге
группировки или в общем итоге. Обычным делением её не получить: в детальной записи нет
итога. Здесь нужна функция компоновки ВычислитьВыражение(), которой первым
аргументом передаётся выражение, а вторым — имя группировки или служебное значение.
// Доля строки в общем итоге отчёта, %
ВЫБОР
КОГДА ВычислитьВыражение("Сумма(СуммаОборот)", "ОбщийИтог") = 0 ТОГДА 0
ИНАЧЕ 100 * СуммаОборот / ВычислитьВыражение("Сумма(СуммаОборот)", "ОбщийИтог")
КОНЕЦ
Вторым параметром вместо "ОбщийИтог" указывают имя конкретной группировки настроек —
тогда доля считается внутри неё. Пустая строка означает текущую группировку:
// Доля внутри текущей группировки
ВЫБОР
КОГДА ВычислитьВыражение("Сумма(СуммаОборот)", "") = 0 ТОГДА 0
ИНАЧЕ 100 * СуммаОборот / ВычислитьВыражение("Сумма(СуммаОборот)", "")
КОНЕЦ
// Накопительный итог с начала группировки
ВычислитьВыражение("Сумма(СуммаОборот)", , , "Первая", "Текущая")
Важный нюанс: ВычислитьВыражение() работает на уровне группировок настроек,
а не набора данных. Если вычисляемое поле с ней выводится в детальные записи, а нужной группировки
в настройках варианта нет, результат будет пустым или неожиданным. Проверяйте состав группировок
в варианте отчёта, а не только текст выражения.
Вычисляемое поле или ресурс: чем отличаются
Вычисляемое поле считается по каждой записи. Ресурс (в схеме — коллекция
ПоляИтога) считается по группировкам агрегатной функцией. Классическая
ошибка — посчитать среднюю цену вычисляемым полем Сумма / Количество, а потом сделать
его ресурсом с формулой Сумма(СредняяЦена): в итоге получится сумма средних, а не средняя.
// Правильно: средняя цена как ресурс по агрегатам,
// а не как сумма построчных вычисляемых полей
ПолеИтога = Схема.ПоляИтога.Добавить();
ПолеИтога.ПутьКДанным = "СредняяЦена";
ПолеИтога.Выражение = "Сумма(СуммаОборот) / Сумма(КоличествоОборот)";
ПолеИтога.Группировки.Добавить("Номенклатура");
Практическое правило выбора: если формула складывается из агрегатов
(Сумма(A) / Сумма(B)) — это ресурс. Если формула считается по одной строке
(категория, флаг, разница дат, форматированное представление) — это вычисляемое поле. Если нужен
построчный расчёт с оглядкой на итог группировки — вычисляемое поле плюс
ВычислитьВыражение().
Программное создание вычисляемого поля в схеме
Вычисляемые поля СКД добавляются не только в конструкторе. Коллекция
Схема.ВычисляемыеПоля доступна из кода — это нужно для универсальных отчётов,
где состав полей зависит от настроек пользователя:
Схема = Отчеты.АнализПродаж.ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
Поле = Схема.ВычисляемыеПоля.Добавить();
Поле.ПутьКДанным = "ДоляВИтоге";
Поле.Заголовок = "Доля в итоге, %";
Поле.Выражение =
"ВЫБОР
| КОГДА ВычислитьВыражение(""Сумма(СуммаОборот)"", ""ОбщийИтог"") = 0 ТОГДА 0
| ИНАЧЕ 100 * СуммаОборот / ВычислитьВыражение(""Сумма(СуммаОборот)"", ""ОбщийИтог"")
|КОНЕЦ";
Поле.ТипЗначения = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2));
Существующее поле правится через Найти() по имени — метод возвращает
Неопределено, если поля с таким именем в схеме нет:
Поле = Схема.ВычисляемыеПоля.Найти("ДоляВИтоге");
Если Поле = Неопределено Тогда
Поле = Схема.ВычисляемыеПоля.Добавить();
Поле.ПутьКДанным = "ДоляВИтоге";
КонецЕсли;
// Истина = использование запрещено
Поле.ОграничениеИспользования.Условие = Истина;
Поле.ОграничениеИспользования.Группировка = Истина;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки);
После правки схемы обязательно перекомпоновать макет: КомпоновщикМакетаКомпоновкиДанных.Выполнить()
принимает схему и настройки и возвращает МакетКомпоновкиДанных. Изменение схемы уже
после получения макета на результат не влияет.
Параметры схемы и выражения СКД
Параметры в СКД тоже умеют считаться выражением: у ПараметрСхемыКомпоновкиДанных
есть свойство Выражение. Это штатный способ получить производный параметр —
например, конец периода из начала — не заставляя пользователя вводить обе даты.
Параметр = Схема.Параметры.Найти("ДатаОкончания");
Если Параметр <> Неопределено Тогда
Параметр.Выражение = "КонецПериода(&Период, ""День"")";
Параметр.Использование = ИспользованиеПараметраКомпоновкиДанных.Всегда;
КонецЕсли;
В самом вычисляемом поле параметр читается как &ИмяПараметра. Если параметр
передаётся ещё и в текст запроса набора данных, следите за совпадением имён: в схеме параметр один,
а вот значение к моменту расчёта вычисляемого поля уже подставлено, и «пустая» дата даст
неожиданное сравнение.
NULL, деление на ноль и тип значения
Три типовые причины, по которым корректное на вид выражение даёт пустую колонку.
NULL заражает всё выражение. Любая арифметика с NULL даёт
NULL, а он приходит из левых соединений и остатков без движений. Оборачивайте
поля в ЕСТЬNULL до вычислений, а не после:
// Неверно: NULL внутри скобок обнулит весь результат
ЕСТЬNULL(СуммаОборот - СуммаВозврата, 0)
// Верно: страхуем каждое слагаемое
ЕСТЬNULL(СуммаОборот, 0) - ЕСТЬNULL(СуммаВозврата, 0)
Деление на ноль. Отдельной защиты в СКД нет — знаменатель проверяется явно
через ВЫБОР. Проверять нужно именно то выражение, на которое делите, включая
результат ВычислитьВыражение().
ВЫБОР
КОГДА ЕСТЬNULL(КоличествоОборот, 0) = 0 ТОГДА 0
ИНАЧЕ СуммаОборот / КоличествоОборот
КОНЕЦ
Тип значения не определён. Если ТипЗначения у вычисляемого поля
пустой, платформа выводит тип из выражения — и для ВЫБОР с разнотипными ветками
получает составной тип. Итог: не работает сортировка, отбор предлагает не те значения, число
выводится как строка. Задавайте ОписаниеТипов явно и приводите ветки к одному типу
через ВЫРАЗИТЬ.
NULL, а где составной тип.
Частые ошибки при работе с вычисляемыми полями СКД
- Ссылка на другое вычисляемое поле или на ресурс. В выражении вычисляемого поля допустимы только поля наборов данных, параметры и функции СКД. Повторите формулу или перенесите расчёт в набор данных.
-
Агрегатная функция прямо в вычисляемом поле.
Сумма(СуммаОборот)безВычислитьВыражение()не даст итога по группировке — поле считается построчно. -
Вычисляемое поле, назначенное ресурсом «в лоб».
Сумма(Процент)по построчным процентам даёт бессмысленное число. Ресурс должен быть выражен через агрегаты исходных полей. -
Пробелы и точки в
ПутьКДанным. Имя поля используется в других выражениях и настройках, поэтому должно быть идентификатором. Человеческое название — вЗаголовок. - Отбор по вычисляемому полю на больших выборках. Условие не уходит в СУБД: сначала выбираются все записи, потом отсеиваются. Фильтровать лучше в запросе набора данных.
-
Правка схемы после компоновки макета. Изменения в
Схема.ВычисляемыеПоляучитываются только при повторном вызовеКомпоновщикМакетаКомпоновкиДанных.Выполнить(). -
Кавычки в программно заданном выражении. Внутри строки 1С кавычки
удваиваются:
"ВычислитьВыражение(""Сумма(Сумма)"", ""ОбщийИтог"")".
Частые вопросы о вычисляемых полях СКД
Чем вычисляемое поле СКД отличается от ресурса?
Вычисляемое поле рассчитывается для каждой детальной записи, ресурс — агрегатной функцией
по группировкам. Формула из агрегатов вида Сумма(A) / Сумма(B) должна быть
ресурсом; построчная формула — вычисляемым полем.
Можно ли в вычисляемом поле использовать другое вычисляемое поле?
Нет. В выражении вычисляемого поля доступны только поля наборов данных, параметры схемы и функции языка выражений СКД. Общую часть формулы придётся повторить или вынести в набор данных.
Как посчитать процент от итога группировки в СКД?
Через функцию ВычислитьВыражение(): первым аргументом — агрегат
("Сумма(СуммаОборот)"), вторым — имя группировки или "ОбщийИтог".
Знаменатель обязательно проверяйте на ноль конструкцией ВЫБОР.
ИИ Консоль запросов 1С
Лайт
Для ознакомления с возможностями
- Полный набор инструментов без урезаний
- Без ввода карты
Старт
Популярный выборДля индивидуального использования
- До 5ти конфигураций
-
≈ 100 задач Подробнее про лимиты
- Техническая поддержка
Продвинутый
Для интенсивного использования или команд
- До 15-ти конфигураций
-
≈ 300 задач Подробнее про лимиты
- Техническая поддержка