Как исправить ошибку в вычисляемых полях СКД при использовании функций общих модулей и программном выводе отчета?

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

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

Проблема 1: Ошибка инициализации внешних функций при программном выводе

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

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

Рассмотрим стандартный (нерабочий в данном контексте) код инициализации:


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

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


// Параметры метода:
// 1. МакетКомпоновки
// 2. ВнешниеНаборыДанных (необязательно)
// 3. ДанныеРасшифровки (необязательно)
// 4. ВозможностьИспользованияВнешнихФункций (Истина для разрешения вызовов)

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

После установки этого флага в значение Истина, движок СКД получит разрешение на обращение к серверным методам конфигурации. Важно помнить, что функция в общем модуле должна иметь признак Экспорт, а сам модуль должен быть доступен на сервере.

Проблема 2: Ошибка "Неверные параметры *" и проблемы типизации

Даже если функция успешно вызывается, можно столкнуться со следующей ошибкой: "Ошибка в выражении: Неверные параметры '*'". Проанализируем ситуацию: выражение вида Утечка * опМодуль.КореньКвадратный(Давление) внезапно перестает работать, хотя по отдельности поля выводятся нормально.

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


Функция КореньКвадратный(Значение) Экспорт
    Результат = Sqrt(Значение);
    Возврат Формат(Результат, "ЧДЦ=2"); // ОШИБКА! Возвращается строка
КонецФункции

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

Рекомендуется возвращать из функции чистое числовое значение:


Функция КореньКвадратный(Значение) Экспорт
    // Возвращаем только число
    Возврат Sqrt(Число(Значение)); 
КонецФункции

Если же вам необходимо ограничить количество знаков после запятой в отчете, используйте вкладку "Наборы данных" или "Вычисляемые поля" в СКД, настроив свойство "Оформление" -> "Формат" для конкретного поля. Это позволит сохранить числовой тип данных для итогов и при этом красиво отобразить результат пользователю.

Полезные советы по оптимизации вычислений в СКД

Проанализируем еще несколько моментов, которые помогут избежать ошибок и ускорить работу отчетов:

  1. Использование встроенной функции POW: Если вам нужно извлечь квадратный корень, не обязательно обращаться к общему модулю. В языке выражений СКД есть функция POW(Число, Степень). Корень квадратный — это возведение в степень 0.5. Запись POW(ПолеДавление, 0.5) будет работать быстрее, так как не требует переключения контекста выполнения между СКД и встроенным языком 1С.
  2. Обработка значений NULL: При выполнении математических операций во внешних функциях всегда проверяйте входные данные. Если в поле Давление придет NULL, внешняя функция может вызвать исключение. Используйте конструкцию ЕстьNull(Давление, 0) прямо в выражении вычисляемого поля.
  3. Глобальные модули: Если ваш общий модуль помечен как "Глобальный", то в СКД к его функциям нужно обращаться напрямую по имени функции: ИмяФункции(). Если модуль не глобальный, обращение идет через точку: ИмяМодуля.ИмяФункции().
  4. Тип поля "Число": Убедитесь, что у вычисляемого поля в колонке "Тип значения" явно указано "Число". Это помогает системе заранее подготовить соответствующие механизмы агрегации (сумм, средних и т.д.).

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

← На главную