При автоматизации загрузки прайс-листов, интеграции с интернет-магазинами или обработке каталогов товаров часто возникает задача программной привязки графических файлов к позициям справочника Номенклатура. Рассмотрим, как устроен этот механизм в типовых конфигурациях (на примере 1С:Управление торговлей 10.3) и напишем рабочий код для сохранения изображений.
В отличие от простейших структур, где графический файл помещается напрямую в реквизит справочника, в типовых решениях применяется более гибкая схема. Проанализируем устройство хранения изображений:
СправочникСсылка.Номенклатура.ХранилищеДополнительнойИнформации. В нем создается отдельный элемент, где бинарные данные картинки помещаются в объект ХранилищеЗначения.ОсновноеИзображение сохраняется ссылка на созданную запись из справочника ХранилищеДополнительнойИнформации.Разберем последовательность действий, которую необходимо выполнить для правильного сохранения и вывода изображения на форму номенклатуры:
Картинка, передавая в конструктор путь к файлу на диске.ХранилищеЗначения на основании полученной картинки с использованием сжатия данных.ХранилищеДополнительнойИнформации, заполняем реквизиты ВидДанных, Объект (ссылка на номенклатуру), ИмяФайла и Хранилище. Записываем объект.ОсновноеИзображение.Рассмотрим практический пример кода для программной привязки файла изображения к существующей позиции номенклатуры:
// 1. Загружаем файл с диска и помещаем его в хранилище значения
ПутьКФайлу = "C:\Images\item123.jpg";
КартинкаФайла = Новый Картинка(ПутьКФайлу);
ХранилищеФайла = Новый ХранилищеЗначения(КартинкаФайла, Новый СжатиеДанных);
// 2. Создаем элемент в справочнике ХранилищеДополнительнойИнформации
НовоеХранилище = Справочники.ХранилищеДополнительнойИнформации.СоздатьЭлемент();
НовоеХранилище.ВидДанных = Перечисления.ВидыДополнительнойИнформацииОбъектов.Изображение;
НовоеХранилище.Объект = СсылкаНаНоменклатуру;
НовоеХранилище.Наименование = "Основное изображение";
НовоеХранилище.ИмяФайла = "item123.jpg";
НовоеХранилище.Хранилище = ХранилищеФайла;
НовоеХранилище.Записать();
// 3. Устанавливаем основное изображение для номенклатуры
ОбъектНоменклатура = СсылкаНаНоменклатуру.ПолучитьОбъект();
ОбъектНоменклатура.ОсновноеИзображение = НовоеХранилище.Ссылка;
ОбъектНоменклатура.Записать();
Разберем подробно ключевые моменты этого кода:
При вызове Новый ХранилищеЗначения(КартинкаФайла, Новый СжатиеДанных) платформа сжимает бинарные данные картинки, что позволяет экономить место в базе данных.
Реквизит Объект справочника ХранилищеДополнительнойИнформации связывает запись с конкретным элементом номенклатуры. Это позволяет хранить для одного товара несколько картинок (галерею), выделяя одну из них в качестве основной через реквизит ОсновноеИзображение.
При открытии карточки номенклатуры система автоматически считывает реквизит ОсновноеИзображение, получает из него объект хранилища и извлекает бинарные данные. Чтобы отобразить полученную картинку на форме программно, используется следующий метод:
DdvImage = ЭлементХранилища.Хранилище.Получить();
ЭлементыФормы.ПолеКартинки.Картинка = DdvImage;
Выясним важные особенности, о которых стоит помнить при массовой загрузке картинок:
НачатьТранзакцию() и ЗафиксироватьТранзакцию(). Это защитит базу данных от появившихся «сиротских» записей в хранилище, если при записи самой номенклатуры произойдет ошибка.ХранилищеЗначения быстро приведет к раздуванию файла базы данных. Перед заполнением хранилища рекомендуется предварительно сжимать и оптимизировать файлы до стандартного разрешения (например, 1024x768).Новый Картинка("C:\path...") обращается к файловой системе локального компьютера. Если код выполняется в серверном контексте или в фоновом задании, пути к файлам должны быть доступны серверу 1С, либо файлы предварительно должны помещаться во временное хранилище.