Выражения СКД 1С: шпаргалка по функциям и синтаксису

Дата: 06.10.2026 16:54:16
СКД
Отчеты
Выражения СКД
Вычисляемые поля
Компоновка данных
Комментарий:
0
Платформа:
8.3
Конфигурация:
Любая
Формы:
Любые

Выражения СКД в 1С — формулы на языке выражений системы компоновки данных. На нём пишут вычисляемые поля, ресурсы, параметры, связи наборов, параметры макетов и пользовательские поля. Язык похож на язык запросов, но синтаксис у части функций другой. Ниже — шпаргалка по функциям, сверенная со справкой платформы 8.3.27, отличия от запросов, примеры ВЫБОР, ЕстьNull и ЗначениеЗаполнено и стенд, на котором выражение проверяется без отчёта.

Где в СКД пишут выражения

Все места — на закладках конструктора схемы компоновки данных:

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

У полей набора и вычисляемых полей есть ещё выражение представления и выражения упорядочивания. Параметры пишут с амперсандом (&Период), подробнее — в статьях о параметрах СКД и про макет СКД.

Выражения СКД: синтаксис, операции и NULL

  • Литералы. Строка — в двойных кавычках, кавычка внутри удваивается. Число — через точку: 10.5. Дата — ДАТАВРЕМЯ(2026, 1, 31), время необязательно. Булево — Истина, Ложь, тип — Тип("Строка"). Перечисления и предопределённые данные — через Значение(…), в УТ 11.4 например Значение(Перечисление.СтатусыЗаказовКлиентов.Закрыт).
  • Арифметика: + - * / и остаток от деления %. Строки склеиваются плюсом.
  • Сравнения: = <> < > <= >=, В (&Склад1, &Склад2), Контрагент В Контрагенты — проверка по набору из одного поля, ЕСТЬ NULL, ЕСТЬ НЕ NULL, ПОДОБНО с шаблонами % и _.
  • Логика и условие: НЕ, И, ИЛИ, ВЫБОР КОГДА … ТОГДА … ИНАЧЕ … КОНЕЦ.

Приоритет от низшего к высшему: ИЛИ, И, НЕ, затем В и ЕСТЬ NULL, сравнения, сложение и вычитание, умножение, деление и %, унарный минус. Любая операция с NULL даёт NULL, кроме двух случаев: И вернёт Ложь, если хоть один операнд Ложь, а ИЛИ — Истину, если хоть один Истина. Значения разных типов сравниваются по старшинству: NULL, Булево, Число, Дата, Строка, ссылки.

Функции СКД: шпаргалка по группам

Функции вычисляемых полей СКД, ресурсов и пользовательских полей берутся из одного списка, разница в том, какие записи видит выражение.

ГруппаФункцииПример
ДатыГод, Квартал, Месяц, День, ДеньГода, Неделя, ДеньНедели, Час, Минута, Секунда, НачалоПериода, КонецПериода, ДобавитьКДате, РазностьДат, ТекущаяДатаДобавитьКДате(Дата, "День", 10)
СтрокиДлинаСтроки, Подстрока, Лев, Прав, СокрЛ, СокрП, СокрЛП, СтрНайти, ВРег, НРег, СтрЗаменить, НСтрСтрЗаменить(Артикул, " ", "")
ЧислаОкр, Цел, Pow, Sqrt, Exp, Log, Log10, Sin, Cos, Tan, ASin, ACos, ATanОкр(Сумма / 1.2, 2)
Значения и типыЕстьNull, ЗначениеЗаполнено, Представление, Строка, Формат, Выразить, ТипЗначения, УникальныйИдентификатор, ПолучитьНавигационнуюСсылкуФормат(Дата, "ДФ=dd.MM.yyyy")
Положение записиНомерПоПорядку, НомерПоПорядкуВГруппировке, Уровень, УровеньВГруппировкеНомерПоПорядкуВГруппировке()
Расчёт в другой группировкеВычислитьВыражение, ВычислитьВыражениеСГруппировкойМассив, ВычислитьВыражениеСГруппировкойТаблицаЗначений; Вычислить оставлена для совместимостиВычислитьВыражение("Сумма(Сумма)", "ОбщийИтог")
АгрегатныеСумма, Количество, Количество(Различные …), Минимум, Максимум, Среднее, Массив, ТаблицаЗначений, Свернуть, ПолучитьЧасть, Упорядочить, СоединитьСтроки, ГрупповаяОбработка, Каждый, Любой, МестоВПорядке, КлассификацияABC, статистическиеКлассификацияABC("Сумма(Сумма)", 3, "80, 95")

