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