Как получить и отобразить значение из ХранилищаЗначения в отчете СКД

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

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

Способ 1: Использование экспортных функций в вычисляемых полях

Проанализируем самый распространенный и простой в реализации метод — использование функции-обертки. Этот способ идеально подходит, когда данных в отчете немного, и нам нужно быстро «распаковать» содержимое хранилища прямо в процессе формирования строк компоновки.

Разберем по шагам алгоритм реализации:

  1. Создадим в общем модуле (например, ОбщегоНазначения) экспортную функцию. Важно, чтобы у модуля были установлены флаги Сервер, Внешнее соединение и, при необходимости, Вызов сервера.
  2. В функции пропишем логику извлечения данных. Проанализируем пример кода:

Функция ИзвлечьДанныеИзХранилища(ОбъектХранилище) Экспорт
    Если ТипЗнч(ОбъектХранилище) <> Тип("ХранилищеЗначения") Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    Попытка
        Возврат ОбъектХранилище.Получить();
    Исключение
        Возврат Неопределено;
    КонецПопытки;
КонецФункции

Затем в схеме компоновки данных (СКД) перейдем на закладку Вычисляемые поля. Добавим новое поле, укажем его заголовок, а в колонке Выражение пропишем вызов нашей функции, передавая в нее имя поля из запроса, которое содержит бинарные данные: ОбщегоНазначения.ИзвлечьДанныеИзХранилища(ПолеХранилищеИзЗапроса).

Важный нюанс производительности: Выясним причину, по которой этот метод может замедлять отчет. Система будет вызывать эту функцию для каждой строки результата. Если в отчете 10 000 строк, функция выполнится 10 000 раз. Если внутри хранилища лежат тяжелые объекты, время формирования отчета существенно возрастет.

Способ 2: Набор данных - объект (Внешняя таблица значений)

Если мы работаем с большими массивами данных, рассмотрим более производительный вариант — использование объектного набора данных. В этом случае мы берем на себя управление выборкой данных и их «распаковкой» еще до того, как СКД начнет их обрабатывать.

Алгоритм действий будет следующим:

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

Посмотрим на пример кода в модуле объекта отчета или в обработке:


// 1. Формируем таблицу значений с нужной структурой
ТЗДанных = Новый ТаблицаЗначений;
ТЗДанных.Колонки.Добавить("Номенклатура", Новый ОписаниеТипов("СправочникСсылка.Номенклатура"));
ТЗДанных.Колонки.Добавить("РаспакованныеДанные", Новый ОписаниеТипов("Строка"));

// 2. Выбираем данные из регистра
Запрос = Новый Запрос("ВЫБРАТЬ Номенклатура, ДанныеХранилище ИЗ РегистрСведений.ДополнительныеСведения");
Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
    НоваяСтрока = ТЗДанных.Добавить();
    НоваяСтрока.Номенклатура = Выборка.Номенклатура;
    
    // Распаковываем данные один раз в коде
    Если ТипЗнч(Выборка.ДанныеХранилище) = Тип("ХранилищеЗначения") Тогда
        НоваяСтрока.РаспакованныеДанные = Выборка.ДанныеХранилище.Получить();
    КонецЕсли;
КонецЦикла;

// 3. Передаем таблицу в СКД
ВнешниеНаборыДанных = Новый Структура;
ВнешниеНаборыДанных.Вставить("ТаблицаСДанными", ТЗДанных);

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

Этот метод исключает многократные серверные вызовы в процессе компоновки, так как СКД получает уже готовую, «чистую» таблицу.

Ограничения и особенности работы в запросах

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

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

Вывод изображений из хранилища

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

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

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

← На главную