При разработке сложных отчетов на Системе Компоновки Данных (СКД) разработчики часто расширяют стандартный функционал, используя вычисляемые поля. Когда встроенных функций языка выражений СКД становится недостаточно, логичным решением становится вызов экспортных функций из общих модулей конфигурации. Готовые варианты реализации можно посмотреть в примерах отчетов со сложными выражениями в СКД.
В обычном режиме, когда отчет формируется платформой автоматически, такие вызовы работают корректно. Однако при переходе к программному формированию отчета (например, для реализации сложной логики в обработчике ПриКомпоновкеРезультата, создания рассылок или сохранения в файл), система часто выдает "Синтаксическую ошибку". При этом имя функции указано верно, и она доступна в глобальном контексте.
В этой статье мы разберем причину этого поведения и научимся правильно инициализировать процессор компоновки для работы с внешними функциями.
Представьте ситуацию: в схеме компоновки данных добавлено поле, выражение которого обращается к общему модулю:
УправлениеОтчетами.ПолучитьНомерГДизГТД(НомерГТД)
Если запустить отчет стандартно — всё работает. Но стоит нам переопределить процесс формирования в модуле объекта отчета, как выполнение прерывается ошибкой:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных,
КомпоновщикНастроек.Настройки,,,
Тип("ГенераторМакетаКомпоновкиДанных"));
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
// Ошибка возникает именно здесь:
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
// ... дальнейший вывод в табличный документ ...
КонецПроцедуры
Текст ошибки: Синтаксическая ошибка "УправлениеОтчетами.ПолучитьНомерГДизГТД". Проблема заключается в том, что по умолчанию процессор компоновки данных работает в изолированном режиме, где доступ к внешним функциям ограничен в целях безопасности.
Чтобы исправить ситуацию, необходимо заглянуть в синтаксис-помощник и изучить параметры метода Инициализировать объекта ПроцессорКомпоновкиДанных. Его сигнатура выглядит так:
Инициализировать(<Макет>, <ВнешниеНаборыДанных>, <ДанныеРасшифровки>, <ВозможностьИспользованияВнешнихФункций>, ...)
Ключевым является четвертый параметр — ВозможностьИспользованияВнешнихФункций. Если он не задан, платформа устанавливает его в Ложь. Это предотвращает выполнение кода при использовании схем из сомнительных источников. Для корректной работы вашего отчета параметр нужно явно установить в Истина:
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
// Разрешаем использование внешних функций (4-й параметр)
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки, , , Истина);
После этой правки СКД успешно распознает вызов общего модуля, и "Синтаксическая ошибка" исчезнет.
Если после передачи параметра ошибка сохраняется, убедитесь, что соблюдены технические требования к вызываемой функции:
Экспорт.При использовании данного метода важно помнить о двух аспектах:
Если ваш отчет является внешней обработкой и запускается в безопасном режиме, платформа может блокировать вызовы даже при наличии флага Истина. В таких случаях требуется настройка профилей безопасности в информационной базе.
Вызов функций в СКД происходит итерационно для каждой строки. Это может существенно замедлить работу. Если внутри функции выполняется запрос, вы столкнетесь с лавинообразным ростом нагрузки на сервер. В таких случаях эффективнее подготовить данные заранее и передать их как внешний набор данных (Таблицу Значений).
Для исправления ошибки при программном формировании отчета:
ПроцессорКомпоновкиДанных.Инициализировать в значение Истина.