Как в отчете СКД вывести текст из ресурса с типом данных Форматированный документ

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

При разработке отчетов в системе 1С часто возникает ситуация, когда стандартных строковых реквизитов недостаточно для хранения информации. Например, в конфигурации 1С:Экзаменатор или в блоках управления контентом полное наименование вопроса или описание задачи может храниться в формате ФорматированныйДокумент. На уровне базы данных такие данные упаковываются в ХранилищеЗначения.

Попытка вывести такое поле в отчет Системы компоновки данных (СКД) «напрямую» через запрос приведет к тому, что в колонке отчета будет пустота или техническое описание объекта. Рассмотрим подробно, как правильно извлечь текст и отобразить его в отчете.

Почему данные не выводятся стандартным способом

Проанализируем ситуацию: реквизит с типом ФорматированныйДокумент — это сложный объект, который может содержать не только текст, но и шрифты, цвета, списки и даже изображения. Чтобы сохранить всю эту структуру в базе данных, платформа 1С использует ХранилищеЗначения.

Когда СКД выполняет запрос к базе данных, она получает бинарные данные из хранилища. Система компоновки не умеет автоматически «распаковывать» этот объект и преобразовывать его в читаемую строку прямо в ячейке табличного документа. Выясним причину неудачи: у объекта ХранилищеЗначения нет метода ПолучитьТекст(), а сам ФорматированныйДокумент недоступен напрямую в языке запросов SQL. Для решения задачи нам потребуется создать программную «прослойку».

Шаг 1. Создание экспортной функции в общем модуле

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

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

Теперь проанализируем пример кода, который позволит нам извлечь чистый текст без лишнего оформления:


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

Важный момент: метод ПолучитьТекст(ТекстРезультат) работает именно так — он наполняет переданную в него переменную. Это распространенная ошибка среди начинающих разработчиков, которые ожидают, что метод вернет строку в качестве результата функции.

Шаг 2. Настройка вычисляемого поля в СКД

После того как функция написана и сохранена, нам нужно заставить СКД использовать ее. Рассмотрим, как это сделать в конструкторе схемы компоновки данных:

  1. Откроем вкладку Вычисляемые поля.
  2. Добавим новое поле. В колонке Путь к данным укажем понятное имя, например, НаименованиеПолноеТекст.
  3. В колонке Выражение вызовем нашу функцию, передав в нее имя поля из набора данных (запроса), в котором лежит хранилище. Например: ИмяВашегоОбщегоМодуля.ИзвлечьТекстИзФорматированногоДокумента(НаименованиеДляПечати).
  4. Укажем Заголовок для колонки отчета.

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

Шаг 3. Разрешение вызова внешних функций

В современных версиях платформы 1С (8.3.15 и выше) безопасность выполнения кода усилена. Если вы столкнулись с тем, что метод не найден или вызов блокируется, нужно проверить настройки процессора компоновки. Рассмотрим ситуацию программного вывода отчета.

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


ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки, ВнешниеНаборыДанных, ДанныеРасшифровки, Истина);

Особенности форматирования и производительности

Проанализируем дополнительные нюансы, которые могут возникнуть при работе с этим методом.

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

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

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

← На главную