Как вывести картинку из Хранилища Значений в СКД при компоновке результата?

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

При разработке отчетов, например, прайс-листов с фотографиями номенклатуры, часто возникает задача вывести изображения в результирующий табличный документ. Нередко разработчики пытаются решить эту задачу программно в процедуре ПриКомпоновкеРезультата, обходя ячейки и заменяя ссылки на картинки самими изображениями. Проанализируем ситуацию, когда при таком подходе в отчет выводятся только пустые картинки, выясним причину такого поведения и разберем по шагам рабочие варианты решения.

Анализ исходной проблемы и поиск ошибок

Рассмотрим типичный фрагмент кода, который часто пишут для вывода картинок через расшифровку СКД:


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

На первый взгляд логика верна, но в результате картинки получаются пустыми. Разберем подробнее, почему это происходит:

  1. Несоответствие типов данных и использование БСП. В современных конфигурациях (ERP, УТ 11, КА) картинки редко хранятся напрямую в реквизите типа ХранилищеЗначения самого справочника. Обычно они лежат в присоединенных файлах. Из-за этого переменная ФайлКартинки содержит ссылку на справочник, а не хранилище. Проверка ТипЗнч(ФайлКартинки) = Тип("ХранилищеЗначения") дает ложь.
  2. Неправильная инициализация объекта. Метод Получить() у хранилища может вернуть ДвоичныеДанные, а может — готовый объект Картинка. Если там уже объект картинки, конструкция Новый Картинка() отработает некорректно.
  3. Перекрытие текстом и размеры ячеек. Даже если картинка успешно добавлена в область, в самой ячейке остается текст (например, строковое представление ссылки). Этот текст может перекрывать картинку. Кроме того, высота строки по умолчанию вычисляется автоматически по тексту, и картинка сжимается до невидимых размеров.

Исправленный программный вариант обхода ячеек

Посмотрим на пример правильной реализации программного вывода, если вы используете конфигурацию на базе БСП (Библиотека стандартных подсистем). Вместо прямого обращения к хранилищу, используем программный интерфейс работы с файлами:


// Предполагается, что в поле расшифровки находится ссылка на присоединенный файл
ДвоичныеДанныеФайла = ПрисоединенныеФайлы.ПолучитьДвоичныеДанныеФайла(ФайлКартинкиСсылка);

Если ДвоичныеДанныеФайла <> Неопределено Тогда
    КартинкаВДокументе = ДокументРезультат.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
    КартинкаВДокументе.Картинка = Новый Картинка(ДвоичныеДанныеФайла);
    КартинкаВДокументе.РазмерКартинки = РазмерКартинки.Пропорционально;
    
    // Обязательно очищаем ячейку от служебного текста
    ТекущаяОбласть.Текст = "";
    
    // Отключаем автовысоту и задаем фиксированный размер для видимости картинки
    ТекущаяОбласть.АвтоВысотаСтроки = Ложь;
    ТекущаяОбласть.ВысотаСтроки = 50; 
    
    КартинкаВДокументе.Расположить(ТекущаяОбласть);
КонецЕсли;

Альтернативный метод: использование навигационной ссылки

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


// Пример получения ссылки для реквизита формы
ЭтаФорма.Фото = ПолучитьНавигационнуюСсылку(ЭтаФорма.Элементы.Товары.ТекущиеДанные.Номенклатура.ОсновноеИзображение, "Хранилище");

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

Современный метод вывода картинок в СКД (без программирования)

Начиная с версии платформы 1С 8.3.14, разработчики добавили штатный механизм вывода изображений прямо через настройки схемы компоновки данных. Вам больше не нужно писать код в ПриКомпоновкеРезультата. Разберем по шагам, как это настроить:

  1. Подготовка запроса СКД. Убедитесь, что в запросе выбирается поле, содержащее двоичные данные картинки (из ХранилищеЗначения) или навигационную ссылку на изображение.
  2. Добавление поля в настройки. На вкладке «Настройки» СКД добавьте это поле в «Выбранные поля».
  3. Настройка условного оформления. Перейдите в раздел «Условное оформление» и добавьте новый элемент.
  4. Параметры оформления. В свойствах оформления найдите параметр Картинка (или аналогичное свойство вывода изображения). Выберите поле из вашего набора данных. Платформа сама распознает тип данных (двоичные данные или ссылку) и отрисует картинку.
  5. Форматирование ячейки. Чтобы изображения не слипались и имели красивый вид, в том же условном оформлении (или в свойствах колонки) задайте фиксированную высоту и ширину (параметры МаксимальнаяВысота, МинимальнаяШирина и т.д.).

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

← На главную