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