В процессе реорганизации каталога товаров в 1С:Управление нашей фирмой (УНФ) часто возникает задача консолидации данных. Типичный сценарий: ранее разные варианты одного товара велись как отдельные карточки номенклатуры, а теперь их необходимо объединить в одну карточку с использованием характеристик. Подобные задачи часто встречаются, когда выполняется перенос данных из ТиС 7.7 в УНФ 3.0 или другие варианты миграции. Одной из самых трудоемких подзадач в этом процессе является перенос изображений. В этой статье мы подробно разберем, как программно перенести картинку из объекта Номенклатура в объект ХарактеристикиНоменклатуры.
Проанализируем структуру хранения файлов в современных конфигурациях на базе БСП. Картинки не хранятся напрямую в реквизитах справочника. Вместо этого используются подчиненные справочники присоединенных файлов. Для номенклатуры это НоменклатураПрисоединенныеФайлы, а для характеристик — ХарактеристикиНоменклатурыПрисоединенныеФайлы. Сложности с типами данных часто возникают, когда требуется кастомная выгрузка номенклатуры с картинками из старой УНФ 1.6 в новые редакции программ.
Разберем основные причины, по которым нельзя просто скопировать ссылку:
ВладелецФайла в каждом из этих справочников имеет жестко заданный тип. В справочнике файлов номенклатуры это ссылка на Справочник.Номенклатура, а в справочнике файлов характеристик — Справочник.ХарактеристикиНоменклатуры.ХранилищеФайлов, либо на внешних томах (на диске).Рассмотрим два способа решения задачи: «быстрый хак» через прямой запрос к регистру и «правильный метод» с использованием механизмов БСП.
Этот метод подходит для разового переноса данных, когда вы точно знаете, что файлы хранятся внутри базы данных, а не в томах на диске.
Проанализируем пример кода для реализации этой задачи:
// Предположим, у нас уже есть ссылки на Характеристику и исходную Номенклатуру
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Файл,
| ХранилищеДвоичныхданных
|ИЗ
| РегистрСведений.ХранилищеФайлов КАК ХранилищеФайлов
|ГДЕ
| Файл = &ВыбФайл";
// Ссылка на картинку исходной номенклатуры
Запрос.УстановитьПараметр("ВыбФайл", НоменклатураИсточник.ФайлКартинки);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Если Выборка.Следующий() Тогда
// 1. Создаем новый элемент в справочнике файлов характеристик
НоваяКартинка = Справочники.ХарактеристикиНоменклатурыПрисоединенныеФайлы.СоздатьЭлемент();
// Копируем основные реквизиты (наименование, расширение и т.д.)
ЗаполнитьЗначенияСвойств(НоваяКартинка, НоменклатураИсточник.ФайлКартинки, , "Родитель, Владелец");
// Устанавливаем нового владельца — нашу характеристику
НоваяКартинка.ВладелецФайла = СсылкаНаХарактеристику;
НоваяКартинка.Записать();
// 2. Копируем двоичные данные в регистр сведений
МенеджерЗаписи = РегистрыСведений.ХранилищеФайлов.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Файл = НоваяКартинка.Ссылка;
МенеджерЗаписи.ХранилищеДвоичныхДанных = Выборка.ХранилищеДвоичныхданных;
МенеджерЗаписи.Записать();
// 3. Обновляем основную картинку в самой характеристике
ОбъектХарактеристика = СсылкаНаХарактеристику.ПолучитьОбъект();
ОбъектХарактеристика.ФайлКартинки = НоваяКартинка.Ссылка;
ОбъектХарактеристика.Записать();
КонецЕсли;
Важный нюанс: В коде выше мы используем ЗаполнитьЗначенияСвойств, исключая Родитель и Владелец. Это необходимо, так как мы создаем объект в другом справочнике, и эти поля должны быть инициализированы заново.
Если в вашей базе настроено хранение файлов в томах на диске, прямой метод через регистр ХранилищеФайлов не сработает. В этом случае лучше использовать стандартные возможности платформы, изучив справочник по методам БСП с примерами использования.
Рассмотрим пошаговый алгоритм работы через БСП:
Посмотрим на пример реализации:
// Получаем двоичные данные файла номенклатуры
// Метод РаботаСФайлами.ДвоичныеДанныеФайла корректно получит данные и из базы, и с диска
ДвоичныеДанные = РаботаСФайлами.ДвоичныеДанныеФайла(НоменклатураИсточник.ФайлКартинки);
Если ДвоичныеДанные <> Неопределено Тогда
// Подготавливаем параметры для создания нового файла характеристик
ПараметрыФайла = Новый Структура;
ПараметрыФайла.Вставить("Автор", Пользователи.ТекущийПользователь());
ПараметрыФайла.Вставить("ИмяБезРасширения", "Картинка_Характеристики");
ПараметрыФайла.Вставить("Расширение", "jpg"); // Желательно получить из исходного файла
// Добавляем файл в систему
// Функция сама создаст запись в нужном справочнике присоединенных файлов
НовыйФайлСсылка = РаботаСФайлами.ДобавитьФайл(
СсылкаНаХарактеристику,
"Картинка_Характеристики.jpg",
ДвоичныеДанные,
"Перенос из номенклатуры",
ПараметрыФайла
);
// Устанавливаем привязку в объекте Характеристика
Если ЗначениеЗаполнено(НовыйФайлСсылка) Тогда
ОбъектХ = СсылкаНаХарактеристику.ПолучитьОбъект();
ОбъектХ.ФайлКартинки = НовыйФайлСсылка;
ОбъектХ.Записать();
КонецЕсли;
КонецЕсли;
При массовом переносе картинок следует обратить внимание на следующие аспекты:
1. Очистка старых данных. Если вы переносите картинку и старая номенклатура больше не нужна, не забудьте пометить на удаление или удалить исходный файл. В противном случае объем базы данных неоправданно вырастет за счет дублей.
2. Превью и миниатюры. В 1С:УНФ для быстрого отображения в списках генерируются уменьшенные копии изображений. При использовании РаботаСФайлами.ДобавитьФайл() система создаст их автоматически.
3. Владелец файла. Убедитесь, что у характеристики правильно заполнен реквизит Владелец (ссылка на номенклатуру), прежде чем привязывать к ней файлы. Корректная связь объектов особенно важна, когда выполняется синхронизация характеристик номенклатуры между УНФ и Бухгалтерией.
4. Обработка ошибок. Всегда оборачивайте код записи объектов в блок Попытка...Исключение, особенно если работаете с транзакциями. При ошибке записи объекта присоединенного файла может возникнуть ситуация "битой ссылки" в основной карточке характеристики.
Мы проанализировали два подхода к переносу картинок. Первый метод (через регистр ХранилищеФайлов) эффективен для быстрых правок в простых базах. Второй метод (через РаботаСФайлами) является стандартом разработки на платформе 1С:Предприятие 8.3, так как он учитывает настройки томов хранения, автоматически генерирует миниатюры изображений и поддерживает целостность данных БСП. Для разработки долгосрочных решений мы рекомендуем использовать именно его.