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