При настройке пользовательских и вычисляемых полей в отчетах на базе схемы компоновки данных (СКД) разработчики и аналитики часто сталкиваются с ошибкой Синтаксическая ошибка. Подобные ситуации возникают при расчете удельных показателей, нормализации данных за период или пересчете ставок, когда формула объединяет поля выборки, параметры и числовые коэффициенты. Разберем по шагам, почему возникает эта ошибка и как правильно составить расчетное выражение в СКД.
Проанализируем выражение, вызвавшее сбой:
Сумма / [Отработано часов] * [Отработано часов в периоде] / РазностьДат(&[Начало периода], &[Конец периода], "День")*30,41
Главная причина синтаксической ошибки здесь заключается в записи числа с плавающей точкой: 30,41. В языке выражений системы компоновки данных, как и во встроенном языке 1С, в качестве десятичного разделителя в числовых литералах допускается исключительно точка. Запятая воспринимается парсером как разделитель аргументов функций или элементов списка. Встретив запятую посреди арифметического действия, транслятор формул выдает сообщение о синтаксической ошибке.
Для исправления коэффициента заменим запятую на точку: 30.41.
Посмотрим на другие элементы формулы, которые могут вызвать проблемы при выполнении или формировании отчета:
[...] в выражениях СКД служат для экранирования имен полей набора данных, если они содержат пробелы. Параметры схемы задаются через знак амперсанда без квадратных скобок (например, &НачалоПериода, &КонецПериода). Имена параметров в СКД не должны содержать пробелов. Если в отчете используется стандартный период, обращение к датам выполняется через точку: &Период.ДатаНачала и &Период.ДатаОкончания.РазностьДат передается обязательно как строковый литерал в кавычках (например, "День", "Месяц", "Час"). Если опустить кавычки (как это делается в текстах запросов), система воспримет слово как обращение к полю выборки и сообщит, что поле не найдено. В исходной формуле кавычки расставлены верно.Дата2 - Дата1. Если дата начала передана вторым аргументом, результат будет отрицательным. Первым аргументом всегда указывается начальная граница, а вторым — конечная.РазностьДат(&ДатаНачала, &ДатаОкончания, "День") вернет 0. Если требуется рассчитать количество включенных календарных дней, к функции прибавляют единицу: (РазностьДат(&ДатаНачала, &ДатаОкончания, "День") + 1).Даже после исправления синтаксиса отчет может завершиться аварийно в процессе формирования, если один из делителей в знаменателе окажется равен нулю или значению NULL. В формуле присутствуют сразу два потенциальных источника ошибки:
[Отработано часов] может быть не заполнено (равно NULL) или равно нулю для сотрудников без зарегистрированного времени.Чтобы отчет работал стабильно, добавим проверку через условную конструкцию ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ и функцию ЕстьNull. Рассмотрим итоговый безопасный вариант формулы:
ВЫБОР
КОГДА ЕстьNull([Отработано часов], 0) = 0
ИЛИ РазностьДат(&НачалоПериода, &КонецПериода, "День") = 0
ТОГДА 0
ИНАЧЕ Сумма / [Отработано часов] * [Отработано часов в периоде] / РазностьДат(&НачалоПериода, &КонецПериода, "День") * 30.41
КОНЕЦ
Выясним причину, почему пользовательские поля в настройках отчета не всегда подходят для сложных расчетов:
РАЗНОСТЬДАТ(&НачалоПериода, &КонецПериода, ДЕНЬ). Это повышает общую производительность отчета и исключает ошибки ручного ввода формул пользователями.