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