При разработке прайс-листов, каталогов товаров или специализированных складских отчетов часто возникает задача визуализировать данные — вывести рядом с наименованием номенклатуры её фото. Однако начинающие разработчики нередко сталкиваются с ситуацией, когда вместо фотографии в печатную форму выводятся шестнадцатеричные строки двоичных данных или текстовое слово Картинка. Разберем по шагам, почему это происходит и как правильно извлечь изображение из базы данных и отобразить его в табличном документе.
Посмотрим на типовую ситуацию: в справочнике Номенклатура есть реквизит Картинка, который ссылается на дополнительный справочник файлов, либо в самом справочнике хранится реквизит с типом ХранилищеЗначений. Когда данные о файле сохранены в хранилище, мы имеем дело с двоичными данными.
Разберем основные ошибки при попытке вывести такое изображение:
ХранилищеЗначений нельзя выбирать в тексте запроса 1С. Получение данных происходит через программный вызов метода Получить() у соответствующего реквизита объекта.Получить() напрямую в обычный параметр макета (Строка.Параметры.Картинка = ДвоичныеДанные), платформа 1С преобразует двоичные данные в текстовое представление (hex-последовательность вида 89 50 4E 47...).Новый Картинка(ДвоичныеДанные) и присвоить его параметру ячейки с типом заполнения Параметр, табличный документ преобразует объект в строковое представление и напечатает слово Картинка.Выясним, как настроить макет и написать программный код для отображения фотографии непосредственно внутри ячейки таблицы.
Шаг 1. Настройка макета табличного документа:
КартинкаТовара.Текст, если текстовое содержимое не выводится).Шаг 2. Программный код вывода:
Рассмотрим серверную процедуру формирования отчета. Для корректного создания изображения нам необходимо получить двоичные данные из хранилища, обернуть их в объект Картинка через конструктор и присвоить свойству строки макета с проверкой на заполненность:
&НаСервереБезКонтекста
Процедура СформироватьОтчет(ТабДок, ДатаОтчета)
Макет = Отчеты.ОстаткиТоваров.ПолучитьМакет("Макет");
Шапка = Макет.ПолучитьОбласть("Шапка");
Строка = Макет.ПолучитьОбласть("Строка");
ТабДок.Очистить();
Шапка.Параметры.ДатаОтчета = ДатаОтчета;
ТабДок.Вывести(Шапка);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Остатки.Номенклатура КАК Номенклатура,
| Остатки.КоличествоОстаток КАК КоличествоОстаток
|ИЗ
| РегистрНакопления.ОстаткиТовара.Остатки(&ДатаОтчета, ) КАК Остатки";
Запрос.УстановитьПараметр("ДатаОтчета", ДатаОтчета);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Пока Выборка.Следующий() Цикл
Строка.Параметры.Номенклатура = Выборка.Номенклатура;
Строка.Параметры.Количество = Выборка.КоличествоОстаток;
// Получаем двоичные данные из хранилища значений
// В зависимости от структуры конфигурации обращение может быть:
// Выборка.Номенклатура.Картинка.Получить() или через реквизит связанного справочника:
ДвоичныеДанные = Выборка.Номенклатура.Картинка.Файл.Получить();
Если ДвоичныеДанные <> Неопределено Тогда
Строка.Параметры.КартинкаТовара = Новый Картинка(ДвоичныеДанные);
Иначе
Строка.Параметры.КартинкаТовара = Новый Картинка;
КонецЕсли;
ТабДок.Вывести(Строка);
КонецЦикла;
КонецПроцедуры
Проанализируем альтернативный вариант. Свойство ПараметрКартинки выводит изображение строго в фон ячейки. Если требуется управлять пропорциями, масштабированием и точным положением изображения, удобнее использовать коллекцию Рисунки табличного документа.
Вариант с предопределенным рисунком на макете:
ФотоТовара.Пропорционально (чтобы изображение вписывалось в границы без искажения пропорций).
Пока Выборка.Следующий() Цикл
Строка.Параметры.Номенклатура = Выборка.Номенклатура;
Строка.Параметры.Количество = Выборка.КоличествоОстаток;
ДвоичныеДанные = Выборка.Номенклатура.Картинка.Файл.Получить();
Если ДвоичныеДанные <> Неопределено Тогда
Строка.Рисунки.ФотоТовара.Картинка = Новый Картинка(ДвоичныеДанные);
Иначе
Строка.Рисунки.ФотоТовара.Картинка = Новый Картинка;
КонецЕсли;
ТабДок.Вывести(Строка);
КонецЦикла;
При выводе изображений в прайс-листы и печатные формы важно учитывать следующие технические ограничения платформы 1С:
Получить() возвращает Неопределено. Передача Неопределено в конструктор Новый Картинка() приведет к ошибке во время выполнения. Всегда проверяйте результат на заполненность.Выборка.Номенклатура.Картинка.Файл) внутри цикла вызывает дополнительные неявные запросы к СУБД. При формировании больших прайс-листов оптимально предварительно выгружать ссылки на файлы в массив и считывать их пакетом.