Как программно загрузить картинки в 1С:УНФ и установить их основными

Программист 1С v8.3 (Управляемые формы) 1С:Управление нашей фирмой Управленческий учет Торговля и дистрибуция
← На главную

В современных конфигурациях на базе 1С:Предприятие 8.3, таких как "Управление нашей фирмой" (УНФ), работа с файлами и изображениями тесно интегрирована с Библиотекой стандартных подсистем (БСП). Часто перед разработчиком встает задача массово загрузить фотографии товаров из внешних папок или по прямым ссылкам. Разберем по шагам, как это реализовать правильно, учитывая особенности хранения данных и механизмы назначения "главного" фото.

Понимание архитектуры хранения изображений

Прежде всего, проанализируем, как 1С:УНФ хранит картинки. В отличие от старых версий платформ, где изображение могло храниться непосредственно в реквизите справочника Номенклатура, в актуальных релизах используется подсистема "Присоединенные файлы".

Для каждого товара создается запись в подчиненном справочнике (обычно это НоменклатураПрисоединенныеФайлы). Сами двоичные данные могут лежать либо в информационной базе, либо в томах на диске, в зависимости от настроек программы. Однако, чтобы картинка отображалась в карточке товара как основная, ссылка на этот присоединенный файл должна быть записана в специальный реквизит ФайлКартинки основной карточки номенклатуры.

Способ 1: Прямое создание элемента присоединенного файла

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


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

    ИмяБезРасширения = ФайлНаДиске.ИмяБезРасширения;
    Расширение = СтрЗаменить(ФайлНаДиске.Расширение, ".", "");
    РазмерФайла = ФайлНаДиске.Размер();
    
    // Читаем данные файла в объект ДвоичныеДанные
    ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлу);
    
    // Создаем новый элемент в справочнике присоединенных файлов
    НоваяКартинка = Справочники.НоменклатураПрисоединенныеФайлы.СоздатьЭлемент();
    НоваяКартинка.Наименование = ИмяБезРасширения; 
    НоваяКартинка.ВладелецФайла = ТоварСсылка;       
    НоваяКартинка.ТипХраненияФайла = Перечисления.ТипыХраненияФайлов.ВИнформационнойБазе;
    НоваяКартинка.ДатаСоздания = ТекущаяДата();
    НоваяКартинка.ДатаМодификацииУниверсальная = ТекущаяДата();
    НоваяКартинка.СтатусИзвлеченияТекста = Перечисления.СтатусыИзвлеченияТекстаФайлов.НеИзвлечен; 
    
    // Помещаем данные в хранилище со сжатием
    НоваяКартинка.ФайлХранилище = Новый ХранилищеЗначения(ДвоичныеДанные, Новый СжатиеДанных());
    НоваяКартинка.Расширение = Расширение;
    НоваяКартинка.Размер = РазмерФайла; 
    
    Попытка
        НоваяКартинка.Записать();
        
        // Для корректной работы БСП вызываем служебный метод записи в базу
        РаботаСФайламиСлужебный.ЗаписатьФайлВИнформационнуюБазу(НоваяКартинка.Ссылка, ДвоичныеДанные);
    Исключение
        ОбщегоНазначения.СообщитьПользователю("Ошибка при записи файла: " + ОписаниеОшибки());
    КонецПопытки;

КонецПроцедуры

В этом примере мы используем объект ХранилищеЗначения. Обратите внимание на вызов РаботаСФайламиСлужебный.ЗаписатьФайлВИнформационнуюБазу. Несмотря на то что мы уже записали объект, этот метод гарантирует, что данные будут корректно обработаны подсистемой хранения файлов БСП.

Способ 2: Использование стандартных методов БСП

Если мы хотим следовать стандартам разработки 1С, лучше использовать методы общего модуля ПрисоединенныеФайлы. Проанализируем, как это выглядит в современных версиях БСП. Основное отличие здесь в том, что сначала файл нужно поместить во временное хранилище.


// Пример на клиенте
АдресФайлаВоХранилище = ПоместитьВоВременноеХранилище(ДвоичныеДанныеКартинки);

// Пример на сервере
ПараметрыФайла = ПрисоединенныеФайлы.ПараметрыДобавленияФайла();
ПараметрыФайла.Автор = Пользователи.ТекущийПользователь();
ПараметрыФайла.Наименование = "Фото товара";

НовыйФайлСсылка = ПрисоединенныеФайлы.ДобавитьФайл(
    ТоварСсылка, 
    "ИмяФайла.jpg", 
    "jpg", 
    ТекущаяДата(), 
    ТекущаяДата(), 
    АдресФайлаВоХранилище, 
    , 
    "Загружено автоматически", 
    ПараметрыФайла
);

Этот метод более универсален, так как он автоматически учитывает настройки хранения (база или тома на диске), проверяет права доступа и корректно заполняет все служебные реквизиты.

Установка загруженной картинки как основной

Выясним важный момент: после того как файл загружен, он просто появляется в списке "Файлы" или "Изображения" карточки номенклатуры. Но само изображение в карточке товара останется пустым. Чтобы это исправить, нам нужно обновить реквизит ФайлКартинки у самого объекта Номенклатура.

Рассмотрим алгоритм массовой привязки уже загруженных файлов:


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

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

Особенности работы в облаке (1С:Fresh)

При работе в облачных сервисах использование объекта Файл с прямым указанием пути (например, C:\Images\1.jpg) на сервере запрещено из соображений безопасности. В этом случае алгоритм действий меняется:

  1. Пользователь на клиенте выбирает файлы через диалог выбора файлов.
  2. Файлы передаются на сервер через ПоместитьФайлыНаСервер.
  3. Сервер получает массив структур с двоичными данными и адресами во временном хранилище.
  4. Далее используется метод ПрисоединенныеФайлы.ДобавитьФайл, как описано выше.

Оптимизация при больших объемах данных

Если вам нужно загрузить десятки тысяч изображений, проанализируем следующие рекомендации:

1. Контроль дублей. БСП умеет вычислять хеш-сумму файла. Перед добавлением проверьте, нет ли уже файла с таким же хешем, чтобы не раздувать размер базы данных одинаковыми изображениями.

2. Использование транзакций. Записывайте изменения порциями (например, по 100-500 элементов), чтобы минимизировать нагрузку на транзакционный лог SQL-сервера.

3. Хранение в томах. Настоятельно рекомендуем настроить хранение файлов в томах на диске до начала массовой загрузки. Это позволит сохранить размер файла базы данных (.1CD или .mdf) компактным и ускорит процесс резервного копирования.

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

← На главную