Тип периода в НачалоПериода, КонецПериода и ДобавитьКДате — строка: "Минута", "Час", "День", "Неделя", "Месяц", "Квартал", "Год", "Декада", "Полугодие"; у РазностьДат недели и декады нет. СтрНайти ищет без учёта регистра, КлассификацияABC возвращает номер класса (1 — это A). В старых релизах части функций может не быть — сверяйтесь со справкой своей платформы.

Отличия от языка запросов

ЧтоЯзык запросовВыражения СКД
Тип периодаНАЧАЛОПЕРИОДА(Дата, МЕСЯЦ)НачалоПериода(Дата, "Месяц")
Приведение типаВЫРАЗИТЬ(Поле КАК Число(15, 2))Выразить(Поле, "Число(15,2)")
Литерал типаТИП(Строка)Тип("Строка")
Остаток от делениянетКоличество % 10
Текущая датанет, передают параметромТекущаяДата()
Заполненность и форматнетЗначениеЗаполнено(), Формат()
Нумерация строкАВТОНОМЕРЗАПИСИ() только во временной таблицеНомерПоПорядку()
Функции общих модулейнельзяможно
МЕЖДУ, В ИЕРАРХИИ, ССЫЛКАестьв справке нет; вместо МЕЖДУ — два сравнения через И

Запрос набора удобно отлаживать отдельно — в бесплатной консоли запросов, а выражения — на стенде ниже.

ВЫБОР, ЕстьNull и ЗначениеЗаполнено в вычисляемых полях

Условия в вычисляемых полях СКД пишут конструкцией ВЫБОР КОГДА, пустые значения закрывают ЕстьNull и ЗначениеЗаполнено:

ЗадачаВыражение
Размер сделкиВЫБОР КОГДА Сумма >= 100000 ТОГДА "Крупная" КОГДА Сумма >= 20000 ТОГДА "Средняя" ИНАЧЕ "Мелкая" КОНЕЦ
Цена без деления на нольВЫБОР КОГДА Количество = 0 ТОГДА 0 ИНАЧЕ Окр(Сумма / Количество, 2) КОНЕЦ
Отклонение от плана из второго набораСумма - ЕстьNull(План, 0)
Статус оплатыВЫБОР КОГДА ЗначениеЗаполнено(ДатаОплаты) ТОГДА "Оплачено" ИНАЧЕ "Ждём оплату" КОНЕЦ
Подпись из ссылки и числаПредставление(Склад) + ": " + Формат(Сумма, "ЧДЦ=2")

ЗначениеЗаполнено в СКД возвращает Ложь для NULL и Неопределено, Истину для любого Булево, остальное сравнивает со значением по умолчанию для типа. Поэтому НЕ ЗначениеЗаполнено(ДатаОплаты) поймает и пустую дату, и NULL от набора без пары, а ДатаОплаты ЕСТЬ NULL пустую дату пропустит. Подробнее — в статьях о ЗначениеЗаполнено и о вычисляемых полях СКД.

Стенд: проверка выражений на таблице значений

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

// Стенд для проверки выражений СКД: схема собирается в памяти
// вокруг таблицы значений, запрос к базе не нужен.
// Модуль объекта внешней обработки или общий модуль с флагом «Сервер».

