Выражения СКД в 1С — формулы на языке выражений системы компоновки данных. На нём пишут вычисляемые поля, ресурсы, параметры, связи наборов, параметры макетов и пользовательские поля. Язык похож на язык запросов, но синтаксис у части функций другой. Ниже — шпаргалка по функциям, сверенная со справкой платформы 8.3.27, отличия от запросов, примеры ВЫБОР, Есть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 и ЗначениеЗаполнено:
| Задача | Выражение |
|---|---|
| Размер сделки | ВЫБОР КОГДА Сумма >= 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(План, 0).Сумма / Количество на строке услуги с нулевым количеством обрывает формирование ошибкой «Деление на 0». Защита — ВЫБОР.Инициализировать. Другая ловушка — тяжёлая функция: КалендарныеГрафики.РазностьДатПоКалендарю из БСП (в УТ 11.4) делает несколько запросов на каждую строку отчёта. Такие данные берите в запросе набора.Справка платформы это запрещает: в выражении допускаются только поля наборов данных. Повторите нужную часть выражения или перенесите расчёт в запрос.
Ресурсом ВычислитьВыражение("Сумма(Сумма)", , , "Первая", "Текущая"). Итог копится в порядке сортировки группировки, поэтому группируйте по периоду по возрастанию.
Вложенные поля числового ресурса «% в группировке», «% общий» и другие считаются только в таблице, вне её справка обещает 100%. В отчёте с обычными группировками долю считают сами: Сумма(Сумма) / ВычислитьВыражение("Сумма(Сумма)", "ОбщийИтог") * 100, защитив знаменатель через ВЫБОР.
Функция считает переходы через границу суток: в примере справки с 12 октября 10:15 до 14 октября 09:18 выходит 2. Полные сутки дадут секунды: Цел(РазностьДат(Дата, ДатаОплаты, "Секунда") / 86400).
Если выражения разрослись до формул на полстраницы, нужны расчёты по производственному календарю, свои макеты или вывод кодом с расшифровкой, быстрее отдать отчёт программисту: доработка отчётов и обработок 1С. Разместите задачу на площадке — оценка бесплатная, ответ в течение рабочего дня.
Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.