При разработке отчетов в системе компоновки данных (СКД) нередко возникает необходимость использовать функции общих модулей в вычисляемых полях. Однако если функция возвращает сложный тип данных, например объект типа Структура, разработчики сталкиваются с тем, что стандартные способы обращения к свойствам не работают. Разберем особенности языка выражений СКД и практические способы решения этой задачи.
Выясним причину, почему стандартные синтаксические конструкции 1С не срабатывают в поле Выражение вычисляемых полей СКД:
Функция().ИмяПоля вызывает ошибку синтаксического анализатора.[] в языке выражений СКД не поддерживается, поэтому запись вида Функция()["ИмяПоля"] также не будет обработана.Рассмотрим рабочие способы обойти это ограничение платформы.
Проанализируем наиболее универсальный подход, который не требует переписывания уже существующих функций конфигурации. Для этого создадим в общем модуле вспомогательную экспортную функцию для извлечения нужного ключа из переданной структуры.
Посмотрим на пример кода в общем модуле (например, ОбщегоНазначенияКлиентСервер или специализированном модуле отчетов):
Функция ПолучитьСвойствоСтруктуры(Структура, ИмяСвойства) Экспорт
Если ТипЗнч(Структура) = Тип("Структура") И Структура.Свойство(ИмяСвойства) Тогда
Возврат Структура[ИмяСвойства];
КонецЕсли;
Возврат Неопределено;
КонецФункции
Теперь в схеме компоновки данных на вкладке Вычисляемые поля в колонке Выражение мы можем вызвать вложенную конструкцию:
ИмяОбщегоМодуля.ПолучитьСвойствоСтруктуры(ИмяОбщегоМодуля.ТвояФункция(Параметры), "ИмяКлюча")
В этом случае платформа сначала выполнит исходную функцию, передаст полученную структуру в функцию-геттер и вернет конкретное скалярное значение в вычисляемое поле отчета.
Если у нас есть доступ к исходной функции общего модуля, разберем возможность добавления параметра, определяющего возвращаемое значение.
Посмотрим на пример реализации:
Функция ТвояФункция(Параметр1, Параметр2, ИмяКлюча = "") Экспорт
// Формирование структуры данных
Результат = Новый Структура;
Результат.Вставить("Сумма", 1000);
Результат.Вставить("Количество", 10);
Если ЗначениеЗаполнено(ИмяКлюча) Тогда
Если Результат.Свойство(ИмяКлюча) Тогда
Возврат Результат[ИмяКлюча];
КонецЕсли;
Возврат Неопределено;
КонецЕсли;
Возврат Результат;
КонецФункции
В выражении вычисляемого поля СКД теперь достаточно указать имя требуемого свойства в качестве параметра:
ИмяОбщегоМодуля.ТвояФункция(Поле1, Поле2, "Сумма")
Обратим внимание на важный архитектурный аспект: если из одной структуры требуется получить сразу несколько значений в разные колонки отчета (например, «Сумма», «Количество», «Цена»), то для каждой строки отчета функция расчета будет вызываться повторно для каждого вычисляемого поля. При больших объемах данных это существенно замедлит формирование отчета.
Для оптимизации расчетов применим следующие подходы:
На время вызова, платформа выполнит тяжелый расчет только один раз для одинакового набора параметров, а последующие вызовы функций-геттеров для той же строки будут моментально считывать результат из кэша.ПриКомпоновкеРезультата), выгружаются в объект ТаблицаЗначений со всеми готовыми колонками и передаются в СКД через набор данных типа «Объект».Проверим настройки конфигурации, чтобы вызов функций в СКД завершался успешно:
Экспорт.ПроцессорКомпоновкиДанных необходимо убедиться, что параметр ВозможностьИспользованияВнешнихФункций установлен в значение Истина.