// Выполняет компоновку таблицы значений с заданными выражениями.
//
// Параметры:
//  Данные          - ТаблицаЗначений - исходные строки, у колонок заданы типы.
//  ВычисляемыеПоля - Структура - ключ: путь к данным поля, значение: выражение.
//  Ресурсы         - Структура, Неопределено - ключ: поле, значение: выражение итога.
//  ПоляГруппировки - Строка - поля через запятую; пустая строка - детальные записи.
//
// Возвращаемое значение:
//  ТаблицаЗначений - результат компоновки.
//
Функция ВыполнитьВыраженияСКД(Данные, ВычисляемыеПоля, Ресурсы = Неопределено, ПоляГруппировки = "") Экспорт

	Схема = Новый СхемаКомпоновкиДанных;
	Источник = Схема.ИсточникиДанных.Добавить();
	Источник.Имя = "Источник";
	Источник.ТипИсточникаДанных = "Local";

	// Набор-объект: строки придут из внешней таблицы, а не из запроса.
	Набор = Схема.НаборыДанных.Добавить(Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
	Набор.Имя = "Данные";
	Набор.ИмяОбъекта = "Данные";
	Набор.ИсточникДанных = Источник.Имя;
	Для Каждого Колонка Из Данные.Колонки Цикл
		ПолеНабора = Набор.Поля.Добавить(Тип("ПолеНабораДанныхСхемыКомпоновкиДанных"));
		ПолеНабора.Поле = Колонка.Имя;
		ПолеНабора.ПутьКДанным = Колонка.Имя;
		ПолеНабора.ТипЗначения = Колонка.ТипЗначения;
	КонецЦикла;

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

	Если Ресурсы <> Неопределено Тогда
		ЛюбойПримитивный = Новый ОписаниеТипов("Число, Строка, Дата, Булево");
		Для Каждого Описание Из Ресурсы Цикл
			// Ресурс всегда привязан к полю: для нового имени заводим поле-заглушку.
			// Тип у нее составной, иначе колонка результата возьмет тип из выражения "0".
			Если Набор.Поля.Найти(Описание.Ключ) = Неопределено
				И Схема.ВычисляемыеПоля.Найти(Описание.Ключ) = Неопределено Тогда
				Заглушка = Схема.ВычисляемыеПоля.Добавить();
				Заглушка.ПутьКДанным = Описание.Ключ;
				Заглушка.Выражение = "0";
				Заглушка.ТипЗначения = ЛюбойПримитивный;
			КонецЕсли;
			Ресурс = Схема.ПоляИтога.Добавить();
			Ресурс.ПутьКДанным = Описание.Ключ;
			Ресурс.Выражение = Описание.Значение;
			Если ИменаПолей.Найти(Описание.Ключ) = Неопределено Тогда
				ИменаПолей.Добавить(Описание.Ключ);
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;

	Компоновщик = Новый КомпоновщикНастроекКомпоновкиДанных;
	Компоновщик.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(Схема));
	Настройки = Компоновщик.Настройки;

	// Без группировки выводим все колонки, с группировкой - ее поля; плюс выражения.
	ГруппировочныеПоля = Новый Массив;
	Для Каждого ИмяПоля Из СтрРазделить(ПоляГруппировки, ",", Ложь) Цикл
		ГруппировочныеПоля.Добавить(СокрЛП(ИмяПоля));
	КонецЦикла;
	Выводимые = Новый Массив;
	Если ГруппировочныеПоля.Количество() = 0 Тогда
		Для Каждого Колонка Из Данные.Колонки Цикл
			Выводимые.Добавить(Колонка.Имя);
		КонецЦикла;
	Иначе
		Для Каждого ИмяПоля Из ГруппировочныеПоля Цикл
			Выводимые.Добавить(ИмяПоля);
		КонецЦикла;
	КонецЕсли;
	Для Каждого ИмяПоля Из ИменаПолей Цикл
		Если Выводимые.Найти(ИмяПоля) = Неопределено Тогда
			Выводимые.Добавить(ИмяПоля);
		КонецЕсли;
	КонецЦикла;
	Для Каждого ИмяПоля Из Выводимые Цикл
		ВыбранноеПоле = Настройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
		ВыбранноеПоле.Поле = Новый ПолеКомпоновкиДанных(ИмяПоля);
		ВыбранноеПоле.Использование = Истина;
	КонецЦикла;

	// Группировка без полей группировки - это детальные записи.
	Группировка = Настройки.Структура.Добавить(Тип("ГруппировкаКомпоновкиДанных"));
	Для Каждого ИмяПоля Из ГруппировочныеПоля Цикл
		ПолеГруппировки = Группировка.ПоляГруппировки.Элементы.Добавить(Тип("ПолеГруппировкиКомпоновкиДанных"));
		ПолеГруппировки.Поле = Новый ПолеКомпоновкиДанных(ИмяПоля);
		ПолеГруппировки.Использование = Истина;
	КонецЦикла;
	Группировка.Выбор.Элементы.Добавить(Тип("АвтоВыбранноеПолеКомпоновкиДанных"));
	Группировка.Порядок.Элементы.Добавить(Тип("АвтоЭлементПорядкаКомпоновкиДанных"));

	КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
	Макет = КомпоновщикМакета.Выполнить(Схема, Компоновщик.ПолучитьНастройки(), , ,
		Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));

	// Истина четвертым параметром разрешает функции общих модулей в выражениях.
	Процессор = Новый ПроцессорКомпоновкиДанных;
	Процессор.Инициализировать(Макет, Новый Структура("Данные", Данные), , Истина);

	Результат = Новый ТаблицаЗначений;
	ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
	ПроцессорВывода.УстановитьОбъект(Результат);
	ПроцессорВывода.Вывести(Процессор);

	Возврат Результат;

