Как правильно использовать выражения в вычисляемых полях СКД и почему возникают синтаксические ошибки?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При работе с Системой компоновки данных (СКД) разработчики часто сталкиваются с ситуацией, когда привычный код на встроенном языке 1С выдает ошибку "Синтаксическая ошибка" или "Функция не найдена" в поле «Выражение» вычисляемых полей. Рассмотрим подробно, почему это происходит, в чем заключаются основные отличия языков и как правильно писать формулы, чтобы отчет работал корректно.

Разбор типичной ошибки: смешение языков программирования

Разберем ситуацию: программист пытается написать в вычисляемом поле выражение ?(ПустаяСтрока(ФизЛицо.КК), КолвоДней*50, ""). На первый взгляд, логика верна, но система выдает ошибку. Выясним причину. В экосистеме 1С существует три разных синтаксиса, которые важно не путать:

  1. Встроенный язык (код в модулях): здесь мы используем тернарный оператор ?(), функции ПустаяСтрока() и ЗначениеЗаполнено().
  2. Язык запросов: он используется внутри текста запроса (набор данных - запрос). Здесь нет тернарного оператора, а проверка условий выполняется через конструкцию ВЫБОР КОГДА ... ТОГДА ... ИНАЧЕ ... КОНЕЦ.
  3. Язык выражений СКД: используется в вычисляемых полях и ресурсах. Он очень похож на язык запросов, но дополнен специальными функциями.

Важно: оператор ?() и функция ПустаяСтрока() не входят в стандарт языка выражений СКД. Именно поэтому попытка их использования напрямую ведет к ошибке.

Решение 1: Использование универсальной функции ЗначениеЗаполнено

Проанализируем самый эффективный способ проверки полей на пустоту. Начиная с версии платформы 8.3, функция ЗначениеЗаполнено() была добавлена непосредственно в язык выражений СКД. Это универсальный инструмент, который одинаково хорошо обрабатывает:

Посмотрим на пример правильного выражения для вычисляемого поля:


ВЫБОР 
    КОГДА НЕ ЗначениеЗаполнено(ФизЛицо.КК) 
        ТОГДА КолвоДней * 50 
    ИНАЧЕ 0 
КОНЕЦ

Решение 2: Применение конструкции ВЫБОР для строковых полей

Если мы имеем дело именно со строками и хотим имитировать поведение ПустаяСтрока(), разберем альтернативный вариант с явным сравнением. В языке выражений СКД (как и в запросах) пустоту строки можно проверить путем сравнения с пустой строковой константой. Однако здесь кроется подвох: если поле может содержать NULL, обычное сравнение Поле = "" может не сработать.

Проанализируем правильную конструкцию с использованием ЕстьNULL:


ВЫБОР 
    КОГДА ЕстьNULL(ФизЛицо.КК, "") = "" 
        ТОГДА КолвоДней * 50 
    ИНАЧЕ 0 
КОНЕЦ

В данном примере функция ЕстьNULL подменяет отсутствующее значение в базе данных на пустую строку, что позволяет корректно выполнить сравнение.

Почему функция ПустаяСтрока не работает в СКД?

Выясним причину, по которой ПустаяСтрока вызывает ошибку «Функция не найдена». Движок СКД ищет эту функцию во внутреннем списке доступных операторов языка выражений. Поскольку она там не задекларирована, система пытается найти ее среди экспортных функций общих модулей.

Если вам критически важно использовать именно ПустаяСтрока, вы можете вызвать ее через общий модуль, например: ОбщегоНазначения.ПустаяСтрока(Поле). Однако помните о двух условиях:

  1. Функция должна быть помечена ключевым словом Экспорт.
  2. В настройках схемы компоновки данных (вкладка «Прочее») должна быть установлена галочка «Разрешить вызов функций общих модулей».

Важный нюанс: вызов функций общих модулей из СКД работает значительно медленнее, чем использование встроенных механизмов типа ЗначениеЗаполнено, так как требует переключения контекста исполнения.

Доступные функции в СКД, которых нет в обычных запросах

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

Посмотрим на пример использования нескольких функций в одном выражении:


ВЫБОР 
    КОГДА ДлинаСтроки(ФизЛицо.КК) > 0 
        ТОГДА ВРег(ФизЛицо.КК) 
    ИНАЧЕ "ЗНАЧЕНИЕ НЕ УКАЗАНО" 
КОНЕЦ

Критическое ограничение вычисляемых полей

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

Например, если вы создали вычисляемое поле ЦенаСоСкидкой с формулой Цена * 0.9, и хотите создать второе поле ИтоговаяСумма, вы не сможете написать в нем ЦенаСоСкидкой * Количество. Система выдаст ошибку, так как на момент расчета второго поля первое еще может быть не определено в памяти.

Как обойти это ограничение: необходимо дублировать формулы. Для нашего примера выражение в поле ИтоговаяСумма должно выглядеть так: (Цена * 0.9) * Количество. Это увеличивает размер выражений, но гарантирует стабильную работу отчета.

Порядок выполнения и производительность

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

  1. Данные из запроса сначала попадают в память сервера приложений (в объект РезультатКомпоновки).
  2. Затем для каждой строки результата выполняется расчет вашего выражения.

С одной стороны, это позволяет использовать функции, которые база данных "не понимает" (например, преобразование в строку сложных типов). С другой стороны, если в вашем отчете миллион строк, сложные вычисления в вычисляемых полях могут заметно замедлить формирование отчета. В таких случаях расчеты лучше переносить непосредственно в текст запроса, используя ВЫБОР КОГДА там.

Итоги и рекомендации

Подведем итог нашему разбору. Для создания надежных и быстрых отчетов в СКД придерживайтесь следующих правил:

Соблюдение этих простых правил поможет вам избежать большинства ошибок синтаксиса и сделает ваши отчеты более профессиональными и производительными.

← На главную