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

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

Вывод изображений в печатные формы — это классическая задача, которая часто сопровождается трудностями. Основная проблема заключается в том, что изображения в базе данных 1С хранятся в специальном формате ХранилищеЗначения, а для отображения в табличном документе требуется объект типа Картинка. Если попытаться напрямую присвоить данные из хранилища объекту рисунка, система выдаст ошибку "Несоответствие типов".

В этой статье мы подробно рассмотрим, как правильно извлечь данные, преобразовать их и вывести в макет, избежав типичных ошибок начинающих разработчиков.

Разберем причину ошибки «Несоответствие типов»

Проанализируем ситуацию: когда мы обращаемся к реквизиту объекта, имеющему тип ХранилищеЗначения, мы получаем объект-контейнер. Чтобы достать из него содержимое, необходимо использовать метод Получить(). Однако даже после этого мы можем получить не саму картинку, а ДвоичныеДанные.

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

Шаг 1: Правильное извлечение данных из Хранилища

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


// Предположим, Выборка.ТипПродукцииКартинкаФайл — это реквизит типа ХранилищеЗначения
ДанныеИзХранилища = Выборка.ТипПродукцииКартинкаФайл.Получить();

Если ТипЗнч(ДанныеИзХранилища) = Тип("Картинка") Тогда
    // Если в хранилище уже была упакована Картинка
    лкКартинка = ДанныеИзХранилища;
ИначеЕсли ТипЗнч(ДанныеИзХранилища) = Тип("ДвоичныеДанные") Тогда
    // Если в хранилище лежат двоичные данные (байты файла), создаем объект Картинка
    лкКартинка = Новый Картинка(ДанныеИзХранилища);
Иначе
    // Если данных нет или тип неизвестен
    лкКартинка = Неопределено;
КонецЕсли;

Обратите внимание на параметр Ложь или Истина в конструкторе Новый Картинка(Данные, ПроверятьФормат). Обычно достаточно передать только данные, чтобы система автоматически определила формат (JPG, PNG, BMP).

Шаг 2: Подготовка макета и поиск рисунка

Для вывода изображения в табличный документ в макете заранее должен быть создан объект Рисунок (Меню: Таблица -> Рисунки -> Вставить картинку). Этому рисунку необходимо назначить имя, например, КартинкаТовара. Это позволит нам обращаться к нему программно.

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


ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет("Макет");
ОбластьДанные = Макет.ПолучитьОбласть("Данные");

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

    // Выводим готовую область в итоговый документ
    ТабДок.Вывести(ОбластьДанные);
КонецЦикла;

Оптимизация: Работа с Библиотекой Стандартных Подсистем (БСП)

Если ваша конфигурация построена на базе БСП (например, УТ 11, ERP 2, БП 3), то картинки чаще всего хранятся не просто в реквизите, а через подсистему «Присоединенные файлы». В этом случае прямой доступ к хранилищу через точку от ссылки может быть неэффективным или вовсе невозможным, если файлы хранятся в томах на диске.

Посмотрим, как рекомендуется решать задачу в современных системах:

  1. Используйте функцию РаботаСФайлами.ДвоичныеДанныеФайла(СсылкаНаФайл). Она сама определит, где лежит файл (в базе или на диске), и вернет ДвоичныеДанные.
  2. Проверьте, не является ли файл помеченным на удаление перед обработкой.
  3. Не выбирайте поле ХранилищеЗначения непосредственно в запросе ВЫБРАТЬ.... Это создает огромную нагрузку на SQL-сервер и оперативную память. Проанализируем правильный подход: в запросе мы получаем только Ссылку на объект или файл, а само Хранилище извлекаем в цикле обхода выборки через метод Получить() или средства БСП.

Тонкости форматирования и прозрачности

При работе с изображениями формата PNG с прозрачным фоном, вы можете столкнуться с тем, что в печатной форме фон становится белым или черным. Чтобы этого избежать, убедитесь, что в свойствах рисунка в макете:

Также полезно использовать свойство РазмерКартинки.Пропорционально. Это гарантирует, что фотография товара не будет "растянута" по вертикали или горизонтали, если пропорции загруженного файла не совпадают с пропорциями рамки в макете.

Итоговый алгоритм действий

Подведем итог нашей совместной работы по настройке вывода изображений:

  1. Убеждаемся, что в макете есть объект Рисунок с уникальным именем.
  2. В коде на сервере получаем данные из ХранилищаЗначения.
  3. Обязательно проверяем тип полученных данных: если это ДвоичныеДанные, преобразуем их в Картинка через Новый Картинка(...).
  4. Присваиваем полученную картинку свойству Рисунки.ИмяРисунка.Картинка текущей области.
  5. Выводим область в табличный документ.

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

← На главную