КонецФункции

Пример: семь продаж в памяти, шесть вычисляемых полей и шесть ресурсов по месяцам.

// Пример для стенда: продажи в памяти, вычисляемые поля и ресурсы.
Процедура ПроверитьВыраженияНаПримере() Экспорт

	Продажи = Новый ТаблицаЗначений;
	Продажи.Колонки.Добавить("Канал", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(50)));
	Продажи.Колонки.Добавить("Склад", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(50)));
	Продажи.Колонки.Добавить("Дата", Новый ОписаниеТипов("Дата", , , Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя)));
	Продажи.Колонки.Добавить("ДатаОплаты", Новый ОписаниеТипов("Дата", , , Новый КвалификаторыДаты(ЧастиДаты.Дата)));
	Продажи.Колонки.Добавить("Количество", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 3)));
	Продажи.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));

	НеОплачено = Дата(1, 1, 1);
	ДобавитьПродажу(Продажи, "Опт", "Основной склад", Дата(2026, 1, 12, 10, 0, 0), Дата(2026, 1, 20), 120, 156000);
	ДобавитьПродажу(Продажи, "Розница", "Склад магазина", Дата(2026, 1, 18, 15, 30, 0), Дата(2026, 1, 18), 3, 4500);
	ДобавитьПродажу(Продажи, "Интернет", "Основной склад", Дата(2026, 1, 25, 11, 15, 0), НеОплачено, 10, 23900);
	ДобавитьПродажу(Продажи, "Опт", "Основной склад", Дата(2026, 2, 3, 9, 40, 0), Дата(2026, 2, 27), 80, 98000);
	ДобавитьПродажу(Продажи, "Розница", "Склад магазина", Дата(2026, 2, 14, 17, 5, 0), Дата(2026, 2, 14), 5, 7200);
	ДобавитьПродажу(Продажи, "Интернет", "Склад магазина", Дата(2026, 2, 21, 13, 20, 0), Дата(2026, 2, 24), 0, 1500);
	ДобавитьПродажу(Продажи, "Опт", "Основной склад", Дата(2026, 3, 2, 10, 10, 0), НеОплачено, 150, 187500);

	// Вычисляемые поля: выражение считается для каждой строки.
	Поля = Новый Структура;
	Поля.Вставить("Размер", "ВЫБОР КОГДА Сумма >= 100000 ТОГДА ""Крупная""
		|КОГДА Сумма >= 20000 ТОГДА ""Средняя"" ИНАЧЕ ""Мелкая"" КОНЕЦ");
	Поля.Вставить("Цена", "ВЫБОР КОГДА Количество = 0 ТОГДА 0 ИНАЧЕ Окр(Сумма / Количество, 2) КОНЕЦ");
	Поля.Вставить("Оплачено", "ЗначениеЗаполнено(ДатаОплаты)");
	Поля.Вставить("ДнейДоОплаты", "РазностьДат(Дата, ВЫБОР КОГДА ЗначениеЗаполнено(ДатаОплаты)
		|ТОГДА ДатаОплаты ИНАЧЕ ТекущаяДата() КОНЕЦ, ""День"")");
	Поля.Вставить("ЭтоМагазин", "СтрНайти(Склад, ""МАГАЗИН"") > 0");
	Поля.Вставить("Подпись", "Канал + "", "" + НРег(Склад) + "": "" + Формат(Сумма, ""ЧДЦ=2"")");

	Детальные = ВыполнитьВыраженияСКД(Продажи, Поля);
	Для Каждого Запись Из Детальные Цикл
		Сообщить(СтрШаблон("%1 | %2 | цена %3 | оплачено: %4 | дней: %5 | магазин: %6",
			Запись.Подпись, Запись.Размер, Запись.Цена, Запись.Оплачено, Запись.ДнейДоОплаты, Запись.ЭтоМагазин));
	КонецЦикла;

	// Ресурсы: выражение считается по всем строкам группировки, здесь - месяца.
	Ресурсы = Новый Структура;
	Ресурсы.Вставить("Сумма", "Сумма(Сумма)");
	Ресурсы.Вставить("Нарастающим", "ВычислитьВыражение(""Сумма(Сумма)"", , , ""Первая"", ""Текущая"")");
	Ресурсы.Вставить("Прирост", "Сумма(Сумма)
		|- ЕстьNull(ВычислитьВыражение(""Сумма(Сумма)"", , , ""Предыдущая"", ""Предыдущая""), 0)");
	Ресурсы.Вставить("Каналов", "Количество(Различные Канал)");
	Ресурсы.Вставить("Склады", "СоединитьСтроки(Массив(Различные Склад), "", "")");
	Ресурсы.Вставить("ВсеОплачены", "Каждый(ЗначениеЗаполнено(ДатаОплаты))");

	ПоМесяцам = ВыполнитьВыраженияСКД(Продажи,
		Новый Структура("МесяцПродажи", "НачалоПериода(Дата, ""Месяц"")"), Ресурсы, "МесяцПродажи");
	Для Каждого Запись Из ПоМесяцам Цикл
		Сообщить(СтрШаблон("%1: сумма %2, нарастающим %3, прирост %4, каналов %5, склады: %6, все оплачены: %7",
			Формат(Запись.МесяцПродажи, "ДФ=MM.yyyy"), Запись.Сумма, Запись.Нарастающим,
			Запись.Прирост, Запись.Каналов, Запись.Склады, Запись.ВсеОплачены));
	КонецЦикла;

КонецПроцедуры

Процедура ДобавитьПродажу(Продажи, Канал, Склад, ДатаПродажи, ДатаОплаты, Количество, Сумма)

	НоваяСтрока = Продажи.Добавить();
	НоваяСтрока.Канал = Канал;
	НоваяСтрока.Склад = Склад;
	НоваяСтрока.Дата = ДатаПродажи;
	НоваяСтрока.ДатаОплаты = ДатаОплаты;
	НоваяСтрока.Количество = Количество;
	НоваяСтрока.Сумма = Сумма;

КонецПроцедуры

Чтобы запустить пример из формы обработки, добавьте команду «ПроверитьВыражения» и кнопку для неё:

// Модуль формы обработки: команда «ПроверитьВыражения» запускает пример.
&НаКлиенте
Процедура ПроверитьВыражения(Команда)

	ПроверитьВыраженияНаСервере();

КонецПроцедуры

&НаСервере
Процедура ПроверитьВыраженияНаСервере()

	// Экспортные методы модуля объекта вызываем через объект обработки.
	ОбработкаОбъект = РеквизитФормыВЗначение("Объект");
	ОбработкаОбъект.ПроверитьВыраженияНаПримере();

КонецПроцедуры

Разбор ключевых строк

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

Агрегатные функции и ВычислитьВыражение в ресурсах

Вычисляемое поле видит одну детальную запись, ресурс — все записи группировки, поэтому поля в нём обёрнуты агрегатными функциями. Ресурсы из примера:

  • ВычислитьВыражение("Сумма(Сумма)", , , "Первая", "Текущая") — сумма от первой записи группировки до текущей, то есть нарастающий итог.
  • С "Предыдущая", "Предыдущая" берётся только прошлая запись. У первого месяца её нет, результат пустой — поэтому разница обёрнута в ЕстьNull.
  • Количество(Различные Канал) — число разных каналов.
  • СоединитьСтроки(Массив(Различные Склад), ", ") — склады одной строкой; без второго параметра разделителем будет перевод строки.
  • Каждый(ЗначениеЗаполнено(ДатаОплаты)) — Истина, если оплачено всё; Любой — если хоть что-то.

Второй параметр ВычислитьВыражение — группировка: "ОбщийИтог", пустая строка (текущая) или имя родительской группировки из настроек. ВычислитьВыражениеСГруппировкойМассив умеет отбирать группы: Количество(ВычислитьВыражениеСГруппировкойМассив("Сумма(Сумма)", "Контрагент", , "Сумма(Сумма) > 100000")) — число клиентов с покупками больше 100 тысяч. Колонка «Рассчитывать по...» на закладке «Ресурсы» ограничивает группировки ресурса, а для одного поля можно завести несколько строк с разными выражениями. Подробнее — в статье о группировках СКД.

Пользовательские поля: выражение для деталей и для итогов

Пользовательское поле-выражение живёт в варианте отчёта: его добавляют на закладке «Пользовательские поля» в настройках или из кода. Выражений у него два — для детальных и для итоговых записей, и для наценки это важно: итог считают отношением сумм, а не суммой процентов.

// Добавляет в настройки пользовательское поле «Наценка, %».
// В детальной записи - наценка строки, в итоговой - отношение сумм группы,
// а не сумма процентов по строкам.
//
// Параметры:
//  Настройки - НастройкиКомпоновкиДанных - настройки компоновщика, связанные со схемой,
//              в которой есть поля Сумма и Себестоимость.
//
// Возвращаемое значение:
//  ПользовательскоеПолеВыражениеКомпоновкиДанных
//
Функция ДобавитьПолеНаценка(Настройки) Экспорт

	Поле = Настройки.ПользовательскиеПоля.Элементы.Добавить(
		Тип("ПользовательскоеПолеВыражениеКомпоновкиДанных"));
	Поле.Заголовок = "Наценка, %";
	Поле.УстановитьВыражения(
		"ВЫБОР КОГДА Себестоимость = 0 ТОГДА 0
		|ИНАЧЕ (Сумма - Себестоимость) / Себестоимость * 100 КОНЕЦ",
		"ВЫБОР КОГДА Сумма(Себестоимость) = 0 ТОГДА 0
		|ИНАЧЕ (Сумма(Сумма) - Сумма(Себестоимость)) / Сумма(Себестоимость) * 100 КОНЕЦ");

	// Путь к данным платформа назначила сама - по нему поле и выводим.
	ВыбранноеПоле = Настройки.Выбор.Элементы.Добавить(Тип("ВыбранноеПолеКомпоновкиДанных"));
	ВыбранноеПоле.Поле = Новый ПолеКомпоновкиДанных(Поле.ПутьКДанным);
	ВыбранноеПоле.Использование = Истина;

	Возврат Поле;

КонецФункции

Метод УстановитьВыражения появился в 8.3.10, старый УстановитьВыражениеИтоговыхЗаписей с тех пор не рекомендуется. Путь к данным полю назначает платформа. Функции общих модулей и другие пользовательские поля в этих выражениях использовать нельзя.

Функции общих модулей в выражениях

То, что неудобно писать выражением, выносят в экспортную функцию серверного общего модуля и вызывают как ИмяМодуля.ИмяФункции(Поле), функцию глобального модуля — просто по имени. Она выполняется для каждой записи, поэтому запросов в ней быть не должно.

// Общий модуль ВыраженияСКДСервер: флаг «Сервер», не глобальный.
// Вызов из выражения вычисляемого поля:
//   ВыраженияСКДСервер.РабочихДнейМежду(Дата, ДатаОплаты)

// Количество будних дней (пн-пт) после ДатаНачала по ДатаОкончания включительно.
// Праздники не учитывает. Запросов нет: функция вызывается для каждой записи отчета.
//
// Параметры:
//  ДатаНачала    - Дата - дата документа.
//  ДатаОкончания - Дата - дата оплаты; NULL и пустая дата дают 0.
//
// Возвращаемое значение:
//  Число
//
Функция РабочихДнейМежду(ДатаНачала, ДатаОкончания) Экспорт

	Если Не ЗначениеЗаполнено(ДатаНачала) Или Не ЗначениеЗаполнено(ДатаОкончания)
		Или ДатаОкончания <= ДатаНачала Тогда
		Возврат 0;
	КонецЕсли;

	СекундВСутках = 86400;
	Дней = 0;
	ТекущийДень = НачалоДня(ДатаНачала) + СекундВСутках;
	Пока ТекущийДень <= НачалоДня(ДатаОкончания) Цикл
		Если ДеньНедели(ТекущийДень) <= 5 Тогда
			Дней = Дней + 1;
		КонецЕсли;
		ТекущийДень = ТекущийДень + СекундВСутках;
	КонецЦикла;

	Возврат Дней;

КонецФункции

Штатная форма отчёта разрешает такие вызовы сама. При выводе своим кодом, например в ПриКомпоновкеРезультата, передайте Истина четвёртым параметром Инициализировать:

// Модуль объекта отчета: свой вывод вместо штатного.
// Без Истина в Инициализировать функции общих модулей в выражениях не выполнятся.
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)

	СтандартнаяОбработка = Ложь;

	Схема = ПолучитьМакет("ОсновнаяСхемаКомпоновкиДанных");
	Настройки = ЭтотОбъект.КомпоновщикНастроек.ПолучитьНастройки();

	КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
	Макет = КомпоновщикМакета.Выполнить(Схема, Настройки, ДанныеРасшифровки);

	Процессор = Новый ПроцессорКомпоновкиДанных;
	Процессор.Инициализировать(Макет, , ДанныеРасшифровки, Истина);

	ДокументРезультат.Очистить();
	ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
	ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
	ПроцессорВывода.Вывести(Процессор);

КонецПроцедуры

Типичные ошибки

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

Частые вопросы

Можно ли в вычисляемом поле сослаться на другое вычисляемое поле?

Справка платформы это запрещает: в выражении допускаются только поля наборов данных. Повторите нужную часть выражения или перенесите расчёт в запрос.

Как сделать нарастающий итог в СКД?

Ресурсом ВычислитьВыражение("Сумма(Сумма)", , , "Первая", "Текущая"). Итог копится в порядке сортировки группировки, поэтому группируйте по периоду по возрастанию.

Почему «% в группировке» показывает 100%?

Вложенные поля числового ресурса «% в группировке», «% общий» и другие считаются только в таблице, вне её справка обещает 100%. В отчёте с обычными группировками долю считают сами: Сумма(Сумма) / ВычислитьВыражение("Сумма(Сумма)", "ОбщийИтог") * 100, защитив знаменатель через ВЫБОР.

Почему РазностьДат в днях даёт 2, хотя не прошло и двух суток?

Функция считает переходы через границу суток: в примере справки с 12 октября 10:15 до 14 октября 09:18 выходит 2. Полные сутки дадут секунды: Цел(РазностьДат(Дата, ДатаОплаты, "Секунда") / 86400).

Когда проще заказать

Если выражения разрослись до формул на полстраницы, нужны расчёты по производственному календарю, свои макеты или вывод кодом с расшифровкой, быстрее отдать отчёт программисту: доработка отчётов и обработок 1С. Разместите задачу на площадке — оценка бесплатная, ответ в течение рабочего дня.

По теме

Не хотите разбираться сами?

Адаптируем это решение под вашу базу. Оценка бесплатно.

Оставить задачу

Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.


1С, 1С:Предприятие — товарные знаки ООО «1С». Сайт не является официальным представительством фирмы «1С» и не аффилирован с ней.