- Перенос в обычном случае реквизита типа ХранилищеЗначения
- Главная сложность переноса файлов между базами 1С
- Перенос, когда данные хранятся в отдельном регистре
- Перенос присоединенных файлов между новыми 1С
- Перенос в старые 1С (УПП, КА 1.1, УТ 10.3)
- Другие статьи по работе с файлами на управляемых формах 1С
Перенос в обычном случае реквизита типа ХранилищеЗначения
Если вам необходимо с помощью правил обмена 1С в формате XML перенести объект, у которого есть свойства типа ХранилищеЗначения, в общем случае ничего особенного делать не надо. Установите соответствие этих свойств в ПКС один в один. Перенос будет выполнен автоматически. При выгрузке будет автоматически выполняться конвертация в base64-строку, а при загрузке из этой строки будет заполняться значение типа ХранилищеЗначения в базе 1С-приемнике данных.
Пример, как такой перенос может выглядеть в Конвертация данных 2, смотрите на скриншоте:
Главная сложность переноса файлов между базами 1С
Главная сложность заключается в том, чтобы найти, где в исходной базе действительно хранится значение файла. Дело в том, что часто есть справочник, в нем есть реквизит с названием ФайлХранилище, имеющий тип значения ХранилищеЗначения. Но при этом реквизит пустой. В момент создания нового файла дополнительно создается запись регистра сведений и/или другого дополнительного справочника. Ваша задача - найти этот объект и выгружать именно из него. Пример для современных программ 1С рассмотрим по тексту ниже.
Перенос, когда данные хранятся в отдельном регистре
В современных программах 1С, таких как 1С:ERP, 1С:Бухгалтерия, 1С:Комплексная автоматизация 2, 1С:Управление торговлей, 1С:УНФ, 1С:Розница, 1С:ЗУП, хранение файлов устроено сложнее.
Есть множество справочников, имеющих в названии фразу …ПрисоединенныеФайлы. У них есть свойства ФайлХранилище, имеющее тип ХранилищеЗначения. Но реквизит этот пустой.
Есть регистр сведений ХранилищеФайлов. Запись в нем создается автоматически для каждого справочника присоединенных файлов. В этом регистре ресурс с типом ХранилищеЗначения, но и он также пустой! Также в регистре сведений ХранилищеФайлов есть ресурс Файл с типом значения СправочникСсылка.ХранилищеДвоичныхФайлов. И вот уже в этом справочнике в реквизите с названием ДвоичныеДанные хранятся сами данные прикрепленного файла. Именно эти данные надо выгружать.
На рисунке показана структура справочника ХранилищеДвоичныхДанных:
Перенос присоединенных файлов между новыми 1С
Представим, что у вас стоит задача перенести элементы справочника ФизическиеЛицаПрисоединенныеФайлы или НоменклатураПрисоединенныеФайлы или любого другого подобного справочника. Нужно, чтобы сам файл был перенесен, то есть корректно открывался на просмотр или редактирование в новой 1С, в которую выполнен перенос данных 1С.
Как уже выше разбирали, сам файл хранится в дополнительных реквизитах и справочниках, а не в хранилище текущего элемента справочника.
В реальном переносе нам помог следующий код в обработке ПослеВыгрузки текущего ПКО (ниже). В этом коде для текущего элемента справочника выгружаются связанные записи регистра сведений УдалитьДвоичныеДанныеФайлы (проверьте, есть ли такой регистр в вашей 1С), а также регистра ХранилищеФайлов и регистра СведенияОФайлах.
Такой код будет работать при переносе из одной современной конфигурации 1С в другую современную конфигурацию 1С. Если нужно переносить в старую 1С (например, в 1С:УПП), изучите пример кода далее по тексту статьи в следующем абзаце.
нзДвоичныеДанныеФайлов = РегистрыСведений.УдалитьДвоичныеДанныеФайлов.СоздатьНаборЗаписей(); нзДвоичныеДанныеФайлов.Отбор.Файл.Установить(Источник.Ссылка); нзДвоичныеДанныеФайлов.Прочитать(); Для Каждого текЗапись Из нзДвоичныеДанныеФайлов Цикл Попытка ВыгрузитьПоПравилу(текЗапись,,,,"УдалитьДвоичныеДанныеФайлов"); Исключение Сообщить(ОписаниеОшибки()); КонецПопытки; КонецЦикла; нзДвоичныеДанныеФайлов = РегистрыСведений.ХранилищеФайлов.СоздатьНаборЗаписей(); нзДвоичныеДанныеФайлов.Отбор.Файл.Установить(Источник.Ссылка); нзДвоичныеДанныеФайлов.Прочитать(); Для Каждого текЗапись Из нзДвоичныеДанныеФайлов Цикл Попытка ВыгрузитьПоПравилу(текЗапись,,,,"ХранилищеФайлов"); Исключение Сообщить(ОписаниеОшибки()); КонецПопытки; КонецЦикла; нзСведенияОФайлах = РегистрыСведений.СведенияОФайлах.СоздатьНаборЗаписей(); нзСведенияОФайлах.Отбор.Файл.Установить(Источник.Ссылка); нзСведенияОФайлах.Прочитать(); Для Каждого текЗапись Из нзСведенияОФайлах Цикл Попытка ВыгрузитьПоПравилу(текЗапись,,,,"СведенияОФайлах"); Исключение Сообщить(ОписаниеОшибки()); КонецПопытки; КонецЦикла;
Перенос в старые 1С (УПП, КА 1.1, УТ 10.3)
Представим, что выгрузить данные нужно из современной программы 1С в какую-либо старую, например, в 1С:УПП. В таком случае программный код в ПКС ФайлХранилище будет примерно следующим:
Значение = Неопределено; нзДвоичныеДанныеФайлов = РегистрыСведений.ХранилищеФайлов.СоздатьНаборЗаписей(); нзДвоичныеДанныеФайлов.Отбор.Файл.Установить(Источник.Ссылка); нзДвоичныеДанныеФайлов.Прочитать(); ЕстьДанные = Ложь; Для Каждого текЗапись Из нзДвоичныеДанныеФайлов Цикл Если ЗначениеЗаполнено(текЗапись.ХранилищеДвоичныхДанных) Тогда ЕстьДанные = Истина; Значение = ДанныеХранилища; КонецЕсли; КонецЦикла; Если Значение = Неопределено Тогда Отказ = Истина; Иначе Отказ = Ложь; КонецЕсли;
Здесь Источник.Ссылка - ссылка на текущий выгружаемый элемент справочника присоединенных файлов (как написано выше, таких справочников много с разными именами в новых 1С).
Но проделать это будет недостаточно. В старых 1С хранение изображений устроено немного по-другому. Вроде бы, реквизит имеет тип значения ХранилищеЗначения. Но в момент, когда программа 1С пытается отобразить его для просмотра, вызывает метод Получить() и возникает объект типа Картина, а не типа ДвоичныеДанные, как можно было ожидать.
Таким образом, в момент загрузки данных нужно поместить в реквизит типа ХранилищеЗначения именно эту картинку, иначе будет в 1С:УПП возникать ошибка при попытке открытия картинки на просмотр. Как это сделать?
ПКО выглядит так:
Обработчик выглядит так:
Мы реализовали в обработчике ПослеЗагрузки следущим кодом:
Если Объект.ВидДанных = Перечисления.ВидыДополнительнойИнформацииОбъектов.Изображение Тогда Картинка = Новый Картинка(Объект.Хранилище.Получить()); Объект.Хранилище = Новый ХранилищеЗначения(Картинка, Новый СжатиеДанных()); Объект.Записать(); КонецЕсли;
То есть инициализировали хранилище значения именно по объекту типа Картинка, а не по ДвоичнымДанным.
Другие статьи по работе с файлами на управляемых формах 1С
Если вас интересуют подробности про работу с файлами из 1С, изучите другие статьи на нашем сайте:














































Получать значение из хранилища значения НЕ НУЖНО! Некоторые разработчики в ситуации ниже пишут в ПКС Файл - Файл такой код:
Значение = Источник.Файл.Получить();Делать так неверно. Если для реквизита типа ХранилищеЗначения вызвать метод
Получить(), результат будет иметь тип ДвоичныеДанные. Такое выгружаться не будет!