Как вывести картинку из хранилища значений в табличный документ 1С?

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

При разработке прайс-листов, каталогов товаров или других печатных форм часто возникает необходимость вывести изображения номенклатуры. В 1С картинки обычно хранятся в реквизитах с типом ХранилищеЗначений. Если попытаться вывести такие данные напрямую в ячейку табличного документа, платформа выдаст ошибку или выведет пустую область. Давайте подробно разберем по шагам, как правильно подготовить макет, извлечь картинку из базы данных и вывести ее на печать без потери производительности. При необходимости можно воспользоваться готовым решением для формирования прайс-листа с картинками в УНФ и Рознице.

Шаг 1. Подготовка макета: правильное добавление рисунка

Сначала проанализируем частую ошибку: разработчики пытаются присвоить картинку ячейке макета, задавая ей тип параметра. На самом деле, картинка в табличном документе 1С не может быть вставлена напрямую в ячейку как обычный текст.

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

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

Шаг 2. Настройка масштабирования и размеров

Посмотрим на частую проблему: если фотографии в базе имеют разный размер и разрешение (что бывает почти всегда), при выводе в прайс-лист они могут перекрывать соседние ячейки или растягивать строки, ломая всю верстку документа.

Чтобы этого избежать, выполним настройку свойств нашего объекта в макете:

  1. В свойствах добавленного рисунка найдите параметр Размер картинки.
  2. Установите его в значение Пропорционально (или РеальныйРазмер с ограничением области, но Пропорционально предпочтительнее для прайс-листов).
  3. Обязательно снимите галочку Авторазмер, чтобы изображение вписывалось строго в нарисованные нами границы рисунка, а не расширяло их под свои исходные габариты.

Шаг 3. Извлечение картинки и программный вывод

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

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

Посмотрим на правильный пример кода заполнения области с картинкой:


// Получаем секцию макета
ОбластьДанные = Макет.ПолучитьОбласть("Данные");

// ... (выполнение запроса и начало цикла обхода выборки) ...

Пока Выборка.Следующий() Цикл
    // Заполняем обычные текстовые параметры
    ОбластьДанные.Параметры.Заполнить(Выборка);
    
    // Получаем данные из хранилища
    ИзвлеченнаяКартинка = Выборка.Картинка.Получить();

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

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

Шаг 4. Оптимизация производительности (Критически важно!)

Выясним причину, по которой сервер 1С может "зависнуть" при формировании большого прайс-листа. В первом сообщении темы автор получает поле с типом ХранилищеЗначений прямо в основном тексте запроса: Номенклатура.ТипПродукции.Картинка.Файл КАК Картинка.

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

Как делать правильно:

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

Рассмотрим исправленный подход к запросу и выборке:


// В запросе получаем только ссылку на присоединенный файл!
Запрос.Текст = 
"ВЫБРАТЬ
|   Номенклатура.Наименование КАК Наименование,
|   Номенклатура.ТипПродукции.Картинка КАК СсылкаНаФайлКартинки
|ИЗ
|   Справочник.Номенклатура КАК Номенклатура
|ГДЕ
|   Номенклатура.Фирма = &Фирма";

Выборка = Запрос.Выполнить().Выбрать();

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

    ТабДок.Вывести(ОбластьДанные);
КонецЦикла;

При таком алгоритме тяжелые бинарные данные будут считываться из базы данных порциями (по одному файлу за итерацию) и сразу же передаваться в табличный документ, не перегружая кэш и оперативную память сервера 1С. Это обеспечит стабильную работу обработки даже на огромных объемах номенклатуры. Для этой задачи также можно использовать внешнюю обработку для формирования прайс-листа с картинками в УТ 11.

← На главную