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

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При разработке отчетов на базе Системы компоновки данных (СКД) часто возникает задача вывести дополнительные сведения о партнере, например, его адрес электронной почты. Многие разработчики пытаются реализовать это «на лету» в вычисляемом поле, используя функции общего модуля УправлениеКонтактнойИнформацией. Однако при попытке обратиться к результату функции через индекс, например [0].Значение, система выдает ошибку компоновки макета. Давайте разберем, почему так происходит и как решить эту задачу правильно.

Анализ проблемы: почему возникает синтаксическая ошибка?

Главная причина кроется в том, что язык выражений СКД — это не полноценный встроенный язык программирования 1С. Это декларативный язык, предназначенный для выполнения простых арифметических или логических операций. У него есть жесткие ограничения:

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

Решение 1: Использование обертки для корректного возврата значения

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

Рассмотрим пример кода, который стоит реализовать в общем модуле:


Функция ПолучитьПервыйEmailПартнера(Партнер) Экспорт
    МассивКонтактов = УправлениеКонтактнойИнформацией.ЗначенияКонтактнойИнформацииОбъекта(
        Партнер, 
        ПредопределенноеЗначение("Перечисление.ТипыКонтактнойИнформации.АдресЭлектроннойПочты")
    );
    
    Если МассивКонтактов.Количество() > 0 Тогда
        Возврат МассивКонталтов[0].Значение;
    Иначе
        Возврат "";
    КонецЕсли;
КонецФункции

В этом случае в вычисляемом поле СКД вы просто пишете: ПолучитьПервыйEmailПартнера(Партнер). Это чисто, понятно и исключает синтаксические ошибки обращения к индексам массива внутри выражений СКД.

Решение 2: Использование методов преобразования коллекции

Как было предложено в ходе обсуждения на форуме, можно воспользоваться вспомогательными методами платформы, которые возвращают понятные для СКД типы данных. Метод ОбщегоНазначения.ВыгрузитьКолонку позволяет извлечь данные из таблицы в массив, что может быть корректно воспринято компоновщиком.

Пример использования в выражении поля:


ОбщегоНазначения.ВыгрузитьКолонку(
    УправлениеКонтактнойИнформацией.ЗначенияКонтактнойИнформацииОбъекта(
        Партнер, 
        ПредопределенноеЗначение("Перечисление.ТипыКонтактнойИнформации.АдресЭлектроннойПочты")
    ), 
    "Значение"
)

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

Рекомендованный архитектурный подход: Соединение в запросе

Наилучшим способом получения дополнительных данных для отчета является левое соединение в основном запросе набора данных. Это позволяет СУБД объединить таблицы наиболее оптимальным способом.

Вместо вычисляемых полей, выполните следующее:

  1. Откройте набор данных «Запрос» в СКД.
  2. Добавьте в запрос объединение с виртуальной таблицей контактной информации (например, КонтактнаяИнформация).
  3. Используйте условие соединения по Объект и Вид контактной информации.
  4. Если у партнера может быть несколько адресов, используйте ВЫБРАТЬ ПЕРВЫЕ 1 или сгруппируйте данные в запросе.

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

← На главную