При разработке печатных форм в среде 1С:Предприятие 8 часто возникает бизнес-требование: дополнить выводимые строки документов (например, заказов клиентов, заказов поставщикам или прайс-листов) визуальными изображениями товаров. Это делает печатную форму более информативной и презентабельной для клиентов и контрагентов.
Однако начинающие разработчики часто сталкиваются с трудностями при попытке вывести картинки напрямую из базы данных. В современных конфигурациях, разработанных на базе Библиотеки Стандартных Подсистем (БСП), таких как 1С:Управление торговлей (УТ 11), 1С:ERP или 1С:Комплексная автоматизация, хранение файлов реализовано через подчиненные справочники присоединенных файлов. Прямая передача ссылки на файл в макет не дает результата и приводит к ошибкам. В этой статье мы подробно разберем, как устроен механизм хранения картинок номенклатуры, как правильно извлечь эти данные и вывести их в табличный документ без ошибок.
Давайте разберем типичную ситуацию. В запросе для печатной формы разработчик получает реквизит номенклатуры ФайлКартинки:
| ЗаказПоставщикуТовары.Номенклатура.ФайлКартинки КАК ФайлКартинки,
При попытке вывести это значение в макет через параметр области строки или при создании картинки кодом:
Рисунок.Картинка = Новый Картинка(Выборка.ФайлКартинки);
Платформа генерирует ошибку выполнения: "Ошибка при вызове конструктора (Картинка): Несоответствие типов (параметр номер '1')". Выясним причину этого поведения.
Дело в том, что реквизит ФайлКартинки содержит не само изображение, а ссылку на элемент подчиненного справочника (например, НоменклатураПрисоединенныеФайлы). Сам же файл картинки физически может храниться либо в информационной базе в виде двоичных данных (в реквизите ХранилищеЗначения), либо во внешнем томе на диске (в сетевом каталоге).
Чтобы вывести изображение на печать, нам необходимо выполнить следующие шаги:
Картинка.---
Этот способ является самым лаконичным и удобным для реализации в простых печатных формах, когда структура табличного документа фиксирована.
Шаг 1. Настройка макета
В макете печатной формы выделите ячейку, в которой должна отображаться фотография товара. В свойствах этой ячейки установите значение свойства Заполнение в положение Параметр. Задайте имя параметра, например, ФотоТовара. Очень важно в свойствах этой же ячейки указать тип значения — Картинка (или в свойстве Картинка выбрать соответствующий режим отображения, чтобы платформа понимала, что в параметр будет передаваться графический объект).
Шаг 2. Написание программного кода вывода
Рассмотрим по шагам программный код, который извлекает данные с помощью стандартных механизмов БСП и передает изображение в параметр макета.
Пока Выборка.Следующий() Цикл
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, Выборка);
// Проверяем, заполнена ли ссылка на файл картинки у номенклатуры
Если ЗначениеЗаполнено(Выборка.ФайлКартинки) Тогда
Попытка
// Используем стандартный метод БСП для получения структуры с данными файла
ДанныеФайла = ПрисоединенныеФайлы.ПолучитьДанныеФайла(Выборка.ФайлКартинки);
// Получаем адрес во временном хранилище, где лежат двоичные данные файла
АдресХранилища = ДанныеФайла.СсылкаНаДвоичныеДанныеФайла;
Если ЗначениеЗаполнено(АдресХранилища) Тогда
// Получаем двоичные данные и создаем объект Картинка
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресХранилища);
ОбластьСтрока.Параметры.ФотоТовара = Новый Картинка(ДвоичныеДанные);
КонецЕсли;
Исключение
// Обработка непредвиденных ошибок при получении файла (например, отсутствие доступа к диску)
ЗаписьЖурналаРегистрации("ПечатьКартинки",
УровеньЖурналаРегистрации.Ошибка, , ,
ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
КонецЕсли;
ТабличныйДокумент.Вывести(ОбластьСтрока);
КонецЦикла;
---
Если вам требуется более гибкий контроль над размером, границами или расположением картинки, либо если вы хотите выводить изображение со свободным позиционированием, то лучше использовать программное добавление рисунка в коллекцию рисунков табличного документа.
Проанализируем пример кода, реализующий этот подход:
Пока Выборка.Следующий() Цикл
ОбластьСтрока = Макет.ПолучитьОбласть("Строка");
ЗаполнитьЗначенияСвойств(ОбластьСтрока.Параметры, Выборка);
Если ЗначениеЗаполнено(Выборка.ФайлКартинки) Тогда
Попытка
ДанныеФайла = ПрисоединенныеФайлы.ПолучитьДанныеФайла(Выборка.ФайлКартинки);
АдресХранилища = ДанныеФайла.СсылкаНаДвоичныеДанныеФайла;
Если ЗначениеЗаполнено(АдресХранилища) Тогда
ДвоичныеДанные = ПолучитьИзВременногоХранилища(АдресХранилища);
ОбъектКартинка = Новый Картинка(ДвоичныеДанные);
// Добавляем новый рисунок в область строки табличного документа
НовыйРисунок = ОбластьСтрока.Рисунки.Добавить(ТипРисункаТабличногоДокумента.Картинка);
// Устанавливаем координаты и размеры рисунка (в миллиметрах)
НовыйРисунок.Верх = 2; // Отступ сверху
НовыйРисунок.Лево = 2; // Отступ слева
НовыйРисунок.Высота = 15; // Высота картинки
НовыйРисунок.Ширина = 15; // Ширина картинки
// Передаем картинку в созданный объект рисунка
НовыйРисунок.Картинка = ОбъектКартинка;
// Настраиваем режим масштабирования
НовыйРисунок.РазмерКартинки = РазмерКартинки.Пропорционально;
// Убираем рамку вокруг картинки, чтобы вывод выглядел аккуратно
НовыйРисунок.Линия = Новый Линия(ТипЛинииРисункаТабличногоДокумента.НетЛинии);
КонецЕсли;
Исключение
// Обрабатываем исключение, печать документа при этом продолжится
ОбластьСтрока.Параметры.ФотоТовара = "Ошибка загрузки фото";
КонецПопытки;
КонецЕсли;
ТабличныйДокумент.Вывести(ОбластьСтрока);
КонецЦикла;
---
В реальных рабочих базах картинки часто хранятся не в самой СУБД, а в томах на диске для разгрузки объема базы данных. При написании кода важно учитывать следующие особенности:
Если ТипХраненияФайла = Перечисления.ТипыХраненияФайлов.ВИнформационнойБазе Тогда. Если администратор системы решит перенести файлы на дисковые тома, ваш код перестанет выводить изображения.ПрисоединенныеФайлы.ПолучитьДанныеФайла() является универсальным. Он инкапсулирует в себе всю логику получения файлов. Система сама определяет, где физически лежит файл (в базе или в томе на диске), считывает его и возвращает валидный адрес временного хранилища.---
Вывод картинок в многостраничные отчеты и печатные формы может значительно снизить скорость формирования документов и привести к высокому расходу оперативной памяти сервера. Разберем основные рекомендации по оптимизации:
1. Контроль размера исходных файлов
Часто пользователи загружают фотографии товаров в исходном высоком разрешении (например, снимки с камер смартфонов объемом 5–10 Мб каждый). При выводе на печать система тратит ресурсы на распаковку и сжатие этих тяжелых файлов в памяти. Рекомендуется настроить в конфигурации ограничение на максимальный размер загружаемого изображения или использовать автоматическое уменьшение разрешения при загрузке картинок в карточку номенклатуры.
2. Использование миниатюр
Если ваша конфигурация поддерживает создание миниатюр (уменьшенных копий изображений для предварительного просмотра), то в печатные формы табличной части товаров следует выводить именно их. Это позволит сократить объем обрабатываемых данных в десятки раз.
3. Проверка на заполненность картинки
Обязательно используйте конструкцию Если ЗначениеЗаполнено(Выборка.ФайлКартинки) Тогда. Попытка вызова методов получения данных для незаполненных ссылок приводит к лишним обращениям к базе данных и существенно замедляет цикл вывода строк.
Применяя данные подходы, вы сможете создавать быстрые, надежные и визуально привлекательные печатные формы документов в 1С любой сложности.