Перенос присоединенных файлов в современных конфигурациях на базе Библиотеки стандартных подсистем (БСП), таких как Управление торговлей 11.4 или Управление нашей фирмой, представляет собой комплексную задачу. В отличие от старых версий программ, где файл мог храниться прямо в реквизите справочника, современные системы используют распределенную структуру: сам файл описывается в специальном справочнике (например, НоменклатураПрисоединенныеФайлы), а его содержимое (двоичные данные) хранится в регистре сведений ДвоичныеДанныеФайлов или во внешних томах.
Разберем подробно, как настроить правила обмена в программном продукте Конвертация данных 2.0 (КД 2.0), чтобы файлы переносились корректно, а ссылки не «бились».
Прежде чем приступать к настройке правил, проанализируем цепочку связей объектов, которую нам необходимо воссоздать в базе-приемнике:
Справочник.Номенклатура или Справочник.СоглашенияСКлиентами).ТипХраненияФайла.ХранилищеЗначения лежат сами байты файла. Измерение Файл этого регистра ссылается на элемент из пункта 2.Основная проблема при обычном переносе заключается в том, что если выгружать эти объекты отдельно через ПВД (Поля выборки данных), нарушается последовательность их создания. В итоге в приемнике может появиться запись в регистре, ссылающаяся на пустой справочник, или справочник без самих данных. Рассмотрим правильный алгоритм.
Для успешного переноса нам потребуется создать три ПКО. Выясним, как они должны взаимодействовать:
СоглашенияСКлиентами. Здесь мы настраиваем перенос основных реквизитов.СоглашенияСКлиентамиПрисоединенныеФайлы. Важно убедиться, что реквизит ВладелецФайла сопоставлен правильно.РегистрСведенийЗапись.ДвоичныеДанныеФайлов. Здесь ключевым является ресурс ДанныеФайла (тип ХранилищеЗначения).Рассмотрим важный нюанс: в ПКО регистра сведений ХранилищеЗначения переносится как обычный реквизит. Система КД 2.0 умеет автоматически сериализовать содержимое хранилища в XML-файл, поэтому никаких дополнительных преобразований в Base64 вручную обычно не требуется, если объем файлов не превышает разумные пределы (до 10-20 Мб).
Чтобы гарантировать наличие всех связей, мы будем использовать механизм вызова правил из обработчиков событий. Рассмотрим ситуацию на примере справочника СоглашенияСКлиентами.
В ПКО справочника-владельца перейдем в обработчик события "После выгрузки". Нам нужно найти все файлы, связанные с этим соглашением, и принудительно отправить их на выгрузку. Проанализируем пример кода:
// Поиск присоединенных файлов для текущего объекта
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Файлы.Ссылка КАК Ссылка
|ИЗ
| Справочник.СоглашенияСКлиентамиПрисоединенныеФайлы КАК Файлы
|ГДЕ
| Файлы.ВладелецФайла = &Владелец";
Запрос.УстановитьПараметр("Владелец", Источник.Ссылка);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующая() Цикл
// Вызываем выгрузку присоединенного файла по конкретному правилу
ВыгрузитьПоПравилу(Выборка.Ссылка, , , , "СоглашенияСКлиентамиПрисоединенныеФайлы");
КонецЦикла;
Теперь перейдем в ПКО справочника СоглашенияСКлиентамиПрисоединенныеФайлы. Аналогично, в обработчике "После выгрузки" нам нужно инициировать выгрузку записи из регистра сведений, где хранятся двоичные данные. Выясним, как это сделать:
// Выгрузка данных из регистра ДвоичныеДанныеФайлов
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ДвоичныеДанные.Файл КАК Файл,
| ДвоичныеДанные.ДанныеФайла КАК ДанныеФайла
|ИЗ
| РегистрСведений.ДвоичныеДанныеФайлов КАК ДвоичныеДанные
|ГДЕ
| ДвоичныеДанные.Файл = &Файл";
Запрос.УстановитьПараметр("Файл", Источник.Ссылка);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();
Если Выборка.Следующая() Тогда
// Подготовим структуру для выгрузки записи регистра
СтруктураЗаписи = Новый Структура("Файл, ДанныеФайла");
ЗаполнитьЗначенияСвойств(СтруктураЗаписи, Выборка);
// Выгружаем запись регистра по правилу
ВыгрузитьПоПравилу(СтруктураЗаписи, , , , "ДвоичныеДанныеФайлов");
КонецЕсли;
Важно: При выгрузке регистра через ВыгрузитьПоПравилу в качестве источника мы передаем Структура. В самом ПКО регистра в этом случае необходимо установить флаг "Получить из входящих данных" для соответствующих свойств.
Одной из самых частых причин ошибки «Объект не найден» или сообщения «Данные были удалены» при попытке открыть файл в базе-приемнике является несовпадение Уникальных Идентификаторов (GUID).
Проанализируем ситуацию: если справочник файлов в приемнике создался с одним GUID, а запись в регистре сведений ссылается на другой GUID (потому что поиск при загрузке отработал некорректно), то система БСП не сможет «собрать» файл воедино.
Чтобы избежать этого, придерживайтесь следующих правил:
Файл также настроен поиск по GUID.Если в вашей базе хранятся тысячи файлов или их размер превышает сотни мегабайт, выгрузка в один XML-файл может привести к ошибке Недостаточно памяти. Рассмотрим способы оптимизации:
Способ 1: Использование Base64. В некоторых случаях стабильнее передавать двоичные данные как строку. В обработчике Перед выгрузкой свойства ДанныеФайла можно использовать код:
Значение = Base64Строка(Источник.ДанныеФайла.Получить());
А в обработчике После загрузки выполнить обратное преобразование:
Объект.ДанныеФайла = Новый ХранилищеЗначения(Base64Значение(Запись.ДанныеФайла));
Способ 2: Поэтапная выгрузка. Рекомендуем сначала перенести справочники владельцев, затем справочники присоединенных файлов, и только в самом конце — записи регистра сведений. Это снизит нагрузку на оперативную память при загрузке в приемник.
В процессе переноса номенклатуры часто возникает сопутствующая задача — перенос дополнительных реквизитов. Рассмотрим, почему они могут не отображаться в приемнике, даже если данные перенесены.
Система БСП хранит дополнительные реквизиты в табличной части объекта, но их видимость и состав определяются справочником НаборыДополнительныхРеквизитовИСведений. Если вы перенесли номенклатуру, но не перенесли запись в этом справочнике, привязанную к ВидуНоменклатуры, то в карточке товара дополнительные поля просто не появятся на форме.
Для корректного переноса "допов" выполните следующие действия:
ДополнительныеРеквизитыИСведений.НаборыДополнительныхРеквизитовИСведений.ВидНоменклатуры, а для вида номенклатуры, в свою очередь, настроен перенос соответствующего набора свойств.Таким образом, системный подход к иерархии объектов БСП позволяет бесшовно переносить файлы и связанные данные, сохраняя полную работоспособность системы в базе-приемнике. Помните, что ключевой момент — это соблюдение последовательности: Владелец -> Справочник-описание файла -> Двоичные данные в регистре.