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

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

В процессе реорганизации каталога товаров в 1С:Управление нашей фирмой (УНФ) часто возникает задача консолидации данных. Типичный сценарий: ранее разные варианты одного товара велись как отдельные карточки номенклатуры, а теперь их необходимо объединить в одну карточку с использованием характеристик. Подобные задачи часто встречаются, когда выполняется перенос данных из ТиС 7.7 в УНФ 3.0 или другие варианты миграции. Одной из самых трудоемких подзадач в этом процессе является перенос изображений. В этой статье мы подробно разберем, как программно перенести картинку из объекта Номенклатура в объект ХарактеристикиНоменклатуры.

Почему простая замена ссылок не работает?

Проанализируем структуру хранения файлов в современных конфигурациях на базе БСП. Картинки не хранятся напрямую в реквизитах справочника. Вместо этого используются подчиненные справочники присоединенных файлов. Для номенклатуры это НоменклатураПрисоединенныеФайлы, а для характеристик — ХарактеристикиНоменклатурыПрисоединенныеФайлы. Сложности с типами данных часто возникают, когда требуется кастомная выгрузка номенклатуры с картинками из старой УНФ 1.6 в новые редакции программ.

Разберем основные причины, по которым нельзя просто скопировать ссылку:

  1. Разная типизация владельца: Реквизит ВладелецФайла в каждом из этих справочников имеет жестко заданный тип. В справочнике файлов номенклатуры это ссылка на Справочник.Номенклатура, а в справочнике файлов характеристик — Справочник.ХарактеристикиНоменклатуры.
  2. Изоляция данных: Метаданные 1С не позволяют назначить элементу одного справочника владельца из другого типа. Это ограничение важно учитывать, если вами настроена синхронизация номенклатуры по протоколу HTTP между различными узлами или базами.
  3. Хранение данных: Сами двоичные данные (бинарный код картинки) могут храниться либо в регистре сведений ХранилищеФайлов, либо на внешних томах (на диске).

Рассмотрим два способа решения задачи: «быстрый хак» через прямой запрос к регистру и «правильный метод» с использованием механизмов БСП.

Метод 1: Прямое копирование через регистр сведений (быстрый способ)

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

Проанализируем пример кода для реализации этой задачи:


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

// Ссылка на картинку исходной номенклатуры
Запрос.УстановитьПараметр("ВыбФайл", НоменклатураИсточник.ФайлКартинки);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

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

Важный нюанс: В коде выше мы используем ЗаполнитьЗначенияСвойств, исключая Родитель и Владелец. Это необходимо, так как мы создаем объект в другом справочнике, и эти поля должны быть инициализированы заново.

Метод 2: Использование функций БСП (рекомендуемый способ)

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

Рассмотрим пошаговый алгоритм работы через БСП:

  1. Извлекаем двоичные данные из исходного файла номенклатуры.
  2. Подготавливаем структуру параметров для добавления нового файла.
  3. Вызываем стандартную процедуру добавления файла для нового владельца (характеристики).

Посмотрим на пример реализации:


// Получаем двоичные данные файла номенклатуры
// Метод РаботаСФайлами.ДвоичныеДанныеФайла корректно получит данные и из базы, и с диска
ДвоичныеДанные = РаботаСФайлами.ДвоичныеДанныеФайла(НоменклатураИсточник.ФайлКартинки);

Если ДвоичныеДанные <> Неопределено Тогда
    
    // Подготавливаем параметры для создания нового файла характеристик
    ПараметрыФайла = Новый Структура;
    ПараметрыФайла.Вставить("Автор", Пользователи.ТекущийПользователь());
    ПараметрыФайла.Вставить("ИмяБезРасширения", "Картинка_Характеристики");
    ПараметрыФайла.Вставить("Расширение", "jpg"); // Желательно получить из исходного файла
    
    // Добавляем файл в систему
    // Функция сама создаст запись в нужном справочнике присоединенных файлов
    НовыйФайлСсылка = РаботаСФайлами.ДобавитьФайл(
        СсылкаНаХарактеристику, 
        "Картинка_Характеристики.jpg", 
        ДвоичныеДанные, 
        "Перенос из номенклатуры", 
        ПараметрыФайла
    );
    
    // Устанавливаем привязку в объекте Характеристика
    Если ЗначениеЗаполнено(НовыйФайлСсылка) Тогда
        ОбъектХ = СсылкаНаХарактеристику.ПолучитьОбъект();
        ОбъектХ.ФайлКартинки = НовыйФайлСсылка;
        ОбъектХ.Записать();
    КонецЕсли;
    
КонецЕсли;

Анализ особенностей и потенциальных проблем

При массовом переносе картинок следует обратить внимание на следующие аспекты:

1. Очистка старых данных. Если вы переносите картинку и старая номенклатура больше не нужна, не забудьте пометить на удаление или удалить исходный файл. В противном случае объем базы данных неоправданно вырастет за счет дублей.

2. Превью и миниатюры. В 1С:УНФ для быстрого отображения в списках генерируются уменьшенные копии изображений. При использовании РаботаСФайлами.ДобавитьФайл() система создаст их автоматически.

3. Владелец файла. Убедитесь, что у характеристики правильно заполнен реквизит Владелец (ссылка на номенклатуру), прежде чем привязывать к ней файлы. Корректная связь объектов особенно важна, когда выполняется синхронизация характеристик номенклатуры между УНФ и Бухгалтерией.

4. Обработка ошибок. Всегда оборачивайте код записи объектов в блок Попытка...Исключение, особенно если работаете с транзакциями. При ошибке записи объекта присоединенного файла может возникнуть ситуация "битой ссылки" в основной карточке характеристики.

Резюме

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

← На главную