Как получить значение из структуры в вычисляемом поле СКД

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

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

Ограничения языка выражений системы компоновки данных

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

  1. Обращение через точку: разыменование через точку в СКД поддерживается только для реквизитов ссылочных типов данных (справочников, документов, перечислений и т. д.). Для произвольных объектов и структур, возвращаемых функциями, синтаксис вида Функция().ИмяПоля вызывает ошибку синтаксического анализатора.
  2. Обращение через квадратные скобки: оператор индексатора [] в языке выражений СКД не поддерживается, поэтому запись вида Функция()["ИмяПоля"] также не будет обработана.

Рассмотрим рабочие способы обойти это ограничение платформы.

Способ 1. Использование универсальной функции-геттера

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

Посмотрим на пример кода в общем модуле (например, ОбщегоНазначенияКлиентСервер или специализированном модуле отчетов):


Функция ПолучитьСвойствоСтруктуры(Структура, ИмяСвойства) Экспорт
    Если ТипЗнч(Структура) = Тип("Структура") И Структура.Свойство(ИмяСвойства) Тогда
        Возврат Структура[ИмяСвойства];
    КонецЕсли;
    Возврат Неопределено;
КонецФункции

Теперь в схеме компоновки данных на вкладке Вычисляемые поля в колонке Выражение мы можем вызвать вложенную конструкцию:

ИмяОбщегоМодуля.ПолучитьСвойствоСтруктуры(ИмяОбщегоМодуля.ТвояФункция(Параметры), "ИмяКлюча")

В этом случае платформа сначала выполнит исходную функцию, передаст полученную структуру в функцию-геттер и вернет конкретное скалярное значение в вычисляемое поле отчета.

Способ 2. Доработка исходной функции или создание специализированной

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

Посмотрим на пример реализации:


Функция ТвояФункция(Параметр1, Параметр2, ИмяКлюча = "") Экспорт
    // Формирование структуры данных
    Результат = Новый Структура;
    Результат.Вставить("Сумма", 1000);
    Результат.Вставить("Количество", 10);
    
    Если ЗначениеЗаполнено(ИмяКлюча) Тогда
        Если Результат.Свойство(ИмяКлюча) Тогда
            Возврат Результат[ИмяКлюча];
        КонецЕсли;
        Возврат Неопределено;
    КонецЕсли;
    
    Возврат Результат;
КонецФункции

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

ИмяОбщегоМодуля.ТвояФункция(Поле1, Поле2, "Сумма")

Оптимизация производительности при вызове функций в СКД

Обратим внимание на важный архитектурный аспект: если из одной структуры требуется получить сразу несколько значений в разные колонки отчета (например, «Сумма», «Количество», «Цена»), то для каждой строки отчета функция расчета будет вызываться повторно для каждого вычисляемого поля. При больших объемах данных это существенно замедлит формирование отчета.

Для оптимизации расчетов применим следующие подходы:

  1. Кэширование на время вызова: если исходная функция вынесена в общий модуль со свойством Повторное использование возвращаемых значений, установленным в значение На время вызова, платформа выполнит тяжелый расчет только один раз для одинакового набора параметров, а последующие вызовы функций-геттеров для той же строки будут моментально считывать результат из кэша.
  2. Набор данных — Объект: если расчеты комплексные и затрагивают много полей, эффективнее отказаться от вычисляемых полей. В этом случае данные рассчитываются предварительно в коде модуля отчета перед компоновкой (например, в событии ПриКомпоновкеРезультата), выгружаются в объект ТаблицаЗначений со всеми готовыми колонками и передаются в СКД через набор данных типа «Объект».

Требования к общим модулям при вызове из СКД

Проверим настройки конфигурации, чтобы вызов функций в СКД завершался успешно:

  1. Общий модуль должен иметь установленный флаг Сервер (или Клиент (управляемое приложение) в зависимости от контекста формирования) и признак Вызов сервера, если обращение идет с клиента.
  2. Функция обязательно должна иметь ключевое слово Экспорт.
  3. При программном выводе отчета с инициализацией объекта ПроцессорКомпоновкиДанных необходимо убедиться, что параметр ВозможностьИспользованияВнешнихФункций установлен в значение Истина.
← На главную