//////////////////////////////////////////////////////////////////////////////// // Подсистема "Выгрузка загрузка данных". // //////////////////////////////////////////////////////////////////////////////// #Область СлужебныйПрограммныйИнтерфейс // Добавляет в список Обработчики процедуры-обработчики обновления, необходимые данной подсистеме. // @skip-warning ПустойМетод - особенность реализации. // // Параметры: // Обработчики - см. ОбновлениеИнформационнойБазы.НоваяТаблицаОбработчиковОбновления // Процедура ЗарегистрироватьОбработчикиОбновления(Обработчики) Экспорт КонецПроцедуры // См. ОбщегоНазначенияПереопределяемый.ПриДобавленииПараметровРаботыКлиентаПриЗапуске. Процедура ПриДобавленииПараметровРаботыКлиентаПриЗапуске(Параметры) Экспорт Параметры.Вставить("ВыгрузкаЗагрузкаДанныхЗагрузкаПрервана", ОбщегоНазначенияВызовСервераБТС.ЗагрузкаПрервана()); КонецПроцедуры Функция НачатьЗагрузкуДанныхТекущейОбластиИзАрхива(Знач ДанныеФайла, Знач ПараметрыЗагрузки, Знач АдресРезультата = Неопределено) Экспорт УстановитьОтключениеБезопасногоРежима(Истина); УстановитьПривилегированныйРежим(Истина); ПараметрыЗагрузки.Вставить( "ЗагружаемыеТипы", ЗагружаемыеТипы(ТипРезервнойКопии(ПараметрыЗагрузки))); Обработчики = Обработки.ВыгрузкаЗагрузкаДанныхМенеджерОбработчиковЗагрузкиДанных.Создать(); Обработчики.Инициализировать(); Контейнер = Обработки.ВыгрузкаЗагрузкаДанныхМенеджерКонтейнера.Создать(); Контейнер.ИнициализироватьЗагрузку(ДанныеФайла, ПараметрыЗагрузки); Если ПараметрыЗагрузки.ВозможноПродолжениеПроцедурыЗагрузки Тогда СоответствиеСсылок = ПродолжитьПроцедуруЗагрузки(ПараметрыЗагрузки, Контейнер, Обработчики); Иначе СоответствиеСсылок = НачатьПроцедуруЗагрузки(ПараметрыЗагрузки, Контейнер, Обработчики); КонецЕсли; РезультатЗагрузки = Новый Структура( "Предупреждения, СоответствиеСсылок", Контейнер.Предупреждения(), СоответствиеСсылок); Если АдресРезультата <> Неопределено Тогда ПоместитьВоВременноеХранилище(РезультатЗагрузки, АдресРезультата); КонецЕсли; Возврат РезультатЗагрузки; КонецФункции //////////////////////////////////////////////////////////////////////////////// // Выгрузка/загрузка данных // Выполняет удаление временного файла, ошибки при удалении игнорируются. // // Параметры: // Путь - Строка - путь к удаляемому файлу. // Процедура УдалитьВременныйФайл(Знач Путь) Экспорт Инфо = Новый Файл(Путь); Если Не Инфо.Существует() Тогда Возврат; КонецЕсли; Попытка УдалитьФайлы(Путь); Исключение ЗаписьЖурналаРегистрации(НСтр("ru = 'Удаление файла'", ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Ошибка, , , ИнформацияОбОшибке().Описание); КонецПопытки; КонецПроцедуры // Возвращает массив всех объектов метаданных, содержащихся в конфигурации. // Используется для запуска выгрузки и загрузки данных в конфигурациях, не содержащих БСП. // // Возвращаемое значение: // Массив из ОбъектМетаданных - типы. // // Пример: // ПараметрыВыгрузки = Новый Структура(); // ПараметрыВыгрузки.Вставить("ВыгружаемыеТипы", ВыгрузкаЗагрузкаДанныхСлужебный.ПолучитьВсеТипыКонфигурации()); // ПараметрыВыгрузки.Вставить("ВыгружатьПользователей", Истина); // ПараметрыВыгрузки.Вставить("ВыгружатьНастройкиПользователей", Истина); // ИмяФайла = ВыгрузкаЗагрузкаДанных.ВыгрузитьДанныеТекущейОбластиВАрхив(ПараметрыВыгрузки); // // ПараметрыЗагрузки = Новый Структура(); // ПараметрыЗагрузки.Вставить("ЗагружаемыеТипы", ВыгрузкаЗагрузкаДанныхСлужебный.ПолучитьВсеТипыКонфигурации()); // ПараметрыЗагрузки.Вставить("ЗагружатьПользователей", Истина); // ПараметрыЗагрузки.Вставить("ЗагружатьНастройкиПользователей", Истина); // ВыгрузкаЗагрузкаДанных.ЗагрузитьДанныеТекущейОбластиИзАрхива(ИмяФайла, ПараметрыЗагрузки); // Функция ПолучитьВсеТипыКонфигурации() Экспорт МассивКоллекцийМетаданных = Новый Массив(); ЗаполнитьКоллекцииКонстант(МассивКоллекцийМетаданных); ЗаполнитьКоллекцииСсылочныхОбъектов(МассивКоллекцийМетаданных); ЗаполнитьКоллекцииНаборовЗаписей(МассивКоллекцийМетаданных); Возврат МассивКоллекцийМетаданных; КонецФункции // Выгружает данные в каталог. // // Параметры: // ПараметрыВыгрузки - Структура - содержащая параметры выгрузки данных. // Ключи: // ВыгружаемыеТипы - Массив Из ОбъектМетаданных - массив объектов метаданных, данные // которых требуется выгрузить в архив, // ВыгружатьПользователей - Булево - выгружать информацию о пользователях информационной базы, // ВыгружатьНастройкиПользователей - Булево - игнорируется если ВыгружатьПользователей = Ложь. // Также структура может содержать дополнительные ключи, которые могут быть обработаны внутри // произвольных обработчиков выгрузки данных. // // Возвращаемое значение: // Структура - с полями: // * ИмяФайла - Строка - имя файла архива // * Предупреждения - Массив Из Строка - предупреждения пользователю по результатам выгрузки. // Функция ВыгрузитьДанныеТекущейОбластиВАрхив(Знач ПараметрыВыгрузки) Экспорт Контейнер = Обработки.ВыгрузкаЗагрузкаДанныхМенеджерКонтейнера.Создать(); Контейнер.ИнициализироватьВыгрузку(ПараметрыВыгрузки); Сериализатор = СериализаторXDTOСАннотациейТипов(); Обработчики = Обработки.ВыгрузкаЗагрузкаДанныхМенеджерОбработчиковВыгрузкиДанных.Создать(); Обработчики.Инициализировать(Контейнер); Обработчики.ПередВыгрузкойДанных(Контейнер); СохранитьОписаниеВыгрузки(Контейнер); Обработки.ВыгрузкаЗагрузкаДанныхМенеджерВыгрузкиДанныхИнформационнойБазы.ВыгрузитьДанныеИнформационнойБазы( Контейнер, Обработчики, Сериализатор); Если ПараметрыВыгрузки.ВыгружатьПользователей Тогда ВыгрузкаЗагрузкаПользователейИнформационнойБазы.ВыгрузитьПользователейИнформационнойБазы(Контейнер); Если ПараметрыВыгрузки.ВыгружатьНастройкиПользователей Тогда Обработки.ВыгрузкаЗагрузкаДанныхМенеджерВыгрузкиНастроекПользователей.ВыгрузитьНастройкиПользователейИнформационнойБазы( Контейнер, Обработчики, Сериализатор); КонецЕсли; КонецЕсли; ВыгрузитьСхемуКонфигурации(Контейнер, ПараметрыВыгрузки); Обработчики.ПослеВыгрузкиДанных(Контейнер); Возврат Новый Структура("ИмяФайла, Предупреждения", Контейнер.ФинализироватьВыгрузку(), Контейнер.Предупреждения()); КонецФункции // Загружает данные из каталога. // // Параметры: // ДанныеФайла - Строка, УникальныйИдентификатор, Структура - имя файла, идентификатор файла или данные файла полученные с помощью ZipАрхивы.ПрочитатьАрхив(). // ПараметрыЗагрузки - см. ВыгрузкаЗагрузкаДанных.ЗагрузитьДанныеТекущейОбластиИзАрхива.ПараметрыЗагрузки. // // Возвращаемое значение: // Структура: // * Предупреждения - Массив Из Строка - предупреждения пользователю по результатам загрузки. // Функция ЗагрузитьДанныеТекущейОбластиИзАрхива(Знач ДанныеФайла, Знач ПараметрыЗагрузки) Экспорт РазделениеВключено = ОбщегоНазначения.РазделениеВключено(); ПропуститьВосстановлениеРасширений = ПараметрыЗагрузки.Свойство("ПропуститьВосстановлениеРасширений") И ПараметрыЗагрузки.ПропуститьВосстановлениеРасширений; ХешСуммаИсточника = ХешСуммаИсточника(ПрочитатьАрхив(ДанныеФайла)); ПараметрыЗагрузки.Вставить("ХешСуммаИсточника", ХешСуммаИсточника); ХешСуммаПараметров = ХешСуммаПараметров(ПараметрыЗагрузки); ПараметрыЗагрузки.Вставить("ХешСуммаПараметров", ХешСуммаПараметров); ВозможноПродолжениеПроцедурыЗагрузки = ВозможноПродолжениеПроцедурыЗагрузки( ХешСуммаИсточника, ХешСуммаПараметров); ПараметрыЗагрузки.Вставить("ВозможноПродолжениеПроцедурыЗагрузки", ВозможноПродолжениеПроцедурыЗагрузки); Если Не (ВозможноПродолжениеПроцедурыЗагрузки Или ЭтоДифференциальнаяРезервнаяКопия(ПараметрыЗагрузки)) Тогда РаботаВМоделиСервиса.ОчиститьДанныеОбласти(Не ПропуститьВосстановлениеРасширений, Ложь); Если Не ПропуститьВосстановлениеРасширений Тогда ДанныеРасширений = Неопределено; ПараметрыЗагрузки.Свойство("ДанныеРасширений", ДанныеРасширений); Если ЗначениеЗаполнено(ДанныеРасширений) Тогда Если РазделениеВключено Тогда ВосстановитьРасширенияОбласти(ДанныеРасширений); ВосстановитьРасширения1СПлюсИзМС(ДанныеРасширений); Иначе ВосстановитьРасширенияИнформационнойБазы(ДанныеРасширений); КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; Если ИспользоватьМногопоточность(ПараметрыЗагрузки) Тогда РаботаВМоделиСервиса.УстановитьМонопольнуюБлокировку(Истина); КонецЕсли; Если Не ПропуститьВосстановлениеРасширений И РасширенияВМоделиСервиса.ЕстьУстановленныеРасширенияИзменяющиеСтруктуруДанных() Тогда РезультатЗагрузки = ЗагрузитьДанныеТекущейОбластиИзАрхиваВФоне(ДанныеФайла, ПараметрыЗагрузки); Иначе РезультатЗагрузки = НачатьЗагрузкуДанныхТекущейОбластиИзАрхива(ДанныеФайла, ПараметрыЗагрузки); КонецЕсли; Возврат РезультатЗагрузки; КонецФункции Процедура ВосстановитьРасширенияИнформационнойБазы(ДанныеРасширений) Экспорт РасширенияДляВосстановления = Неопределено; Если ДанныеРасширений.Свойство("РасширенияДляВосстановления", РасширенияДляВосстановления) Тогда ВосстановитьРасширения(РасширенияДляВосстановления); КонецЕсли; КаркасыРасширенийДляВосстановления = Неопределено; Если ДанныеРасширений.Свойство("КаркасыРасширенийДляВосстановления", КаркасыРасширенийДляВосстановления) Тогда ВосстановитьКаркасыРасширений(КаркасыРасширенийДляВосстановления); КонецЕсли; КонецПроцедуры Процедура ВосстановитьРасширения1СПлюс(Расширения1СПлюс) Экспорт МодульПлюсСервис = ПолучитьМодуль1СПлюс(); Если Не МодульПлюсСервис = Неопределено Тогда МодульПлюсСервис.ВосстановитьРасширения(Расширения1СПлюс); КонецЕсли; КонецПроцедуры // Сравнивает совместима ли выгрузка с текущей конфигурацией. // // Параметры: // ИнформацияОВыгрузке - ОбъектXDTO - см. процедуру "СохранитьОписаниеВыгрузки". // // Возвращаемое значение: // Булево - Истина, если совпадает. // Функция ВыгрузкаВАрхивеСовместимаСТекущейКонфигурацией(ИнформацияОВыгрузке) Экспорт ИмяКонфигурации = ИнформацияОВыгрузке.Configuration.Name; Возврат ВидыПриложенийСервер.СвойстваВидаПриложенияПоИмени(ИмяКонфигурации, Ложь) <> Неопределено; КонецФункции // Сравнивает совместима ли версия конфигурации с выгруженной. // // Параметры: // ИнформацияОВыгрузке - ОбъектXDTO - см. процедуру "СохранитьОписаниеВыгрузки". // // Возвращаемое значение: // Булево - Истина, если совпадает. // Функция ВыгрузкаВАрхивеСовместимаСТекущейВерсиейКонфигурации(ИнформацияОВыгрузке) Экспорт Возврат ИнформацияОВыгрузке.Configuration.Version = Метаданные.Версия; КонецФункции // Сравнивает совместима ли выгрузка с текущей конфигурацией. // // Параметры: // ИнформацияОВыгрузке - ОбъектXDTO - см. процедуру "СохранитьОписаниеВыгрузки". // Процедура ПроверитьВыгрузкаВАрхивеСовместимаСТекущейКонфигурацией(ИнформацияОВыгрузке) Экспорт Если Не ВыгрузкаВАрхивеСовместимаСТекущейКонфигурацией(ИнформацияОВыгрузке) Тогда ВызватьИсключение ТекстОшибкиВыгрузкаНеСовместимаСТекущейКонфигурацией(ИнформацияОВыгрузке); КонецЕсли; КонецПроцедуры // Сравнивает совместима ли версия конфигурации с выгруженной. // // Параметры: // ИнформацияОВыгрузке - ОбъектXDTO - см. процедуру "СохранитьОписаниеВыгрузки". // СтрогаяПроверка - Булево - если Истина, то проверяет на равенство, если Ложь, то версия в выгрузке должна быть меньше либо равна текущей // Процедура ПроверитьВыгрузкаВАрхивеСовместимаСТекущейВерсиейКонфигурации(Знач ИнформацияОВыгрузке, Знач СтрогаяПроверка = Ложь) Экспорт ВыгрузкаСовместима = Ложь; Если СтрогаяПроверка Тогда ВыгрузкаСовместима = ИнформацияОВыгрузке.Configuration.Version = Метаданные.Версия Иначе ВыгрузкаСовместима = ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ИнформацияОВыгрузке.Configuration.Version, Метаданные.Версия) <= 0; КонецЕсли; Если Не ВыгрузкаСовместима Тогда ВызватьИсключение ТекстОшибкиВыгрузкаНеСовместимаСТекущейВерсиейКонфигурации(ИнформацияОВыгрузке); КонецЕсли; КонецПроцедуры // Текст ошибки выгрузка не совместима с текущей конфигурацией. // // Параметры: // ИнформацияОВыгрузке - ОбъектXDTO - см. процедуру "СохранитьОписаниеВыгрузки". // // Возвращаемое значение: // Строка - Текст ошибки Функция ТекстОшибкиВыгрузкаНеСовместимаСТекущейКонфигурацией(ИнформацияОВыгрузке) Экспорт Возврат СтрШаблон(НСтр("ru = 'Невозможно загрузить данные из файла, т.к. файл был выгружен из другой конфигурации (файл выгружен из конфигурации %1 и не может быть загружен в конфигурацию %2).'"), ИнформацияОВыгрузке.Configuration.Name, Метаданные.Имя); КонецФункции // Текст ошибки выгрузка не совместима с текущей версией конфигурации. // // Параметры: // ИнформацияОВыгрузке - ОбъектXDTO - см. процедуру "СохранитьОписаниеВыгрузки". // // Возвращаемое значение: // Строка - Текст ошибки Функция ТекстОшибкиВыгрузкаНеСовместимаСТекущейВерсиейКонфигурации(ИнформацияОВыгрузке) Экспорт Возврат СтрШаблон(НСтр("ru = 'Невозможно загрузить данные из файла, т.к. файл был выгружен из другой версии конфигурации (файл выгружен из конфигурации версии %1 и не может быть загружен в конфигурацию версии %2).'"), ИнформацияОВыгрузке.Configuration.Version, Метаданные.Версия); КонецФункции // Тип данных файла, в котором хранится имя колонки с исходной ссылкой. // // Возвращаемое значение: // Строка - имя типа. // Функция ТипДанныхДляИмениКолонкиТаблицыЗначений() Экспорт Возврат "1cfresh\ReferenceMapping\ValueTableColumnName"; КонецФункции //////////////////////////////////////////////////////////////////////////////// // Типы файлов и структура каталогов выгрузки/загрузки // Возвращает наименование типа файла с информацией о выгрузке. // Возвращаемое значение: // Строка - наименование типа. Функция DumpInfo() Экспорт Возврат "DumpInfo"; КонецФункции // Возвращает наименование типа файла с информацией о составе выгрузке. // Возвращаемое значение: // Строка - наименование типа. Функция PackageContents() Экспорт Возврат "PackageContents"; КонецФункции // Возвращает наименование типа файла с информацией о сопоставлении ссылок. // Возвращаемое значение: // Строка - наименование типа. Функция ReferenceMapping() Экспорт Возврат "ReferenceMapping"; КонецФункции // Возвращает наименование типа файла с информацией о пересоздании ссылок. // Возвращаемое значение: // Строка - наименование типа. Функция ReferenceRebuilding() Экспорт Возврат "ReferenceRebuilding"; КонецФункции // Возвращает наименование типа файла, хранящий сериализованные данные информационной базы. // Возвращаемое значение: // Строка - наименование типа. Функция InfobaseData() Экспорт Возврат "InfobaseData"; КонецФункции // Возвращает наименование типа файла, хранящий сериализованные изменения данных информационной базы. // Возвращаемое значение: // Строка - наименование типа. Функция InfobaseDataChanges() Экспорт Возврат "InfobaseDataChanges"; КонецФункции // Возвращает наименование типа файла, хранящий сериализованные данные границ последовательности. // Возвращаемое значение: // Строка - наименование типа. Функция SequenceBoundary() Экспорт Возврат "SequenceBoundary"; КонецФункции // Возвращает наименование типа файла, хранящий сериализованные данные настроек пользователей. // Возвращаемое значение: // Строка - наименование типа. Функция UserSettings() Экспорт Возврат "UserSettings"; КонецФункции // Возвращает наименование типа файла, хранящий сериализованные данные пользователей. // Возвращаемое значение: // Строка - наименование типа. Функция Users() Экспорт Возврат "Users"; КонецФункции // Возвращает наименование типа файла, хранящий произвольные данные. // Возвращаемое значение: // Строка - наименование типа. Функция CustomData() Экспорт Возврат "CustomData"; КонецФункции // Функция формирует правила структуры каталогов в выгрузке. // // Возвращаемое значение: // ФиксированнаяСтруктура - структура каталогов: // * DumpInfo - Строка // * Digest - Строка // * Extensions - Строка // * CustomExtensions - Строка // * DumpWarnings - Строка // * PackageContents - Строка // * ReferenceMapping - Строка // * ReferenceRebuilding - Строка // * InfobaseData - Строка // * SequenceBoundary - Строка // * Users - Строка // * UserSettings - Строка // * CustomData - Строка Функция ПравилаФормированияСтруктурыКаталогов() Экспорт КорневойКаталог = ""; КаталогДанных = "Data"; Результат = Новый Структура(); Результат.Вставить(DumpInfo(), КорневойКаталог); Результат.Вставить(Digest(), КорневойКаталог); Результат.Вставить(Extensions(), КорневойКаталог); Результат.Вставить(CustomExtensions(), КорневойКаталог); Результат.Вставить(DumpWarnings(), КорневойКаталог); Результат.Вставить(ApplicationTypes(), КорневойКаталог); Результат.Вставить(PackageContents(), КорневойКаталог); Результат.Вставить(ReferenceMapping(), ReferenceMapping()); Результат.Вставить(ReferenceRebuilding(), ReferenceRebuilding()); Результат.Вставить(InfobaseData(), КаталогДанных); Результат.Вставить(SequenceBoundary(), КаталогДанных); Результат.Вставить(Users(), КорневойКаталог); Результат.Вставить(UserSettings(), UserSettings()); Результат.Вставить(CustomData(), CustomData()); Возврат Новый ФиксированнаяСтруктура(Результат); КонецФункции // Возвращает типы файлов, которые поддерживают замену ссылок. // // Возвращаемое значение: // Массив из Строка - массив типов файлов. // Функция ТипыФайловПоддерживающиеЗаменуСсылок() Экспорт Результат = Новый Массив(); Результат.Добавить(InfobaseData()); Результат.Добавить(SequenceBoundary()); Результат.Добавить(UserSettings()); Возврат Результат; КонецФункции // Возвращает имя типа, который будет использован в xml файле для указанного объекта метаданных // Используется при поиске и замене ссылок при загрузке, при модификации схемы current-config при записи. // // Параметры: // Значение - СправочникСсылка, ДокументСсылка, ОбъектМетаданных - объект метаданных или ссылка. // // Возвращаемое значение: // Строка - Строка вида AccountingRegisterRecordSet.Хозрасчетный, описывающая объект метаданных. // Функция XMLТипСсылки(Знач Значение) Экспорт Если ТипЗнч(Значение) = Тип("ОбъектМетаданных") Тогда ОбъектМетаданных = Значение; МенеджерОбъекта = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени(ОбъектМетаданных.ПолноеИмя()); Ссылка = МенеджерОбъекта.ПолучитьСсылку(); Иначе ОбъектМетаданных = Значение.Метаданные(); Ссылка = Значение; КонецЕсли; Если ОбщегоНазначенияБТС.ЭтоСсылочныеДанные(ОбъектМетаданных) Тогда Возврат СериализаторXDTO.XMLТипЗнч(Ссылка).ИмяТипа; Иначе ВызватьИсключение СтрШаблон(НСтр("ru = 'Ошибка при определении XML типа ссылки для объекта %1: объект не является ссылочным'"), ОбъектМетаданных.ПолноеИмя()); КонецЕсли; КонецФункции // Возвращает объект метаданных по типу поля. // // Параметры: // ТипПоля - Тип - тип поля // // Возвращаемое значение: // ОбъектМетаданных - объект метаданных. // Функция ОбъектМетаданныхПоТипуСсылки(Знач ТипПоля) Экспорт СсылкиТочекМаршрутаБизнесПроцессов = СсылкиТочекМаршрутаБизнесПроцессов(); БизнесПроцесс = СсылкиТочекМаршрутаБизнесПроцессов.Получить(ТипПоля); Если БизнесПроцесс = Неопределено Тогда Ссылка = Новый(ТипПоля); МетаданныеСсылки = Ссылка.Метаданные(); Иначе МетаданныеСсылки = БизнесПроцесс; КонецЕсли; Возврат МетаданныеСсылки; КонецФункции // Возвращает полный список констант конфигурации // // Возвращаемое значение: // Массив из ОбъектМетаданных - объекты метаданных. // Функция ВсеКонстанты() Экспорт МетаданныеОбъектов = Новый Массив; ЗаполнитьКоллекцииКонстант(МетаданныеОбъектов); Возврат ВсеМетаданныеКоллекций(МетаданныеОбъектов); КонецФункции // Возвращает полный список ссылочных типов конфигурации // // Возвращаемое значение: // Массив из ОбъектМетаданных // Функция ВсеСсылочныеДанные() Экспорт МетаданныеОбъектов = Новый Массив; ЗаполнитьКоллекцииСсылочныхОбъектов(МетаданныеОбъектов); Возврат ВсеМетаданныеКоллекций(МетаданныеОбъектов); КонецФункции // Возвращает полный список наборов записей конфигурации // // Возвращаемое значение: // Массив из ОбъектМетаданных // Функция ВсеНаборыЗаписей() Экспорт МетаданныеОбъектов = Новый Массив; ЗаполнитьКоллекцииНаборовЗаписей(МетаданныеОбъектов); Возврат ВсеМетаданныеКоллекций(МетаданныеОбъектов); КонецФункции //////////////////////////////////////////////////////////////////////////////// // Чтение/запись данных // Записывает объект в поток записи. // // Параметры: // Объект - Произвольный - записываемый объект. // ПотокЗаписи - ЗаписьXML - поток записи. // Сериализатор - СериализаторXDTO - сериализатор. // Процедура ЗаписатьОбъектВПоток(Знач Объект, ПотокЗаписи, Сериализатор = Неопределено) Экспорт Если Сериализатор = Неопределено Тогда Сериализатор = СериализаторXDTO; КонецЕсли; ПотокЗаписи.ЗаписатьНачалоЭлемента(ИмяЭлементаСодержащегоОбъект()); ПрефиксыПространствИмен = ПрефиксыПространствИмен(); Для Каждого ПрефиксПространстваИмен Из ПрефиксыПространствИмен Цикл ПотокЗаписи.ЗаписатьСоответствиеПространстваИмен(ПрефиксПространстваИмен.Значение, ПрефиксПространстваИмен.Ключ); КонецЦикла; Сериализатор.ЗаписатьXML(ПотокЗаписи, Объект, НазначениеТипаXML.Явное); ПотокЗаписи.ЗаписатьКонецЭлемента(); КонецПроцедуры // Возвращает объект из файла. // // Параметры: // ПотокЧтения - ЧтениеXML - поток чтения. // // Возвращаемое значение: // Произвольный - прочитанных объект. // Функция ПрочитатьОбъектИзПотока(ПотокЧтения) Экспорт Если ПотокЧтения.ТипУзла <> ТипУзлаXML.НачалоЭлемента Или ПотокЧтения.Имя <> ИмяЭлементаСодержащегоОбъект() Тогда ВызватьИсключение СтрШаблон(НСтр("ru = 'Ошибка чтения XML. Неверный формат файла. Ожидается начало элемента %1.'"), ИмяЭлементаСодержащегоОбъект()); КонецЕсли; Если НЕ ПотокЧтения.Прочитать() Тогда ВызватьИсключение НСтр("ru = 'Ошибка чтения XML. Обнаружено завершение файла.'"); КонецЕсли; Объект = СериализаторXDTO.ПрочитатьXML(ПотокЧтения); Возврат Объект; КонецФункции // Читает ОбъектXDTO из файла. // // Параметры: // ИмяФайла - Строка - полный путь к файлу. // ТипXDTO - ТипОбъектаXDTO - тип объекта XDTO. // // Возвращаемое значение: // ОбъектXDTO - прочитанный объект. // Функция ПрочитатьОбъектXDTOИзФайла(Знач ИмяФайла, Знач ТипXDTO) Экспорт ПотокЧтения = Новый ЧтениеXML(); ПотокЧтения.ОткрытьФайл(ИмяФайла); ПотокЧтения.ПерейтиКСодержимому(); Если ПотокЧтения.ТипУзла <> ТипУзлаXML.НачалоЭлемента Или ПотокЧтения.Имя <> ИмяЭлементаСодержащегоXDTOОбъект() Тогда ВызватьИсключение СтрШаблон(НСтр("ru = 'Ошибка чтения XML. Неверный формат файла. Ожидается начало элемента %1.'"), ИмяЭлементаСодержащегоXDTOОбъект()); КонецЕсли; Если НЕ ПотокЧтения.Прочитать() Тогда ВызватьИсключение НСтр("ru = 'Ошибка чтения XML. Обнаружено завершение файла.'"); КонецЕсли; ОбъектXDTO = ФабрикаXDTO.ПрочитатьXML(ПотокЧтения, ТипXDTO); ПотокЧтения.Закрыть(); Возврат ОбъектXDTO; КонецФункции // Возвращает префиксы для часто используемых пространств имен. // // Возвращаемое значение: // Соответствие из КлючИЗначение: // * Ключ - Строка - пространство имени. // * Значение - Строка - префикс. // Функция ПрефиксыПространствИмен() Экспорт Результат = Новый Соответствие(); Результат.Вставить("http://www.w3.org/2001/XMLSchema", "xs"); Результат.Вставить("http://www.w3.org/2001/XMLSchema-instance", "xsi"); Результат.Вставить("http://v8.1c.ru/8.1/data/core", "v8"); Результат.Вставить("http://v8.1c.ru/8.1/data/enterprise", "ns"); Результат.Вставить("http://v8.1c.ru/8.1/data/enterprise/current-config", "cc"); Результат.Вставить("http://www.1c.ru/1cFresh/Data/Dump/1.0.2.1", "dmp"); Возврат Новый ФиксированноеСоответствие(Результат); КонецФункции //////////////////////////////////////////////////////////////////////////////// // Прочее // Возвращает шаблон записи настроек. // // Возвращаемое значение: // Структура: // * Настройки - ХранилищеЗначения // * СериализацияЧерезХранилищеЗначения - Булево // * Представление - Строка // * Пользователь - Строка // * КлючОбъекта - Строка // * КлючНастроек - Строка Функция НоваяЗаписьНастроек() Экспорт ЗаписьНастроек = Новый Структура(); ЗаписьНастроек.Вставить("КлючНастроек", ""); ЗаписьНастроек.Вставить("КлючОбъекта", ""); ЗаписьНастроек.Вставить("Пользователь", ""); ЗаписьНастроек.Вставить("Представление", ""); ЗаписьНастроек.Вставить("СериализацияЧерезХранилищеЗначения", Ложь); ЗаписьНастроек.Вставить("Настройки", Новый ХранилищеЗначения(Неопределено)); Возврат ЗаписьНастроек; КонецФункции // Типы стандартных хранилищ настроек // // Возвращаемое значение: // ФиксированныйМассив из Строка Функция ТипыСтандартныхХранилищНастроек() Экспорт Результат = Новый Массив(); Результат.Добавить("ХранилищеОбщихНастроек"); Результат.Добавить("ХранилищеСистемныхНастроек"); Результат.Добавить("ХранилищеПользовательскихНастроекОтчетов"); Результат.Добавить("ХранилищеВариантовОтчетов"); Результат.Добавить("ХранилищеНастроекДанныхФорм"); Результат.Добавить("ХранилищеПользовательскихНастроекДинамическихСписков"); Возврат Новый ФиксированныйМассив(Результат); КонецФункции // Загрузка прервана // // Возвращаемое значение: // Булево Функция ЗагрузкаПрервана() Экспорт Возврат ИнформацияОПроцедуреЗагрузки() <> Неопределено; КонецФункции Процедура ЗафиксироватьСоответствиеСсылок(СоответствиеСсылок) Экспорт ИнформацияОПроцедуреЗагрузки = ИнформацияОПроцедуреЗагрузки(); ИнформацияОПроцедуреЗагрузки.СоответствиеСсылок = СоответствиеСсылок; ЗаписатьИнформациюОПроцедуреЗагрузки(ИнформацияОПроцедуреЗагрузки); КонецПроцедуры // Параметры: // ОбъектыМетаданных - Массив из ОбъектМетаданных // // Возвращаемое значение: // см. ВыгрузкаЗагрузкаДанныхСлужебный.СсылкиНаТипы // Функция СсылкиНаОбъектыМетаданных(ОбъектыМетаданных) Экспорт ВсеСсылочныеДанные = ВсеСсылочныеДанные(); Типы = Новый Массив; Для Каждого ОбъектМетаданных Из ОбъектыМетаданных Цикл Если ВсеСсылочныеДанные.Найти(ОбъектМетаданных) = Неопределено Тогда Продолжить; КонецЕсли; МенеджерОбъекта = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени( ОбъектМетаданных.ПолноеИмя()); Тип = ТипЗнч(МенеджерОбъекта.ПустаяСсылка()); Типы.Добавить(Тип); КонецЦикла; Возврат СсылкиНаТипы(Типы); КонецФункции // Параметры: // Типы - Массив из Тип // // Возвращаемое значение: // ФиксированноеСоответствие из КлючИЗначение: // * Ключ - Строка - имя объекта метаданных // * Значение - Массив Из Структура см. ВыгрузкаЗагрузкаДанныхСлужебный.СтруктураРеквизитов // Функция СсылкиНаТипы(Типы) Экспорт СписокМетаданных = Новый Соответствие; Для Каждого МетаданныеОбъекта Из ВсеКонстанты() Цикл ДобавитьКонстантуВСписокМетаданных(МетаданныеОбъекта, СписокМетаданных, Типы); КонецЦикла; Для Каждого МетаданныеОбъекта Из ВсеСсылочныеДанные() Цикл ДобавитьСсылочныйТипВСписокМетаданных(МетаданныеОбъекта, СписокМетаданных, Типы); КонецЦикла; Для Каждого МетаданныеОбъекта Из ВсеНаборыЗаписей() Цикл ДобавитьРегистрВТаблицуМетаданных(МетаданныеОбъекта, СписокМетаданных, Типы); КонецЦикла; Возврат Новый ФиксированноеСоответствие(СписокМетаданных); КонецФункции Функция ПрочитатьАрхив(ДанныеАрхива) Экспорт ТипДанныхАрхива = ТипЗнч(ДанныеАрхива); Если ТипДанныхАрхива = Тип("Структура") Тогда Если ДанныеАрхива.Свойство("ИдентификаторФайлаИсточника") Тогда ИмяФайлаПолногоАрхива = ВыгрузкаЗагрузкаОбластейДанных.ИмяФайлаПолногоАрхива(); АрхивКопии = ZipАрхивы.ПрочитатьАрхив(ДанныеАрхива.ИдентификаторФайлаИсточника); Архив = ZipАрхивы.ПрочитатьВложенныйНесжатыйАрхив(АрхивКопии, ИмяФайлаПолногоАрхива); Иначе Архив = ДанныеАрхива; КонецЕсли; ИначеЕсли ТипДанныхАрхива = Тип("УникальныйИдентификатор") Тогда Архив = ZipАрхивы.ПрочитатьАрхив(ДанныеАрхива); Иначе Архив = ZipАрхивы.ПрочитатьАрхив(ФайловыеПотоки.ОткрытьДляЧтения(ДанныеАрхива)); КонецЕсли; Возврат Архив; КонецФункции Процедура РаспаковатьФайлАрхива(Знач Архив, Знач ЦелевойКаталог, Знач Имя, Знач Путь = "") Экспорт Если Не ПустаяСтрока(Путь) Тогда Путь = Путь + "/"; КонецЕсли; ИмяФайлаВАрхиве = ?(ПустаяСтрока(Путь), Имя, Путь + Имя); Если Не ZipАрхивы.ИзвлечьФайл(Архив, ИмяФайлаВАрхиве, ЦелевойКаталог) Тогда ВызватьИсключение СтрШаблон(НСтр("ru = 'Файл %1 не найден'"), ИмяФайлаВАрхиве); КонецЕсли; КонецПроцедуры Функция ПолучитьИмяФайла(Знач ВидФайла, Знач Расширение = "xml") Экспорт Если ВидФайла = DumpInfo() Тогда ИмяФайла = DumpInfo(); ИначеЕсли ВидФайла = Digest() Тогда ИмяФайла = Digest(); ИначеЕсли ВидФайла = Extensions() Тогда ИмяФайла = Extensions(); ИначеЕсли ВидФайла = CustomExtensions() Тогда ИмяФайла = CustomExtensions(); ИначеЕсли ВидФайла = DumpWarnings() Тогда ИмяФайла = DumpWarnings(); ИначеЕсли ВидФайла = ApplicationTypes() Тогда ИмяФайла = ApplicationTypes(); ИначеЕсли ВидФайла = PackageContents() Тогда ИмяФайла = PackageContents(); ИначеЕсли ВидФайла = Users() Тогда ИмяФайла = Users(); ИначеЕсли ВидФайла = PredefinedDataDuplicates() Тогда ИмяФайла = PredefinedDataDuplicates(); Иначе ИмяФайла = Строка(Новый УникальныйИдентификатор); КонецЕсли; Для НомерСимвола = 1 По СтрДлина(Расширение) Цикл Символ = КодСимвола(Расширение, НомерСимвола); // Только цифры и латинские буквы, см. стандарт 542, п. 3.1 Если Не (Символ >= 48 И Символ <= 57) И Не (Символ >= 65 И Символ <= 90) И Не (Символ >= 97 И Символ <= 122) Тогда Расширение = "bin"; Прервать; КонецЕсли; КонецЦикла; Если Расширение <> "" Тогда ИмяФайла = ИмяФайла + "." + Расширение; КонецЕсли; Возврат ИмяФайла; КонецФункции Функция КоличествоЗагружаемыхОбъектовПоОбъектамМетаданных(Состав, ЗагружаемыеТипы, ДляТехническойПоддержки) Экспорт ТаблицаКоличестваЗагружаемыхОбъектов = НоваяТаблицаКоличестваОбрабатываемыхОбъектов(); ПолныеИменаЗагружаемыхТипов = ПолныеИменаТипов(ЗагружаемыеТипы); ПолныеИменаИсключаемыхТипов = ПолныеИменаТипов( ИсключаемыеТипы(ДляТехническойПоддержки)); ВидФайлаДанныеИБ = InfobaseData(); Для Каждого СтрокаСостава Из Состав Цикл ТипДанных = СтрокаСостава.ТипДанных; Если СтрокаСостава.ВидФайла <> ВидФайлаДанныеИБ Или ПолныеИменаЗагружаемыхТипов.Получить(ТипДанных) = Неопределено Или ПолныеИменаИсключаемыхТипов.Получить(ТипДанных) <> Неопределено Тогда Продолжить; КонецЕсли; СтрокаЗагружаемогоОбъекта = ТаблицаКоличестваЗагружаемыхОбъектов.Добавить(); СтрокаЗагружаемогоОбъекта.ПолноеИмя = ТипДанных; СтрокаЗагружаемогоОбъекта.ЧислоОбъектов = СтрокаСостава.ЧислоОбъектов; КонецЦикла; ТаблицаКоличестваЗагружаемыхОбъектов.Свернуть("ПолноеИмя", "ЧислоОбъектов"); Возврат ТаблицаКоличестваЗагружаемыхОбъектов; КонецФункции Функция КоличествоЗагружаемыхОбъектовРезервнойКопии(Архив, ТипРезервнойКопии, ДляТехническойПоддержки) Экспорт ВременныйКаталог = ПолучитьИмяВременногоФайла(); ИмяФайлаСодержимого = ПолучитьИмяФайла(PackageContents()); РаспаковатьФайлАрхива( ПрочитатьАрхив(Архив), ВременныйКаталог, ИмяФайлаСодержимого); СоставАрхива = СоставАрхива( ВременныйКаталог + ПолучитьРазделительПути() + ИмяФайлаСодержимого); УдалитьФайлы(ВременныйКаталог); ЗагружаемыеТипы = ЗагружаемыеТипы(ТипРезервнойКопии); КоличествоЗагружаемыхОбъектовПоОбъектамМетаданных = КоличествоЗагружаемыхОбъектовПоОбъектамМетаданных( СоставАрхива, ЗагружаемыеТипы, ДляТехническойПоддержки); Возврат КоличествоЗагружаемыхОбъектовПоОбъектамМетаданных.Итог("ЧислоОбъектов"); КонецФункции Функция КоличествоВыгружаемыхОбъектовПоОбъектамМетаданных(ВыгружаемыеТипы, ВыгружаемыеТипыОбщихДанных, ДляТехническойПоддержки) Экспорт ТаблицаКоличестваВыгружаемыхОбъектов = НоваяТаблицаКоличестваОбрабатываемыхОбъектов(); ШаблонПодзапроса = "ВЫБРАТЬ | ""%1"" КАК ПолноеИмя, | %2 КАК ЧислоОбъектов |ИЗ | %3"; Подзапросы = Новый Массив; УникальныеВыгружаемыеТипы = Новый Массив; ОбщегоНазначенияКлиентСервер.ДополнитьМассив(УникальныеВыгружаемыеТипы, ВыгружаемыеТипы); ОбщегоНазначенияКлиентСервер.ДополнитьМассив(УникальныеВыгружаемыеТипы, ВыгружаемыеТипыОбщихДанных); УникальныеВыгружаемыеТипы = ОбщегоНазначенияКлиентСервер.СвернутьМассив(УникальныеВыгружаемыеТипы); ПолныеИменаИсключаемыхТипов = ПолныеИменаТипов( ИсключаемыеТипы(ДляТехническойПоддержки)); Для Каждого ВыгружаемыйТип Из УникальныеВыгружаемыеТипы Цикл ПолноеИмяВыгружаемогоТипа = ВыгружаемыйТип.ПолноеИмя(); Если ПолныеИменаИсключаемыхТипов.Получить(ПолноеИмяВыгружаемогоТипа) <> Неопределено Тогда Продолжить; КонецЕсли; Если ОбщегоНазначенияБТС.ЭтоКонстанта(ВыгружаемыйТип) Тогда СтрокаКонстанты = ТаблицаКоличестваВыгружаемыхОбъектов.Добавить(); СтрокаКонстанты.ПолноеИмя = ПолноеИмяВыгружаемогоТипа; СтрокаКонстанты.ЧислоОбъектов = 1; Продолжить; КонецЕсли; Если ОбщегоНазначенияБТС.ЭтоСсылочныеДанные(ВыгружаемыйТип) Или ОбщегоНазначенияБТС.ЭтоНезависимыйНаборЗаписей(ВыгружаемыйТип) Тогда ВыражениеРасчетаКоличества = "Количество(*)"; ИмяТаблицы = ВыгружаемыйТип.ПолноеИмя(); ИначеЕсли ОбщегоНазначенияБТС.ЭтоНаборЗаписей(ВыгружаемыйТип) Тогда Если ОбщегоНазначенияБТС.ЭтоНаборЗаписейПерерасчета(ВыгружаемыйТип) Тогда ВыражениеРасчетаКоличества = "Количество(Различные ОбъектПерерасчета)"; Подстроки = СтрРазделить(ВыгружаемыйТип.ПолноеИмя(), "."); ИмяТаблицы = Подстроки[0] + "." + Подстроки[1] + "." + Подстроки[3]; Иначе ВыражениеРасчетаКоличества = "Количество(Различные Регистратор)"; ИмяТаблицы = ВыгружаемыйТип.ПолноеИмя(); КонецЕсли; Иначе ВызватьИсключение СтрШаблон(НСтр("ru = 'Объект метаданных не поддерживается: %1'"), ВыгружаемыйТип.ПолноеИмя()); КонецЕсли; Подзапросы.Добавить( СтрШаблон(ШаблонПодзапроса, ПолноеИмяВыгружаемогоТипа, ВыражениеРасчетаКоличества, ИмяТаблицы)); Если Подзапросы.Количество() >= 100 Тогда ДополнитьТаблицуКоличестваОбрабатываемыхОбъектов( ТаблицаКоличестваВыгружаемыхОбъектов, ТаблицаКоличестваВыгружаемыхОбъектовПоПодзапросам(Подзапросы)); Подзапросы.Очистить(); КонецЕсли; КонецЦикла; Если ЗначениеЗаполнено(Подзапросы) Тогда ДополнитьТаблицуКоличестваОбрабатываемыхОбъектов( ТаблицаКоличестваВыгружаемыхОбъектов, ТаблицаКоличестваВыгружаемыхОбъектовПоПодзапросам(Подзапросы)); КонецЕсли; Возврат ТаблицаКоличестваВыгружаемыхОбъектов; КонецФункции Функция ЭтоДифференциальнаяРезервнаяКопия(ПараметрыЗагрузки) Экспорт Возврат ТипРезервнойКопии(ПараметрыЗагрузки) = ТипРезервнойКопииДифференциальная(); КонецФункции Функция ЭтоПолнаяРезервнаяКопия(ПараметрыЗагрузки) Экспорт Возврат ТипРезервнойКопии(ПараметрыЗагрузки) = ТипРезервнойКопииПолная(); КонецФункции Функция ТипРезервнойКопииДифференциальная() Экспорт Возврат "Дифференциальная"; КонецФункции Функция ТипРезервнойКопииПолная() Экспорт Возврат "Полная"; КонецФункции Функция ТипРезервнойКопииОбычная() Экспорт Возврат "Обычная"; КонецФункции // Получить данные файла из состава архива. // // Параметры: // Состав - см. СоставАрхива // ПараметрыПоиска - см. НовыеПараметрыПоискаФайлаИзСоставаАрхива // // Возвращаемое значение: // СтрокаТаблицыЗначений - параметры файла: // * Имя - Строка // * Каталог - Строка // * Размер - Число // * ВидФайла - Строка // * ЧислоОбъектов - Число // * ТипДанных - Строка Функция ПолучитьПараметрыФайлаИзСоставаАрхива(Состав, ПараметрыПоиска) Экспорт ПараметрыОтбора = Новый Структура(); Для Каждого ПараметрПоиска Из ПараметрыПоиска Цикл Если ЗначениеЗаполнено(ПараметрПоиска.Значение) Тогда ПараметрыОтбора.Вставить(ПараметрПоиска.Ключ, ПараметрПоиска.Значение); КонецЕсли; КонецЦикла; Если Не ЗначениеЗаполнено(ПараметрыОтбора) Тогда ВызватьИсключение НСтр("ru = 'Неверные параметры поиска файла состава архива'"); КонецЕсли; НайденныеСтроки = Состав.НайтиСтроки(ПараметрыОтбора); КоличествоФайлов = НайденныеСтроки.Количество(); Если КоличествоФайлов = 0 Тогда ВызватьИсключение НСтр("ru = 'В составе архива не найден искомый файл'"); ИначеЕсли КоличествоФайлов > 1 Тогда ВызватьИсключение НСтр("ru = 'В составе архива найдено несколько искомых файлов'"); КонецЕсли; ПараметрыФайла = НайденныеСтроки[0]; // СтрокаТаблицыЗначений Возврат ПараметрыФайла; КонецФункции // Состав архива. // // Параметры: // ПутьКФайлуСостава - Строка - Путь к файлу состава // // Возвращаемое значение: // см. НовыйСостав Функция СоставАрхива(ПутьКФайлуСостава) Экспорт ПотокЧтения = Новый ЧтениеXML(); ПотокЧтения.ОткрытьФайл(ПутьКФайлуСостава); ПотокЧтения.ПерейтиКСодержимому(); Если ПотокЧтения.ТипУзла <> ТипУзлаXML.НачалоЭлемента Или ПотокЧтения.Имя <> "Data" Тогда ВызватьИсключение СтрШаблон(НСтр("ru = 'Ошибка чтения XML. Неверный формат файла. Ожидается начало элемента %1.'"), "Data"); КонецЕсли; Если НЕ ПотокЧтения.Прочитать() Тогда ВызватьИсключение НСтр("ru = 'Ошибка чтения XML. Обнаружено завершение файла.'"); КонецЕсли; СоставАрхива = НовыйСостав(); Пока ПотокЧтения.ТипУзла = ТипУзлаXML.НачалоЭлемента Цикл ЭлементКонтейнера = ФабрикаXDTO.ПрочитатьXML( ПотокЧтения, ФабрикаXDTO.Тип("http://www.1c.ru/1cFresh/Data/Dump/1.0.2.1", "File")); Файл = СоставАрхива.Добавить(); Файл.Имя = ЭлементКонтейнера.Name; Файл.Каталог = ЭлементКонтейнера.Directory; Файл.Размер = ЭлементКонтейнера.Size; Файл.ВидФайла = ЭлементКонтейнера.Type; Файл.ЧислоОбъектов = ЭлементКонтейнера.Count; Файл.ТипДанных = ЭлементКонтейнера.DataType; КонецЦикла; ПотокЧтения.Закрыть(); Возврат СоставАрхива; КонецФункции // Новый состав. // // Возвращаемое значение: // ТаблицаЗначений - Новый состав: // * Имя - Строка // * Каталог - Строка // * Размер - Число // * ВидФайла - Строка // * ЧислоОбъектов - Число // * ТипДанных - Строка Функция НовыйСостав() Экспорт ОписаниеТиповСтрока = Новый ОписаниеТипов("Строка"); ОписаниеТиповЧисло = Новый ОписаниеТипов("Число"); НовыйСостав = Новый ТаблицаЗначений; НовыйСостав.Колонки.Добавить("Имя", ОписаниеТиповСтрока); НовыйСостав.Колонки.Добавить("Каталог", ОписаниеТиповСтрока); НовыйСостав.Колонки.Добавить("Размер", ОписаниеТиповЧисло); НовыйСостав.Колонки.Добавить("ВидФайла", ОписаниеТиповСтрока); НовыйСостав.Колонки.Добавить("ЧислоОбъектов", ОписаниеТиповЧисло); НовыйСостав.Колонки.Добавить("ТипДанных", ОписаниеТиповСтрока); Возврат НовыйСостав; КонецФункции // Новые параметры поиска файла из состава архива. // // Возвращаемое значение: // Структура - Новые параметры поиска файла из состава архива: // * Имя - Строка // * Каталог - Строка // * ВидФайла - Строка // * ТипДанных - Строка Функция НовыеПараметрыПоискаФайлаИзСоставаАрхива() Экспорт ПараметрыПоиска = Новый Структура(); ПараметрыПоиска.Вставить("Имя", ""); ПараметрыПоиска.Вставить("Каталог", ""); ПараметрыПоиска.Вставить("ВидФайла", ""); ПараметрыПоиска.Вставить("ТипДанных", ""); Возврат ПараметрыПоиска; КонецФункции Функция ЗагружаемыеТипы(ТипРезервнойКопии) Экспорт ЗагружаемыеТипы = Новый Массив(); ОбщегоНазначенияКлиентСервер.ДополнитьМассив( ЗагружаемыеТипы, ВыгрузкаЗагрузкаОбластейДанных.ПолучитьТипыМоделиДанныхОбласти()); Если Не РаботаВМоделиСервисаПовтИсп.РазделениеВключено() Тогда ОбщегоНазначенияКлиентСервер.ДополнитьМассив( ЗагружаемыеТипы, ВыгрузкаЗагрузкаДанныхСлужебныйСобытия.ПолучитьТипыОбщихДанныхПоддерживающиеСопоставлениеСсылокПриЗагрузке(), Истина); КонецЕсли; Если ТипРезервнойКопии = ТипРезервнойКопииПолная() Тогда Для ОбратныйИндекс = 1 - ЗагружаемыеТипы.Количество() По 0 Цикл ОбъектМетаданных = ЗагружаемыеТипы[-ОбратныйИндекс]; Если Метаданные.ПланыОбмена.Содержит(ОбъектМетаданных) Или ОбъектМетаданных.РасширениеКонфигурации() <> Неопределено И Не Метаданные.ПланыОбмена.МиграцияПриложений.Состав.Содержит(ОбъектМетаданных) Тогда ЗагружаемыеТипы.Удалить(-ОбратныйИндекс); КонецЕсли; КонецЦикла; КонецЕсли; Возврат ЗагружаемыеТипы; КонецФункции Функция ИсключаемыеТипы(ДляТехническойПоддержки) Экспорт ИсключаемыеТипы = Новый Массив; ОбщегоНазначенияКлиентСервер.ДополнитьМассив( ИсключаемыеТипы, ВыгрузкаЗагрузкаДанныхСлужебныйСобытия.ПолучитьТипыИсключаемыеИзВыгрузкиЗагрузки()); Если ДляТехническойПоддержки Тогда ОбщегоНазначенияКлиентСервер.ДополнитьМассив( ИсключаемыеТипы, ВыгрузкаОбластейДанныхДляТехническойПоддержкиПовтИсп.МетаданныеИсключаемыеИзВыгрузкиВРежимеДляТехническойПоддержки(), Истина); КонецЕсли; Возврат ИсключаемыеТипы; КонецФункции Функция ПолныеИменаТипов(Типы) Экспорт ПолныеИменаТипов = Новый Соответствие(); Для Каждого Тип Из Типы Цикл ПолныеИменаТипов.Вставить(Тип.ПолноеИмя(), Истина); КонецЦикла; Возврат ПолныеИменаТипов; КонецФункции Функция ВыгрузкаВРежимеДляТехническойПоддержки(ПутьКФайлуДайджеста) Экспорт ЧтениеXML = Новый ЧтениеXML; ЧтениеXML.ОткрытьФайл(ПутьКФайлуДайджеста); ПостроительDOM = Новый ПостроительDOM; ДайджестВыгрузки = ПостроительDOM.Прочитать(ЧтениеXML); ЧтениеXML.Закрыть(); Если ДайджестВыгрузки <> Неопределено Тогда СписокЭлементов = ДайджестВыгрузки.ПолучитьЭлементыПоИмени("DataDumpType"); ВыгрузкаДляТехническойПоддержки = ЗначениеЗаполнено(СписокЭлементов) И СписокЭлементов[0].ТекстовоеСодержимое = "TechnicalSupport"; Иначе ВыгрузкаДляТехническойПоддержки = Ложь; КонецЕсли; Возврат ВыгрузкаДляТехническойПоддержки; КонецФункции // Возвращает СериализаторXDTO с аннотацией типов. // // Возвращаемое значение: // СериализаторXDTO - сериализатор. // Функция СериализаторXDTOСАннотациейТипов() Экспорт ДвоичныеДанныеСхемы = СхемаКонфигурации.ДвоичныеДанныеСхемы(Истина, Истина); СхемаXML = СхемаXML(ДвоичныеДанныеСхемы); Фабрика = ФабрикаПоСхеме(СхемаXML); Возврат Новый СериализаторXDTO(Фабрика); КонецФункции // Наличие обработчиков по объектам метаданных. // // Параметры: // ТекущиеОбработчики - ТаблицаЗначений - Текущие обработчики // ИменаКолонокОбработчиков - Массив из Строка - Имена колонок обработчиков // // Возвращаемое значение: // Соответствие из ОбъектМетаданных: Структура - Наличие обработчиков по объектам метаданных Функция НаличиеОбработчиковПоОбъектамМетаданных(ТекущиеОбработчики, ИменаКолонокОбработчиков) Экспорт НаличиеОбработчиков = Новый Соответствие(); Для Каждого СтрокаТаблицы Из ТекущиеОбработчики Цикл НаличиеОбработчиковОбъекта = НаличиеОбработчиков.Получить(СтрокаТаблицы.ОбъектМетаданных); Если НаличиеОбработчиковОбъекта = Неопределено Тогда НаличиеОбработчиковОбъекта = НовыеДанныеНаличияОбработчиковПоОбъектуМетаданных(ИменаКолонокОбработчиков); НаличиеОбработчиков.Вставить(СтрокаТаблицы.ОбъектМетаданных, НаличиеОбработчиковОбъекта); КонецЕсли; Для Каждого ИмяОбработчика Из ИменаКолонокОбработчиков Цикл НаличиеОбработчиковОбъекта[ИмяОбработчика] = Макс( НаличиеОбработчиковОбъекта[ИмяОбработчика], СтрокаТаблицы[ИмяОбработчика]); КонецЦикла; КонецЦикла; Возврат НаличиеОбработчиков; КонецФункции // Новые данные наличия обработчиков по объекту метаданных. // // Параметры: // ИменаКолонокОбработчиков - Массив из Строка - Имена колонок обработчиков // // Возвращаемое значение: // Структура - Новые данные наличия обработчиков по объекту метаданных Функция НовыеДанныеНаличияОбработчиковПоОбъектуМетаданных(ИменаКолонокОбработчиков) Экспорт НаличиеОбработчиков = Новый Структура(); Для Каждого ИмяКолонки Из ИменаКолонокОбработчиков Цикл НаличиеОбработчиков.Вставить(ИмяКолонки, Ложь); КонецЦикла; Возврат НаличиеОбработчиков; КонецФункции Процедура ЗаполнитьУстановленныеРасширения1СПлюс(Расширения1СПлюс) Экспорт ИмяПодсистемы = "ПлюсСервис"; Если ОбщегоНазначения.ПодсистемаСуществует(ИмяПодсистемы) Тогда МодульПлюсСервис = ОбщегоНазначения.ОбщийМодуль(ИмяПодсистемы); Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(МодульПлюсСервис.ВерсияБиблиотеки(), "1.0.0.4") >= 0 Тогда МодульПлюсСервис.ЗаполнитьУстановленныеРасширения(Расширения1СПлюс); КонецЕсли; КонецЕсли; КонецПроцедуры Процедура ВосстановитьРасширения1СПлюсИзМС(Знач ДанныеРасширений) Экспорт Модуль1СПлюс = ПолучитьМодуль1СПлюс(); Если Не ДанныеРасширений.Свойство("Расширения1СПлюс") Или Модуль1СПлюс = Неопределено Тогда Возврат; КонецЕсли; Для Каждого Расширение Из ДанныеРасширений.Расширения1СПлюс Цикл Попытка ИмяФайлаРасширения = РаботаВМоделиСервиса.ПолучитьФайлИзХранилищаМенеджераСервиса( Новый УникальныйИдентификатор(Расширение.PathToData)); Исключение ТекстОшибки = СтрШаблон(НСтр("ru = 'Не удалось получить файл расширения |%1 |%2'"), , ТехнологияСервиса.ПодробныйТекстОшибки(ИнформацияОбОшибке())); ИмяСобытияЖР = НСтр("ru = 'Расширения 1С:Плюс.Ошибка хранилища МС'", ОбщегоНазначения.КодОсновногоЯзыка()); ЗаписьЖурналаРегистрации(ИмяСобытияЖР, УровеньЖурналаРегистрации.Ошибка, , , ТекстОшибки); ВызватьИсключение ТекстОшибки; КонецПопытки; Расширение.PathToData = ИмяФайлаРасширения; КонецЦикла; Модуль1СПлюс.ВосстановитьРасширенияИзМС(ДанныеРасширений.Расширения1СПлюс); КонецПроцедуры Функция ПроверитьРасширения1СПлюс() Экспорт Модуль1СПлюс = ПолучитьМодуль1СПлюс(); Если Модуль1СПлюс <> Неопределено Тогда Возврат Модуль1СПлюс.СписокИзмененныхРасширений(); КонецЕсли; КонецФункции // Параметры: // ПараметрыВыгрузкиЗагрузки - Структура // // Возвращаемое значение: // Число Функция НомерКлиентскогоСеансаИзПараметров(ПараметрыВыгрузкиЗагрузки) Экспорт НомерКлиентскогоСеанса = 0; Если ПараметрыВыгрузкиЗагрузки.Свойство("НомерКлиентскогоСеанса") И ТипЗнч(ПараметрыВыгрузкиЗагрузки.НомерКлиентскогоСеанса) = Тип("Число") И ЗначениеЗаполнено(ПараметрыВыгрузкиЗагрузки.НомерКлиентскогоСеанса) Тогда НомерКлиентскогоСеанса = ПараметрыВыгрузкиЗагрузки.НомерКлиентскогоСеанса; КонецЕсли; Возврат НомерКлиентскогоСеанса; КонецФункции #Область ПараллельнаяВыгрузкаЗагрузка // Параметры параллельной загрузки данных. // // Возвращаемое значение: // Структура - Параметры параллельной загрузки данных: // * ДоступноИспользование - Булево - // * КоличествоПотоков - Число - Функция ПараметрыПараллельнойВыгрузкиЗагрузкиДанных() Экспорт ДоступноИспользование = Не ОбщегоНазначения.РазделениеВключено() И Не ОбщегоНазначения.ИнформационнаяБазаФайловая(); Параметры = Новый Структура(); Параметры.Вставить("ДоступноИспользование", ДоступноИспользование); Параметры.Вставить("КоличествоПотоков", 4); Возврат Параметры; КонецФункции // Использовать многопоточность. // // Параметры: // ПараметрыВыгрузкиЗагрузки - Структура // // Возвращаемое значение: // Булево - Использовать многопоточность Функция ИспользоватьМногопоточность(ПараметрыВыгрузкиЗагрузки) Экспорт Если РаботаВМоделиСервиса.РазделениеВключено() Тогда Возврат ПолучитьФункциональнуюОпцию("ИспользоватьПараллельнуюВыгрузкуЗагрузкуДанных"); Иначе КоличествоПотоков = 0; Если ПараметрыВыгрузкиЗагрузки.Свойство("КоличествоПотоков") Тогда КоличествоПотоков = ПараметрыВыгрузкиЗагрузки.КоличествоПотоков; КонецЕсли; Возврат ЗначениеЗаполнено(КоличествоПотоков) И КоличествоПотоков > 1; КонецЕсли; КонецФункции // Запускает потоки выгрузки загрузки данных. // // Параметры: // ПараметрыПотоков - см. НовыеПараметрыПотоковВыгрузкиЗагрузкиДанных // Контейнер - ОбработкаОбъект.ВыгрузкаЗагрузкаДанныхМенеджерКонтейнера // // Возвращаемое значение: // Массив из ФоновоеЗадание - Запущенные фоновые задания Функция ЗапуститьПотокиВыгрузкиЗагрузкиДанных(ПараметрыПотоков, Контейнер) Экспорт Если Не ЗначениеЗаполнено(ПараметрыПотоков.КоличествоПотоков) Тогда ВызватьИсключение НСтр("ru = 'Некорректные параметры потоков, не указано количество потоков.'"); КонецЕсли; Если ПараметрыПотоков.ЭтоВыгрузка Тогда НаименованиеЗадания = НСтр("ru = 'Выгрузка данных информационной базы'"); ИначеЕсли ПараметрыПотоков.ЭтоЗагрузка Тогда НаименованиеЗадания = НСтр("ru = 'Загрузка данных информационной базы'"); Иначе ВызватьИсключение НСтр("ru = 'Некорректные параметры потоков, не указан признак выгрузки или загрузки.'"); КонецЕсли; ПараметрыЗадания = Новый Массив(); ПараметрыЗадания.Добавить(ПараметрыПотоков); Задания = Новый Массив(); Для НомерПотока = 1 По ПараметрыПотоков.КоличествоПотоков Цикл Задание = ФоновыеЗадания.Выполнить( "ВыгрузкаЗагрузкаДанныхСлужебный.ВыгрузкаЗагрузкаДанныхИнформационнойБазыВПотоке", ПараметрыЗадания, КлючЗаданияВыгрузкиЗагрузкиДанных(Контейнер), НаименованиеЗадания); Задания.Добавить(Задание); РегистрыСведений.ПотокиВыгрузкиЗагрузкиДанных.ДобавитьЗапись(Задание, Контейнер, ПараметрыПотоков.ВидПотоков); Если НомерПотока < ПараметрыПотоков.КоличествоПотоков Тогда // Разносим старт заданий по времени ОбщегоНазначенияБТС.Пауза(1); КонецЕсли; КонецЦикла; Возврат Задания; КонецФункции Функция ИмяМетодаВыгрузкиЗагрузкиДанныхВПотоке() Экспорт Возврат "ВыгрузкаЗагрузкаДанныхСлужебный.ВыгрузкаЗагрузкаДанныхИнформационнойБазыВПотоке"; КонецФункции // Имя метода сообщения потока завершение выгрузки. // // Возвращаемое значение: // Строка - Имя метода сообщения потока завершение выгрузки Функция ИмяМетодаСообщенияПотока_ЗавершениеВыгрузки() Экспорт Возврат "ЗавершениеВыгрузки"; КонецФункции // Ожидает выгрузку загрузку данных в потоках. // // Параметры: // Задания - Массив из ФоновоеЗадание - Запущенные задания // ПараметрыПроцесса - Структура - Для загрузки данных см. обработку ВыгрузкаЗагрузкаДанныхМенеджерЗагрузкиДанныхИнформационнойБазы.НовыеПараметрыПроцессаЗагрузкиДанныхИнформационнойБазы // Для выгрузки данных см. обработку ВыгрузкаЗагрузкаДанныхМенеджерВыгрузкиДанныхИнформационнойБазы.НовыеПараметрыПроцессаВыгрузкиДанныхИнформационнойБазы Процедура ОжидатьВыгрузкуЗагрузкуДанныхВПотоках(Задания, ПараметрыПроцесса) Экспорт УправляющееЗадание = ПолучитьЗаданиеПараллельнойВыгрузкиЗагрузкиДанных(); ИдентификаторЗадания = ?(УправляющееЗадание = Неопределено, ОбщегоНазначенияКлиентСервер.ПустойУникальныйИдентификатор(), УправляющееЗадание.УникальныйИдентификатор); Таймаут = 5; // сек. Контейнер = ПараметрыПроцесса.Контейнер; // ОбработкаОбъект.ВыгрузкаЗагрузкаДанныхМенеджерКонтейнера ИдентификаторПроцесса = Контейнер.ИдентификаторПроцесса(); Пока Истина Цикл ЗапуститьДополнительныеПотокиВыгрузкиЗагрузкиДанных(Задания, ПараметрыПроцесса); Задания = ФоновыеЗадания.ОжидатьЗавершенияВыполнения(Задания, Таймаут); НомерЗадания = Задания.Количество(); Ошибки = Новый Массив(); ЗавершенныеЗадания = Новый Массив(); ТаблицаСообщений = НоваяТаблицаСообщенийПотоков(); Пока НомерЗадания > 0 Цикл НомерЗадания = НомерЗадания - 1; Задание = Задания[НомерЗадания]; Если Задание.Состояние <> СостояниеФоновогоЗадания.Активно Тогда Задания.Удалить(НомерЗадания); КонецЕсли; ПолучитьСообщенияПотока(ТаблицаСообщений, Задание, ИдентификаторПроцесса); ТекстОшибки = Неопределено; Если Задание.Состояние = СостояниеФоновогоЗадания.ЗавершеноАварийно Тогда ИнформацияОбОшибке = ?(Задание.ИнформацияОбОшибке = Неопределено, НСтр("ru = 'Отсутствует информация об ошибке.'"), ОбработкаОшибок.ПодробноеПредставлениеОшибки(Задание.ИнформацияОбОшибке)); ТекстОшибки = СтрШаблон( НСтр("ru = 'Поток %1, фоновое задание завершилось аварийно. |%2'"), НомерПотокаИзКлючаЗадания(Задание.Ключ), ИнформацияОбОшибке); ИначеЕсли Задание.Состояние = СостояниеФоновогоЗадания.Отменено Тогда ТекстОшибки = СтрШаблон( НСтр("ru = 'Поток %1, фоновое задание отменено.'"), НомерПотокаИзКлючаЗадания(Задание.Ключ)); КонецЕсли; Если ЗначениеЗаполнено(ТекстОшибки) Тогда Ошибки.Добавить(ТекстОшибки); РегистрыСведений.ПотокиВыгрузкиЗагрузкиДанных.УдалитьЗапись(Задание.УникальныйИдентификатор); ИначеЕсли ЗаданиеПотокаЗавершено(Задание, ТаблицаСообщений) Тогда ЗавершенныеЗадания.Добавить(НомерЗадания); КонецЕсли; КонецЦикла; Если ЗначениеЗаполнено(Ошибки) Тогда ЗавершенныеЗадания.Очистить(); Для Каждого Задание Из Задания Цикл ТекстОшибки = СтрШаблон( НСтр("ru = 'Поток %1, фоновое задание прервано из-за ошибки в другом потоке.'"), НомерПотокаИзКлючаЗадания(Задание.Ключ)); Задание.Отменить(); Ошибки.Добавить(ТекстОшибки); ПолучитьСообщенияПотока(ТаблицаСообщений, Задание, ИдентификаторПроцесса); РегистрыСведений.ПотокиВыгрузкиЗагрузкиДанных.УдалитьЗапись(Задание); КонецЦикла; ОбработатьСообщенияПотоков(ТаблицаСообщений, Контейнер); РегистрыСведений.ПотокиВыгрузкиЗагрузкиДанных.УдалитьЗапись(ИдентификаторЗадания); РазделительОшибок = Символы.ПС + Символы.ПС; ТекстОшибки = СтрСоединить(Ошибки, РазделительОшибок); ВызватьИсключение ТекстОшибки; КонецЕсли; ОбработатьСообщенияПотоков(ТаблицаСообщений, Контейнер); Для Каждого НомерЗадания Из ЗавершенныеЗадания Цикл Задание = Задания[НомерЗадания]; Задания.Удалить(НомерЗадания); Задание.Отменить(); КонецЦикла; Если Не ЗначениеЗаполнено(Задания) Тогда Прервать; КонецЕсли; КонецЦикла; РегистрыСведений.ПотокиВыгрузкиЗагрузкиДанных.УдалитьЗапись(ИдентификаторЗадания); КонецПроцедуры // Новые параметры потоков выгрузки загрузки данных. // // Возвращаемое значение: // Структура - Новые параметры потоков выгрузки загрузки данных: // * ЭтоВыгрузка - Булево - // * ЭтоЗагрузка - Булево - // * КоличествоПотоков - Число - // * ВидПотоков - ПеречислениеСсылка.ВидыПотоковВыгрузкиЗагрузкиДанных - // * Параметры - Структура - Функция НовыеПараметрыПотоковВыгрузкиЗагрузкиДанных() Экспорт ПараметрыПотока = Новый Структура(); ПараметрыПотока.Вставить("ЭтоВыгрузка", Ложь); ПараметрыПотока.Вставить("ЭтоЗагрузка", Ложь); ПараметрыПотока.Вставить("КоличествоПотоков", 0); ПараметрыПотока.Вставить("ВидПотоков", Перечисления.ВидыПотоковВыгрузкиЗагрузкиДанных.Дополнительный); ПараметрыПотока.Вставить("Параметры", Новый Структура()); Возврат ПараметрыПотока; КонецФункции // Выгрузка загрузка данных информационной базы в потоке. // // Параметры: // ПараметрыПотока - см. ВыгрузкаЗагрузкаДанныхСлужебный.ВыгрузкаЗагрузкаДанныхИнформационнойБазыВПотоке Процедура ВыгрузкаЗагрузкаДанныхИнформационнойБазыВПотоке(ПараметрыПотока) Экспорт УстановитьОтключениеБезопасногоРежима(Истина); УстановитьПривилегированныйРежим(Истина); Если ПараметрыПотока.ЭтоВыгрузка Тогда Обработки.ВыгрузкаЗагрузкаДанныхМенеджерВыгрузкиДанныхИнформационнойБазы.ВыгрузитьДанныеИнформационнойБазыВПотоке( ПараметрыПотока.Параметры); ИначеЕсли ПараметрыПотока.ЭтоЗагрузка Тогда МодульУправлениеДоступом = Неопределено; Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.УправлениеДоступом") Тогда МодульУправлениеДоступом = ОбщегоНазначения.ОбщийМодуль("УправлениеДоступом"); МодульУправлениеДоступом.ОтключитьОбновлениеКлючейДоступа(Истина, Ложь); КонецЕсли; Попытка Обработки.ВыгрузкаЗагрузкаДанныхМенеджерЗагрузкиДанныхИнформационнойБазы.ЗагрузитьДанныеИнформационнойБазыВПотоке( ПараметрыПотока.Параметры); Если МодульУправлениеДоступом <> Неопределено Тогда МодульУправлениеДоступом.ОтключитьОбновлениеКлючейДоступа(Ложь); КонецЕсли; Исключение Если МодульУправлениеДоступом <> Неопределено Тогда МодульУправлениеДоступом.ОтключитьОбновлениеКлючейДоступа(Ложь); КонецЕсли; ВызватьИсключение; КонецПопытки; Иначе ВызватьИсключение НСтр("ru = 'Некорректные параметры потока.'"); КонецЕсли; КонецПроцедуры // Отправить сообщение в родительский поток. // // Параметры: // Контейнер - ОбработкаОбъект.ВыгрузкаЗагрузкаДанныхМенеджерКонтейнера - Текущий контейнер // ИмяМетода - Строка - Имя метода // ДанныеСообщения - Структура - Данные сообщения Процедура ОтправитьСообщениеВРодительскийПоток(Контейнер, ИмяМетода, ДанныеСообщения) Экспорт Если Не Контейнер.КлиентскийСеансСуществует() Тогда Контейнер.ПрерватьПроцессПриОтсутствииКлиентскогоСеанса(); КонецЕсли; СообщениеПотока = Новый Структура(); СообщениеПотока.Вставить("ДатаОтправки", ТекущаяУниверсальнаяДатаВМиллисекундах()); СообщениеПотока.Вставить("НомерСообщения", Контейнер.СледующийНомерСообщенияВПотоке()); СообщениеПотока.Вставить("ИмяМетода", ИмяМетода); СообщениеПотока.Вставить("ДанныеСообщения", ДанныеСообщения); ЗаписьДанныхСообщения = Новый ЗаписьJSON(); ЗаписьДанныхСообщения.УстановитьСтроку(); ЗаписатьJSON(ЗаписьДанныхСообщения, СообщениеПотока); Сообщение = Новый СообщениеПользователю(); Сообщение.ИдентификаторНазначения = Контейнер.ИдентификаторПроцесса(); Сообщение.Текст = ЗаписьДанныхСообщения.Закрыть(); Сообщение.Сообщить(); КонецПроцедуры // Получить задание параллельной выгрузки загрузки данных. // // Возвращаемое значение: // ФоновоеЗадание, Неопределено - Функция ПолучитьЗаданиеПараллельнойВыгрузкиЗагрузкиДанных() Экспорт Задание = ПолучитьТекущийСеансИнформационнойБазы().ПолучитьФоновоеЗадание(); Если Задание = Неопределено И РаботаВМоделиСервиса.РазделениеВключено() Тогда ВызватьИсключение НСтр( "ru = 'Параллельная выгрузка\загрузка данных может выполняться только в фоновом задании.'"); КонецЕсли; Возврат Задание; КонецФункции // Вид потока параллельной выгрузки загрузки данных. // // Параметры: // Контейнер - ОбработкаОбъект.ВыгрузкаЗагрузкаДанныхМенеджерКонтейнера // // Возвращаемое значение: // ПеречислениеСсылка.ВидыПотоковВыгрузкиЗагрузкиДанных Функция ВидПотокаПараллельнойВыгрузкиЗагрузкиДанных(Контейнер) Экспорт Если РаботаВМоделиСервиса.РазделениеВключено() И Контейнер.КоличествоПотоков() = 1 Тогда Возврат Перечисления.ВидыПотоковВыгрузкиЗагрузкиДанных.Основной; Иначе Возврат Перечисления.ВидыПотоковВыгрузкиЗагрузкиДанных.Дополнительный; КонецЕсли; КонецФункции // Проверить параметры параллельной выгрузки загрузки данных. // // Параметры: // ПараметрыВыгрузкиЗагрузки - Структура // ЭтоЗагрузка - Булево Процедура ПроверитьПараметрыПараллельнойВыгрузкиЗагрузкиДанных(ПараметрыВыгрузкиЗагрузки, ЭтоЗагрузка) Экспорт Если Не ПараметрыВыгрузкиЗагрузки.Свойство("КоличествоПотоков") Тогда ПараметрыВыгрузкиЗагрузки.Вставить("КоличествоПотоков", 0); КонецЕсли; Если ПараметрыВыгрузкиЗагрузки.КоличествоПотоков < 1 Тогда ПараметрыВыгрузкиЗагрузки.КоличествоПотоков = 1; КонецЕсли; Если Не (ПараметрыВыгрузкиЗагрузки.Свойство("ВидЗадания") И ЗначениеЗаполнено(ПараметрыВыгрузкиЗагрузки.ВидЗадания)) Тогда ВидЗадания = ?(ЭтоЗагрузка, Перечисления.ВидыЗаданийВыгрузкиЗагрузкиДанных.ПрочаяЗагрузкаДанных, Перечисления.ВидыЗаданийВыгрузкиЗагрузкиДанных.ПрочаяВыгрузкаДанных); ПараметрыВыгрузкиЗагрузки.Вставить("ВидЗадания", ВидЗадания); КонецЕсли; КонецПроцедуры #КонецОбласти #КонецОбласти #Область СлужебныеПроцедурыИФункции Функция ПолучитьМодуль1СПлюс() ИмяПодсистемы = "ПлюсСервис"; Если ОбщегоНазначения.ПодсистемаСуществует(ИмяПодсистемы) Тогда МодульПлюсСервис = ОбщегоНазначения.ОбщийМодуль(ИмяПодсистемы); Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(МодульПлюсСервис.ВерсияБиблиотеки(), "1.0.0.4") >= 0 Тогда Возврат МодульПлюсСервис; КонецЕсли; КонецЕсли; КонецФункции Функция ЗагрузитьДанныеТекущейОбластиИзАрхиваВФоне(Знач ДанныеФайла, Знач ПараметрыЗагрузки) Если ОбщегоНазначения.ИнформационнаяБазаФайловая() И ПолучитьТекущийСеансИнформационнойБазы().ИмяПриложения = "BackgroundJob" Тогда ВызватьИсключение НСтр("ru = 'Невозможно выполнить загрузку в фоновом режиме: файловая информационная база поддерживает одновременное выполнение только одного фонового задания.'"); КонецЕсли; АдресРезультата = ПоместитьВоВременноеХранилище(Неопределено); ПараметрыЗадания = Новый Массив(); ПараметрыЗадания.Добавить(ДанныеФайла); ПараметрыЗадания.Добавить(ПараметрыЗагрузки); ПараметрыЗадания.Добавить(АдресРезультата); Задание = РасширенияКонфигурации.ВыполнитьФоновоеЗаданиеСРасширениямиБазыДанных( "ВыгрузкаЗагрузкаДанныхСлужебный.НачатьЗагрузкуДанныхТекущейОбластиИзАрхива", ПараметрыЗадания, Новый УникальныйИдентификатор, НСтр("ru = 'Восстановление области данных из архива'")) .ОжидатьЗавершенияВыполнения(); Если Задание.Состояние = СостояниеФоновогоЗадания.Отменено Тогда ВызватьИсключение НСтр("ru = 'Задание отменено'"); ИначеЕсли Задание.Состояние = СостояниеФоновогоЗадания.ЗавершеноАварийно Тогда ВызватьИсключение ОбработкаОшибок.ПодробноеПредставлениеОшибки(Задание.ИнформацияОбОшибке); КонецЕсли; Возврат ПолучитьИзВременногоХранилища(АдресРезультата); КонецФункции Функция ВозможноПродолжениеПроцедурыЗагрузки(ХешСуммаИсточника, ХешСуммаПараметров) ИнформацияОПроцедуреЗагрузки = ИнформацияОПроцедуреЗагрузки(); РезультатПроверки = РезультатПроверкиВозможностиПродолженияЗагрузкиДанныхОбласти( ИнформацияОПроцедуреЗагрузки, ХешСуммаИсточника, ХешСуммаПараметров); СобытиеЖурналаРегистрации = НСтр( "ru = 'Выгрузка загрузка данных. Продолжение процедуры загрузки невозможно'", ОбщегоНазначения.КодОсновногоЯзыка()); Если Не РезультатПроверки.ЭтоПродолжениеЗагрузки Тогда ЗаписьЖурналаРегистрации( СобытиеЖурналаРегистрации, УровеньЖурналаРегистрации.Предупреждение,,, НСтр("ru = 'Отсутствует информация о прошлой процедуре загрузки'")); Возврат Ложь; КонецЕсли; Если РезультатПроверки.РазличаетсяВерсияКонфигурации Тогда ТекстПредупреждения = СтрШаблон( НСтр("ru = 'Изменилось имя или версия конфигурации |Прошлые значения: %1 %2 |Текущие значения: %3 %4'"), ИнформацияОПроцедуреЗагрузки.Конфигурация, ИнформацияОПроцедуреЗагрузки.ВерсияКонфигурации, Метаданные.Имя, Метаданные.Версия); ЗаписьЖурналаРегистрации( СобытиеЖурналаРегистрации, УровеньЖурналаРегистрации.Предупреждение,,, ТекстПредупреждения); Возврат Ложь; КонецЕсли; Если РезультатПроверки.РазличаетсяХешСуммаИсточника Тогда ТекстПредупреждения = СтрШаблон( НСтр("ru = 'Изменился источник загрузки |Прошлое значение хеш суммы: %1 |Текущее значение хеш суммы: %2'"), ИнформацияОПроцедуреЗагрузки.ХешСуммаИсточника, ХешСуммаИсточника); ЗаписьЖурналаРегистрации( СобытиеЖурналаРегистрации, УровеньЖурналаРегистрации.Предупреждение,,, ТекстПредупреждения); Возврат Ложь; КонецЕсли; Если РезультатПроверки.РазличаетсяХешСуммаПараметров Тогда ТекстПредупреждения = СтрШаблон( НСтр("ru = 'Изменились параметры загрузки |Прошлое значение хеш суммы: %1 |Текущее значение хеш суммы: %2'"), ИнформацияОПроцедуреЗагрузки.ХешСуммаПараметров, ХешСуммаПараметров); ЗаписьЖурналаРегистрации( СобытиеЖурналаРегистрации, УровеньЖурналаРегистрации.Предупреждение,,, ТекстПредупреждения); Возврат Ложь; КонецЕсли; Если Не РезультатПроверки.ОпределенПоследнийЗагружаемыйОбъектМетаданных Тогда ЗаписьЖурналаРегистрации( СобытиеЖурналаРегистрации, УровеньЖурналаРегистрации.Предупреждение,,, НСтр("ru = 'Процесс загрузки был прерван не на загрузке метаданных'")); Возврат Ложь; КонецЕсли; Возврат Истина; КонецФункции Функция РезультатПроверкиВозможностиПродолженияЗагрузкиДанныхОбласти( ИнформацияОПроцедуреЗагрузки, ХешСуммаИсточника, ХешСуммаПараметров) Результат = Новый Структура(); Результат.Вставить("ЭтоПродолжениеЗагрузки", Ложь); Результат.Вставить("ОпределенПоследнийЗагружаемыйОбъектМетаданных", Ложь); Результат.Вставить("РазличаетсяВерсияКонфигурации", Ложь); Результат.Вставить("РазличаетсяХешСуммаИсточника", Ложь); Результат.Вставить("РазличаетсяХешСуммаПараметров", Ложь); Результат.ЭтоПродолжениеЗагрузки = ИнформацияОПроцедуреЗагрузки <> Неопределено; Если Результат.ЭтоПродолжениеЗагрузки Тогда Результат.ОпределенПоследнийЗагружаемыйОбъектМетаданных = РегистрыСведений.ВыгрузкаЗагрузкаОбъектовМетаданных.ЕстьОбрабатываемыеОбъектыМетаданных(); Результат.РазличаетсяВерсияКонфигурации = ИнформацияОПроцедуреЗагрузки.Конфигурация <> Метаданные.Имя Или ИнформацияОПроцедуреЗагрузки.ВерсияКонфигурации <> Метаданные.Версия; Результат.РазличаетсяХешСуммаИсточника = ИнформацияОПроцедуреЗагрузки.ХешСуммаИсточника <> ХешСуммаИсточника; Результат.РазличаетсяХешСуммаПараметров = ИнформацияОПроцедуреЗагрузки.ХешСуммаПараметров <> ХешСуммаПараметров; КонецЕсли; Возврат Результат; КонецФункции Процедура ЗафиксироватьНачалоПроцедурыЗагрузки(ХешСуммаИсточника, ХешСуммаПараметров, ИдентификаторСостояния) ИнформацияОПроцедуреЗагрузки = Новый Структура(); ИнформацияОПроцедуреЗагрузки.Вставить("ДатаНачала", ТекущаяДатаСеанса()); ИнформацияОПроцедуреЗагрузки.Вставить("Конфигурация", Метаданные.Имя); ИнформацияОПроцедуреЗагрузки.Вставить("ВерсияКонфигурации", Метаданные.Версия); ИнформацияОПроцедуреЗагрузки.Вставить("ХешСуммаИсточника", ХешСуммаИсточника); ИнформацияОПроцедуреЗагрузки.Вставить("ХешСуммаПараметров", ХешСуммаПараметров); ИнформацияОПроцедуреЗагрузки.Вставить("СоответствиеСсылок", Неопределено); ИнформацияОПроцедуреЗагрузки.Вставить("ИдентификаторСостояния", ИдентификаторСостояния); ЗаписатьИнформациюОПроцедуреЗагрузки(ИнформацияОПроцедуреЗагрузки); КонецПроцедуры Функция ИнформацияОПроцедуреЗагрузки() Возврат Константы.ИнформацияОПроцедуреЗагрузки.Получить().Получить(); КонецФункции Процедура ЗаписатьИнформациюОПроцедуреЗагрузки(Значение) Константы.ИнформацияОПроцедуреЗагрузки.Установить( Новый ХранилищеЗначения(Значение)); КонецПроцедуры Процедура ЗафиксироватьЗавершениеПроцедурыЗагрузки() ЗаписатьИнформациюОПроцедуреЗагрузки(Неопределено); КонецПроцедуры Функция НачатьПроцедуруЗагрузки(ПараметрыЗагрузки, Контейнер, Обработчики) Если Контейнер.ФиксироватьСостояние() И ЭтоДифференциальнаяРезервнаяКопия(ПараметрыЗагрузки) Тогда ИдентификаторСостояния = ИдентификаторСостояния(ПараметрыЗагрузки); СостояниеЗагрузки = ВыгрузкаЗагрузкаДанных.СостояниеВыгрузкиЗагрузкиОбластиДанных(ИдентификаторСостояния); Если ЗначениеЗаполнено(СостояниеЗагрузки) Тогда Контейнер.УстановитьДатуНачала( СостояниеЗагрузки.ДатаНачала); Контейнер.УстановитьКоличествоОбработанныхОбъектов( СостояниеЗагрузки.ОбработаноОбъектов); Иначе ЗаписатьСобытиеОтсутствияЗаписиПредыдущегоСостояния( ИдентификаторСостояния); КонецЕсли; КонецЕсли; ИнформацияОВыгрузке = ПрочитатьИнформациюОВыгрузке(Контейнер); ПроверитьВыгрузкаВАрхивеСовместимаСТекущейКонфигурацией( ИнформацияОВыгрузке); ПроверитьВыгрузкаВАрхивеСовместимаСТекущейВерсиейКонфигурации( ИнформацияОВыгрузке, ТипРезервнойКопии(ПараметрыЗагрузки) <> ТипРезервнойКопииПолная()); ЗафиксироватьНачалоПроцедурыЗагрузки( ПараметрыЗагрузки.ХешСуммаИсточника, ПараметрыЗагрузки.ХешСуммаПараметров, ИдентификаторСостояния(ПараметрыЗагрузки)); Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.УправлениеДоступом") Тогда МодульУправлениеДоступом = ОбщегоНазначения.ОбщийМодуль("УправлениеДоступом"); МодульУправлениеДоступом.ОтключитьОбновлениеКлючейДоступа(Истина, Ложь); КонецЕсли; Обработчики.ПередЗагрузкойДанных(Контейнер); СоответствиеСсылок = Неопределено; ПараметрыЗагрузки.Свойство("СоответствиеСсылок", СоответствиеСсылок); Возврат ЗагрузитьДанныеИнформационнойБазы( ПараметрыЗагрузки, Контейнер, Обработчики, СоответствиеСсылок); КонецФункции Функция ПродолжитьПроцедуруЗагрузки(ПараметрыЗагрузки, Контейнер, Обработчики) ИнформацияОПроцедуреЗагрузки = ИнформацияОПроцедуреЗагрузки(); ВыборкаОбъектов = РегистрыСведений.ВыгрузкаЗагрузкаОбъектовМетаданных.ВыборкаОбъектовКОбработке(Истина); ЗагружаемыеОбъектыМетаданных = Новый Массив(); Пока ВыборкаОбъектов.Следующий() Цикл ЗагружаемыеОбъектыМетаданных.Добавить(ВыборкаОбъектов.ОбъектМетаданных); КонецЦикла; СобытиеЖурналаРегистрации = НСтр( "ru = 'Выгрузка загрузка данных. Продолжение процедуры загрузки'", ОбщегоНазначения.КодОсновногоЯзыка()); ТекстПредупреждения = СтрШаблон( НСтр("ru = 'Процедура загрузки продолжена с объектов метаданных: %1'"), СтрСоединить(ЗагружаемыеОбъектыМетаданных, ", ")); ЗаписьЖурналаРегистрации( СобытиеЖурналаРегистрации, УровеньЖурналаРегистрации.Предупреждение,,, ТекстПредупреждения); Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.УправлениеДоступом") Тогда МодульУправлениеДоступом = ОбщегоНазначения.ОбщийМодуль("УправлениеДоступом"); МодульУправлениеДоступом.ОтключитьОбновлениеКлючейДоступа(Истина, Ложь); КонецЕсли; ВыборкаОбъектов.Сбросить(); Пока ВыборкаОбъектов.Следующий() Цикл РаботаВМоделиСервиса.ОчиститьДанныеОбъектаМетаданных( ВыборкаОбъектов.ОбъектМетаданных, Метаданные.НайтиПоПолномуИмени(ВыборкаОбъектов.ОбъектМетаданных)); РегистрыСведений.ВыгрузкаЗагрузкаОбъектовМетаданных.ЗафиксироватьОкончаниеОбработкиОбъекта( ВыборкаОбъектов); КонецЦикла; Если Контейнер.ФиксироватьСостояние() Тогда ИдентификаторСостоянияПроцедурыЗагрузки = ИнформацияОПроцедуреЗагрузки.ИдентификаторСостояния; Если ЗначениеЗаполнено(ИдентификаторСостоянияПроцедурыЗагрузки) Тогда СостояниеЗагрузки = ВыгрузкаЗагрузкаДанных.СостояниеВыгрузкиЗагрузкиОбластиДанных( ИдентификаторСостоянияПроцедурыЗагрузки); Если ЗначениеЗаполнено(СостояниеЗагрузки) Тогда Контейнер.УстановитьДатуНачала( СостояниеЗагрузки.ДатаНачала); Контейнер.УстановитьКоличествоОбработанныхОбъектов( СостояниеЗагрузки.ОбработаноОбъектовДоТекущегоОбъектаМетаданных); Иначе ЗаписатьСобытиеОтсутствияЗаписиПредыдущегоСостояния( ИдентификаторСостоянияПроцедурыЗагрузки); КонецЕсли; ИдентификаторСостоянияПараметровЗагрузки = ИдентификаторСостояния(ПараметрыЗагрузки); Если ИдентификаторСостоянияПроцедурыЗагрузки <> ИдентификаторСостоянияПараметровЗагрузки Тогда ИнформацияОПроцедуреЗагрузки.ИдентификаторСостояния = ИдентификаторСостоянияПараметровЗагрузки; ЗаписатьИнформациюОПроцедуреЗагрузки(ИнформацияОПроцедуреЗагрузки); КонецЕсли; КонецЕсли; КонецЕсли; Возврат ЗагрузитьДанныеИнформационнойБазы( ПараметрыЗагрузки, Контейнер, Обработчики, ИнформацияОПроцедуреЗагрузки.СоответствиеСсылок); КонецФункции Функция ЗагрузитьДанныеИнформационнойБазы( ПараметрыЗагрузки, Контейнер, Обработчики, СоответствиеСсылок = Неопределено) ПотокЗаменыСсылок = Обработки.ВыгрузкаЗагрузкаДанныхМенеджерЗагрузкиДанныхИнформационнойБазы.ЗагрузитьДанныеИнформационнойБазы( Контейнер, Обработчики, СоответствиеСсылок); Если Не РаботаВМоделиСервиса.РазделениеВключено() Тогда РаботаВМоделиСервиса.УдалитьПользователейОбласти(Истина); КонецЕсли; ПослеЗагрузкиДанныхИнформационнойБазы( ПараметрыЗагрузки, Контейнер, Обработчики, ПотокЗаменыСсылок); Возврат ПотокЗаменыСсылок.СоответствиеСсылок(); КонецФункции Процедура ПослеЗагрузкиДанныхИнформационнойБазы(ПараметрыЗагрузки, Контейнер, Обработчики, ПотокЗаменыСсылок) СопоставлениеПользователей = Неопределено; Если ПараметрыЗагрузки.ЗагружатьПользователей Тогда ВыгрузкаЗагрузкаПользователейИнформационнойБазы.ЗагрузитьПользователейИнформационнойБазы(Контейнер); Если ПараметрыЗагрузки.ЗагружатьНастройкиПользователей Тогда Обработки.ВыгрузкаЗагрузкаДанныхМенеджерЗагрузкиНастроекПользователей.ЗагрузитьНастройкиПользователейИнформационнойБазы( Контейнер, Обработчики, ПотокЗаменыСсылок); КонецЕсли; ИначеЕсли ПараметрыЗагрузки.Свойство("СопоставлениеПользователей", СопоставлениеПользователей) И ПараметрыЗагрузки.ТребуетсяСопоставлениеПользователей Тогда // Очистить идентификаторы, если они используются. Запрос = Новый Запрос; Запрос.УстановитьПараметр("Пользователи", СопоставлениеПользователей.ВыгрузитьКолонку("Пользователь")); Запрос.УстановитьПараметр("Идентификаторы", СопоставлениеПользователей.ВыгрузитьКолонку("ИдентификаторПользователяСервиса")); Запрос.Текст = "ВЫБРАТЬ | Пользователи.Ссылка КАК Пользователь |ИЗ | Справочник.Пользователи КАК Пользователи |ГДЕ | НЕ Пользователи.Ссылка В (&Пользователи) | И Пользователи.ИдентификаторПользователяСервиса В(&Идентификаторы)"; Выборка = Запрос.Выполнить().Выбрать(); Пока Выборка.Следующий() Цикл ПользовательОбъект = Выборка.Пользователь.ПолучитьОбъект(); // СправочникОбъект.Пользователи ПользовательОбъект.ИдентификаторПользователяСервиса = Неопределено; ПользовательОбъект.ОбменДанными.Загрузка = Истина; ПользовательОбъект.Записать(); КонецЦикла; // Обновить идентификаторы для используемых пользователей. Для Каждого СопоставлениеПользователя Из СопоставлениеПользователей Цикл Если Не ЗначениеЗаполнено(СопоставлениеПользователя.Пользователь) Тогда Продолжить; КонецЕсли; ПользовательОбъект = СопоставлениеПользователя.Пользователь.ПолучитьОбъект(); // СправочникОбъект.Пользователи Если ПользовательОбъект.ИдентификаторПользователяСервиса <> СопоставлениеПользователя.ИдентификаторПользователяСервиса Тогда ПользовательОбъект.ИдентификаторПользователяСервиса = СопоставлениеПользователя.ИдентификаторПользователяСервиса; ПользовательОбъект.ОбменДанными.Загрузка = Истина; ПользовательОбъект.Записать(); КонецЕсли; КонецЦикла; // Загрузить настройки с заменой имени пользователя ИБ. ЗаменитьПользователяВНастройках = Новый Соответствие; Для Каждого СопоставлениеПользователя Из СопоставлениеПользователей Цикл Если ЗначениеЗаполнено(СопоставлениеПользователя.СтароеИмяПользователяИБ) И ЗначениеЗаполнено(СопоставлениеПользователя.НовоеИмяПользователяИБ) Тогда ЗаменитьПользователяВНастройках.Вставить(СопоставлениеПользователя.СтароеИмяПользователяИБ, СопоставлениеПользователя.НовоеИмяПользователяИБ); КонецЕсли; КонецЦикла; Обработки.ВыгрузкаЗагрузкаДанныхМенеджерЗагрузкиНастроекПользователей.ЗагрузитьНастройкиПользователейИнформационнойБазы( Контейнер, Обработчики, ПотокЗаменыСсылок, ЗаменитьПользователяВНастройках); КонецЕсли; Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.УправлениеДоступом") Тогда МодульУправлениеДоступом = ОбщегоНазначения.ОбщийМодуль("УправлениеДоступом"); МодульУправлениеДоступом.ОтключитьОбновлениеКлючейДоступа(Истина); КонецЕсли; Если ПараметрыЗагрузки.ВидПриложения <> Неопределено Тогда ВидыПриложенийСлужебный.УстановитьВидПриложенияПоСообщению(ПараметрыЗагрузки.ВидПриложения); КонецЕсли; РазделениеВключено = РаботаВМоделиСервиса.РазделениеВключено(); Если РазделениеВключено Тогда КаталогРасширений.ИзменитьЗначениеИспользованияВПриложении(КаталогРасширений.ДоступноВИнформационнойБазе()); ЛичныйКабинетСервиса.ОбновитьИспользованиеЛичногоКабинета(); КонецЕсли; Если РазделениеВключено Тогда ПараметрыБлокировки = СоединенияИБ.ПолучитьБлокировкуСеансовОбластиДанных(); Если НЕ ПараметрыБлокировки.Установлена Тогда ПараметрыБлокировки.Установлена = Истина; СоединенияИБ.УстановитьБлокировкуСеансовОбластиДанных(ПараметрыБлокировки); КонецЕсли; КонецЕсли; ОчередьЗаданийСлужебныйРазделениеДанных.ПослеЗагрузкиДанных(Контейнер); Обработчики.ПослеЗагрузкиДанных(Контейнер); Если РазделениеВключено Тогда ПараметрыБлокировки.Установлена = Ложь; СоединенияИБ.УстановитьБлокировкуСеансовОбластиДанных(ПараметрыБлокировки); КонецЕсли; Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.УправлениеДоступом") Тогда МодульУправлениеДоступом = ОбщегоНазначения.ОбщийМодуль("УправлениеДоступом"); МодульУправлениеДоступом.ОтключитьОбновлениеКлючейДоступа(Ложь); КонецЕсли; Контейнер.ФинализироватьЗагрузку(); ЗафиксироватьЗавершениеПроцедурыЗагрузки(); КонецПроцедуры // Записывает описание конфигурации // // Параметры: // Контейнер - ОбработкаОбъект.ВыгрузкаЗагрузкаДанныхМенеджерКонтейнера - менеджер // контейнера, используемый в процессе выгрузи данных. Подробнее см. комментарий // к программному интерфейсу обработки ВыгрузкаЗагрузкаДанныхМенеджерКонтейнера. // Процедура СохранитьОписаниеВыгрузки(Знач Контейнер) ТипDumpInfo = ФабрикаXDTO.Тип("http://www.1c.ru/1cFresh/Data/Dump/1.0.2.1", "DumpInfo"); ТипConfigurationInfo = ФабрикаXDTO.Тип("http://www.1c.ru/1cFresh/Data/Dump/1.0.2.1", "ConfigurationInfo"); ИнформацияОВыгрузке = ФабрикаXDTO.Создать(ТипDumpInfo); ИнформацияОВыгрузке.Created = ТекущаяУниверсальнаяДата(); ИнформацияОКонфигурации = ФабрикаXDTO.Создать(ТипConfigurationInfo); ИнформацияОКонфигурации.Name = ВидыПриложенийСервер.ИмяТекущегоВидаПриложения(); ИнформацияОКонфигурации.Version = Метаданные.Версия; ИнформацияОКонфигурации.Vendor = Метаданные.Поставщик; ИнформацияОКонфигурации.Presentation = ВидыПриложенийСервер.ПредставлениеТекущегоВидаПриложения(); ИнформацияОВыгрузке.Configuration = ИнформацияОКонфигурации; ИмяФайла = Контейнер.СоздатьФайл(DumpInfo(), CustomData()); ЗаписатьОбъектXDTOВФайл(ИнформацияОВыгрузке, ИмяФайла); Контейнер.ФайлЗаписан(ИмяФайла); КонецПроцедуры // Читает описание конфигурации // // Параметры: // Контейнер - ОбработкаОбъект.ВыгрузкаЗагрузкаДанныхМенеджерКонтейнера - менеджер // контейнера, используемый в процессе выгрузи данных. Подробнее см. комментарий // к программному интерфейсу обработки ВыгрузкаЗагрузкаДанныхМенеджерКонтейнера. // Функция ПрочитатьИнформациюОВыгрузке(Контейнер) Файл = Контейнер.ПолучитьФайлИзКаталога(DumpInfo()); Если Файл = Неопределено Тогда ВызватьИсключение НСтр("ru = 'В информации о составе файлов выгрузки отсутствует описание файла с информацией о выгрузке'"); КонецЕсли; Контейнер.РаспаковатьФайл(Файл); Результат = ПрочитатьОбъектXDTOИзФайла(Файл.ПолноеИмя, ФабрикаXDTO.Тип("http://www.1c.ru/1cFresh/Data/Dump/1.0.2.1", "DumpInfo")); УдалитьФайлы(Файл.ПолноеИмя); Возврат Результат; КонецФункции // Возвращает имя элемента в потоке записи/чтения, в котором хранится XDTOОбъект. // // Возвращаемое значение: // Строка - имя элемента. // Функция ИмяЭлементаСодержащегоXDTOОбъект() Возврат "XDTODataObject"; КонецФункции // Возвращает имя элемента в потоке записи/чтения, в котором хранится объект. // // Возвращаемое значение: // Строка - имя элемента. // Функция ИмяЭлементаСодержащегоОбъект() Возврат "Data"; КонецФункции // Возвращает массив пространства имен для записи пакетов. // // Параметры: // URIПространстваИмен - Строка - пространство имен. // // Возвращаемое значение: // Массив из Строка - массив пространств имен. // Функция ПолучитьПространстваИменДляЗаписиПакета(Знач URIПространстваИмен) Результат = Новый Массив(); Результат.Добавить(URIПространстваИмен); Зависимости = ФабрикаXDTO.Пакеты.Получить(URIПространстваИмен).Зависимости; Для Каждого Зависимость Из Зависимости Цикл ЗависимыеПространстваИмен = ПолучитьПространстваИменДляЗаписиПакета(Зависимость.URIПространстваИмен); ОбщегоНазначенияКлиентСервер.ДополнитьМассив(Результат, ЗависимыеПространстваИмен, Истина); КонецЦикла; Возврат Результат; КонецФункции // Заполняет массив коллекцией метаданных ссылочных объектов. // // Параметры: // МассивКоллекцийМетаданных - Массив из ОбъектМетаданных - объекты метаданных. // Процедура ЗаполнитьКоллекцииСсылочныхОбъектов(МассивКоллекцийМетаданных) МассивКоллекцийМетаданных.Добавить(Метаданные.Справочники); МассивКоллекцийМетаданных.Добавить(Метаданные.Документы); МассивКоллекцийМетаданных.Добавить(Метаданные.БизнесПроцессы); МассивКоллекцийМетаданных.Добавить(Метаданные.Задачи); МассивКоллекцийМетаданных.Добавить(Метаданные.ПланыСчетов); МассивКоллекцийМетаданных.Добавить(Метаданные.ПланыОбмена); МассивКоллекцийМетаданных.Добавить(Метаданные.ПланыВидовХарактеристик); МассивКоллекцийМетаданных.Добавить(Метаданные.ПланыВидовРасчета); КонецПроцедуры // Заполняет массив коллекцией метаданных наборов записей. // // Параметры: // МассивКоллекцийМетаданных - Массив из КоллекцияОбъектовМетаданных - массив. // Процедура ЗаполнитьКоллекцииНаборовЗаписей(МассивКоллекцийМетаданных) МассивКоллекцийМетаданных.Добавить(Метаданные.РегистрыСведений); МассивКоллекцийМетаданных.Добавить(Метаданные.РегистрыНакопления); МассивКоллекцийМетаданных.Добавить(Метаданные.РегистрыБухгалтерии); МассивКоллекцийМетаданных.Добавить(Метаданные.Последовательности); МассивКоллекцийМетаданных.Добавить(Метаданные.РегистрыРасчета); Для Каждого РегистрРасчета Из Метаданные.РегистрыРасчета Цикл МассивКоллекцийМетаданных.Добавить(РегистрРасчета.Перерасчеты); КонецЦикла; КонецПроцедуры // Заполняет массив коллекцией метаданных констант. // // Параметры: // МассивКоллекцийМетаданных - Массив из КоллекцияОбъектовМетаданных - массив. // Процедура ЗаполнитьКоллекцииКонстант(МассивКоллекцийМетаданных) МассивКоллекцийМетаданных.Добавить(Метаданные.Константы); КонецПроцедуры // Возвращает полный список объектов из указанных коллекций // // Параметры: // Коллекции - Массив из КоллекцияОбъектовМетаданных - Коллекции. // // Возвращаемое значение: // Массив из ОбъектМетаданных - Объекты метаданных. // Функция ВсеМетаданныеКоллекций(Знач Коллекции) Результат = Новый Массив; Для Каждого Коллекция Из Коллекции Цикл Для Каждого Объект Из Коллекция Цикл Результат.Добавить(Объект); КонецЦикла; КонецЦикла; Возврат Результат; КонецФункции // Возвращает ссылки точек бизнес процесса // // Возвращаемое значение: // Соответствие из КлючИЗначение: // *Ключ - Тип - тип ссылки точки бизнес процесса. // *Значение - ОбъектМетаданных - бизнес процесс. // Функция СсылкиТочекМаршрутаБизнесПроцессов() Результат = Новый Соответствие(); Для Каждого БизнесПроцесс Из Метаданные.БизнесПроцессы Цикл Результат.Вставить(Тип("ТочкаМаршрутаБизнесПроцессаСсылка." + БизнесПроцесс.Имя), БизнесПроцесс); КонецЦикла; Возврат Результат; КонецФункции // Возвращает наименование файла с дайджестом выгрузки. // // Возвращаемое значение: // Строка - наименование Функция Digest() Экспорт Возврат "Digest"; КонецФункции // Возвращает наименование файла с предупреждениями выгрузки. // // Возвращаемое значение: // Строка - наименование Функция DumpWarnings() Экспорт Возврат "DumpWarnings"; КонецФункции // Extensions // // Возвращаемое значение: // Строка Функция Extensions() Экспорт Возврат "Extensions"; КонецФункции // Custom extensions // // Возвращаемое значение: // Строка Функция CustomExtensions() Экспорт Возврат "CustomExtensions"; КонецФункции // Возвращает наименование файла с видами приложения. // // Возвращаемое значение: // Строка Функция ApplicationTypes() Экспорт Возврат "ApplicationTypes"; КонецФункции // Возвращает наименование файла с дублями предопределенных. // // Возвращаемое значение: // Строка - наименование Функция PredefinedDataDuplicates() Экспорт Возврат "PredefinedDataDuplicates"; КонецФункции // Записывает ОбъектXDTO в файл. // // Параметры: // ОбъектXDTO - ОбъектXDTO - записываемый ОбъектXDTO. // ИмяФайла - Строка - полный путь к файлу. // ПрефиксПространстваИменПоУмолчанию - Строка - префикс. // Процедура ЗаписатьОбъектXDTOВФайл(Знач ОбъектXDTO, Знач ИмяФайла, Знач ПрефиксПространстваИменПоУмолчанию = "") ПотокЗаписи = Новый ЗаписьXML(); ПотокЗаписи.ОткрытьФайл(ИмяФайла); ПрефиксыПространствИмен = ПрефиксыПространствИмен(); ПространствоИменОбъекта = ОбъектXDTO.Тип().URIПространстваИмен; Если ПустаяСтрока(ПрефиксПространстваИменПоУмолчанию) Тогда ПрефиксПространстваИменПоУмолчанию = ПрефиксыПространствИмен.Получить(ПространствоИменОбъекта); КонецЕсли; ИспользуемыеПространстваИмен = ПолучитьПространстваИменДляЗаписиПакета(ПространствоИменОбъекта); ПотокЗаписи.ЗаписатьНачалоЭлемента(ИмяЭлементаСодержащегоXDTOОбъект()); Для Каждого ИспользуемоеПространствоИмен Из ИспользуемыеПространстваИмен Цикл ПрефиксПространстваИмен = ПрефиксыПространствИмен.Получить(ИспользуемоеПространствоИмен); Если ПрефиксПространстваИмен = ПрефиксПространстваИменПоУмолчанию Тогда ПотокЗаписи.ЗаписатьСоответствиеПространстваИмен("", ИспользуемоеПространствоИмен); Иначе ПотокЗаписи.ЗаписатьСоответствиеПространстваИмен(ПрефиксПространстваИмен, ИспользуемоеПространствоИмен); КонецЕсли; КонецЦикла; ФабрикаXDTO.ЗаписатьXML(ПотокЗаписи, ОбъектXDTO); ПотокЗаписи.ЗаписатьКонецЭлемента(); ПотокЗаписи.Закрыть(); КонецПроцедуры Функция СхемаXML(ДвоичныеДанныеСхемы) ПотокДляЧтения = ДвоичныеДанныеСхемы.ОткрытьПотокДляЧтения(); Чтение = Новый ЧтениеXML; Чтение.ОткрытьПоток(ПотокДляЧтения); Построитель = Новый ПостроительDOM; Документ = Построитель.Прочитать(Чтение); // ЭлементDOM ПотокДляЧтения.Закрыть(); ПостроительСхем = Новый ПостроительСхемXML; Возврат ПостроительСхем.СоздатьСхемуXML(Документ); КонецФункции Функция ФабрикаПоСхеме(Схема) НаборСхем = Новый НаборСхемXML; НаборСхем.Добавить(Схема); Возврат Новый ФабрикаXDTO(НаборСхем); КонецФункции Процедура ВыгрузитьСхемуКонфигурации(Контейнер, ПараметрыВыгрузки) ДанныеСхемыКонфигурации = Неопределено; Если Не ПараметрыВыгрузки.Свойство("ДанныеСхемыКонфигурации", ДанныеСхемыКонфигурации) Тогда ДанныеСхемыКонфигурации = СхемаКонфигурации.ДвоичныеДанныеСхемы(Ложь, Ложь); КонецЕсли; ПолноеИмяФайла = Контейнер.СоздатьПроизвольныйФайл("xsd", "ConfigScheme"); ДанныеСхемыКонфигурации.Записать(ПолноеИмяФайла); Контейнер.УстановитьКоличествоОбъектов(ПолноеИмяФайла, 1); КонецПроцедуры Процедура ВосстановитьРасширения(РасширенияДляВосстановления) СтруктураОтбора = Новый Структура("Имя"); Для Каждого РасширениеДляВосстановления Из РасширенияДляВосстановления Цикл СтруктураОтбора.Имя = РасширениеДляВосстановления.Имя; ДанныеВосстанавливаемогоРасширения = РасширениеДляВосстановления.Данные; УстановленныеРасширения = РасширенияКонфигурации.Получить(СтруктураОтбора, ИсточникРасширенийКонфигурации.БазаДанных); Если ЗначениеЗаполнено(УстановленныеРасширения) Тогда УстановленноеРасширение = УстановленныеРасширения[0]; Если УстановленноеРасширение.Активно = РасширениеДляВосстановления.Активно И УстановленноеРасширение.БезопасныйРежим = РасширениеДляВосстановления.БезопасныйРежим И УстановленноеРасширение.ИспользоватьОсновныеРолиДляВсехПользователей = РасширениеДляВосстановления.ИспользоватьОсновныеРолиДляВсехПользователей И УстановленноеРасширение.ИспользуетсяВРаспределеннойИнформационнойБазе = РасширениеДляВосстановления.ИспользуетсяВРаспределеннойИнформационнойБазе И УстановленноеРасширение.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = РасширениеДляВосстановления.ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях Тогда Если УстановленноеРасширение.УникальныйИдентификатор = РасширениеДляВосстановления.УникальныйИдентификатор Тогда Продолжить; КонецЕсли; МетаданныеУстановленногоРасширения = Новый ОбъектМетаданныхКонфигурация(УстановленноеРасширение.ПолучитьДанные()); МетаданныеВосстанавливаемогоРасширения = Новый ОбъектМетаданныхКонфигурация(ДанныеВосстанавливаемогоРасширения); Если МетаданныеУстановленногоРасширения.Версия = МетаданныеВосстанавливаемогоРасширения.Версия Тогда Продолжить; КонецЕсли; КонецЕсли; УстановленноеРасширение.Удалить(); КонецЕсли; ВосстанавливаемоеРасширение = РасширенияКонфигурации.Создать(); ЗаполнитьЗначенияСвойств(ВосстанавливаемоеРасширение, РасширениеДляВосстановления); ВосстанавливаемоеРасширение.Записать(ДанныеВосстанавливаемогоРасширения); КонецЦикла; КонецПроцедуры Процедура ВосстановитьКаркасыРасширений(РасширенияДляВосстановления) СтруктураОтбора = Новый Структура("Имя"); Для Каждого РасширениеДляВосстановления Из РасширенияДляВосстановления Цикл ДанныеВосстанавливаемогоРасширения = РасширениеДляВосстановления.Данные; МетаданныеВосстанавливаемогоРасширения = Новый ОбъектМетаданныхКонфигурация(ДанныеВосстанавливаемогоРасширения); СтруктураОтбора.Имя = МетаданныеВосстанавливаемогоРасширения.Имя; УстановленныеРасширения = РасширенияКонфигурации.Получить(СтруктураОтбора, ИсточникРасширенийКонфигурации.БазаДанных); Если ЗначениеЗаполнено(УстановленныеРасширения) Тогда УстановленноеРасширение = УстановленныеРасширения[0]; МетаданныеУстановленногоРасширения = Новый ОбъектМетаданныхКонфигурация(УстановленноеРасширение.ПолучитьДанные()); Если МетаданныеУстановленногоРасширения.Версия = МетаданныеВосстанавливаемогоРасширения.Версия Тогда Продолжить; КонецЕсли; УстановленноеРасширение.Удалить(); КонецЕсли; ВосстанавливаемоеРасширение = РасширенияКонфигурации.Создать(); ВосстанавливаемоеРасширение.БезопасныйРежим = Ложь; ЗащитаОтОпасныхДействий = Новый ОписаниеЗащитыОтОпасныхДействий; ЗащитаОтОпасныхДействий.ПредупреждатьОбОпасныхДействиях = Ложь; ВосстанавливаемоеРасширение.ЗащитаОтОпасныхДействий = ЗащитаОтОпасныхДействий; ВосстанавливаемоеРасширение.Записать(ДанныеВосстанавливаемогоРасширения); КонецЦикла; КонецПроцедуры Процедура ДобавитьКонстантуВСписокМетаданных(МетаданныеОбъекта, СписокМетаданных, Типы) Для Каждого Тип Из Типы Цикл Если МетаданныеОбъекта.Тип.СодержитТип(Тип) Тогда СписокМетаданных.Вставить(МетаданныеОбъекта.ПолноеИмя(), Новый Массив); Возврат; КонецЕсли; КонецЦикла; КонецПроцедуры Процедура ДобавитьСсылочныйТипВСписокМетаданных(МетаданныеОбъекта, СписокМетаданных, Типы) МассивСтруктур = Новый Массив; Для Каждого Реквизит Из МетаданныеОбъекта.Реквизиты Цикл ДобавитьРеквизитВМассив(МассивСтруктур, Реквизит,, Типы); КонецЦикла; Для Каждого ТабличнаяЧасть Из МетаданныеОбъекта.ТабличныеЧасти Цикл Для Каждого Реквизит Из ТабличнаяЧасть.Реквизиты Цикл ДобавитьРеквизитВМассив(МассивСтруктур, Реквизит, ТабличнаяЧасть, Типы); КонецЦикла; КонецЦикла; ВставитьОбъектМетаданныхВСоответствие(МетаданныеОбъекта.ПолноеИмя(), СписокМетаданных, МассивСтруктур); КонецПроцедуры Процедура ДобавитьРегистрВТаблицуМетаданных(МетаданныеОбъекта, Знач СписокМетаданных, Типы) МассивСтруктур = Новый Массив; ЭтоПерерасчет = Метаданные.РегистрыРасчета.Содержит(МетаданныеОбъекта.Родитель()); Для Каждого Измерение Из МетаданныеОбъекта.Измерения Цикл Если ЭтоПерерасчет Тогда Измерение = Измерение.ИзмерениеРегистра; КонецЕсли; ДобавитьРеквизитВМассив(МассивСтруктур, Измерение,, Типы); КонецЦикла; Если Метаданные.Последовательности.Содержит(МетаданныеОбъекта) Тогда Для Каждого ДокументМетаданные Из МетаданныеОбъекта.Документы Цикл МенеджерДокумента = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени( ДокументМетаданные.ПолноеИмя()); ТипДокумента = ТипЗнч(МенеджерДокумента.ПустаяСсылка()); Если Типы.Найти(ТипДокумента) <> Неопределено Тогда Структура = СтруктураРеквизитов(); Структура.ИмяРеквизита = "Регистратор"; МассивСтруктур.Добавить(Структура); Прервать; КонецЕсли; КонецЦикла; ИначеЕсли Не ЭтоПерерасчет Тогда Для Каждого Реквизит Из МетаданныеОбъекта.Реквизиты Цикл ДобавитьРеквизитВМассив( МассивСтруктур, Реквизит,, Типы); КонецЦикла; Для Каждого Ресурс Из МетаданныеОбъекта.Ресурсы Цикл ДобавитьРеквизитВМассив( МассивСтруктур, Ресурс,, Типы); КонецЦикла; Если Не ОбщегоНазначенияБТС.ЭтоНезависимыйНаборЗаписей(МетаданныеОбъекта) Тогда ДобавитьРеквизитВМассив( МассивСтруктур, МетаданныеОбъекта.СтандартныеРеквизиты.Регистратор,, Типы); КонецЕсли; Если ОбщегоНазначенияБТС.ЭтоРегистрБухгалтерии(МетаданныеОбъекта) И МетаданныеОбъекта.ПланСчетов <> Неопределено Тогда МенеджерПланаСчетов = ОбщегоНазначения.МенеджерОбъектаПоПолномуИмени( МетаданныеОбъекта.ПланСчетов.ПолноеИмя()); ТипПланаСчетов = ТипЗнч(МенеджерПланаСчетов.ПустаяСсылка()); Если Типы.Найти(ТипПланаСчетов) <> Неопределено Тогда Если МетаданныеОбъекта.Корреспонденция Тогда Структура = СтруктураРеквизитов(); Структура.ИмяРеквизита = "СчетДт"; МассивСтруктур.Добавить(Структура); Структура = СтруктураРеквизитов(); Структура.ИмяРеквизита = "СчетКт"; МассивСтруктур.Добавить(Структура); Иначе Структура = СтруктураРеквизитов(); Структура.ИмяРеквизита = "Счет"; МассивСтруктур.Добавить(Структура); КонецЕсли; КонецЕсли; КонецЕсли; КонецЕсли; ВставитьОбъектМетаданныхВСоответствие(МетаданныеОбъекта.ПолноеИмя(), СписокМетаданных, МассивСтруктур); КонецПроцедуры Процедура ДобавитьРеквизитВМассив(МассивСтруктур, Реквизит, ТабличнаяЧасть = Неопределено, Типы) Для Каждого Тип Из Типы Цикл Если Реквизит.Тип.СодержитТип(Тип) Тогда ИмяРеквизита = Реквизит.Имя; ИмяТабличнойЧасти = ?(ТабличнаяЧасть = Неопределено, Неопределено, ТабличнаяЧасть.Имя); Структура = СтруктураРеквизитов(); Структура.ИмяТабличнойЧасти = ИмяТабличнойЧасти; Структура.ИмяРеквизита = ИмяРеквизита; МассивСтруктур.Добавить(Структура); Возврат; КонецЕсли; КонецЦикла; КонецПроцедуры Процедура ВставитьОбъектМетаданныхВСоответствие(ПолноеИмяМетаданных, СписокМетаданных, МассивСтруктур) Если МассивСтруктур.Количество() = 0 Тогда Возврат; КонецЕсли; СписокМетаданных.Вставить(ПолноеИмяМетаданных, МассивСтруктур); КонецПроцедуры // Возвращаемое значение: // Структура: // * ИмяРеквизита - Строка // * ИмяТабличнойЧасти - Строка // Функция СтруктураРеквизитов() Результат = Новый Структура; Результат.Вставить("ИмяТабличнойЧасти"); Результат.Вставить("ИмяРеквизита"); Возврат Результат; КонецФункции // Возвращает тип резервной копии в зависимости от параметров загрузки. // Параметры: // ПараметрыЗагрузки - Структура - параметры // // Возвращаемое значение: // Строка - одно из значений: Обычная, Полная, Дифференциальная Функция ТипРезервнойКопии(ПараметрыЗагрузки) Если ПараметрыЗагрузки.Свойство("ТипРезервнойКопии") Тогда Возврат ПараметрыЗагрузки.ТипРезервнойКопии; КонецЕсли; Возврат ТипРезервнойКопииОбычная(); КонецФункции Функция ИдентификаторСостояния(ПараметрыЗагрузки) Если Не ЗначениеЗаполнено(ПараметрыЗагрузки) Тогда Возврат Неопределено; КонецЕсли; ИдентификаторСостояния = Неопределено; ПараметрыЗагрузки.Свойство("ИдентификаторСостояния", ИдентификаторСостояния); Возврат ИдентификаторСостояния; КонецФункции Процедура ВосстановитьРасширенияОбласти(ДанныеРасширений) КаталогРасширений.ПрочитатьДанныеВосстанавливаемыхРасширенийОбласти(ДанныеРасширений); КлючОбластиДанных = Неопределено; Если ДанныеРасширений.Свойство("КлючОбластиДанных", КлючОбластиДанных) Тогда Константы.КлючОбластиДанных.Установить(КлючОбластиДанных); КонецЕсли; РасширенияДляВосстановления = Неопределено; Если ДанныеРасширений.Свойство("РасширенияДляВосстановления", РасширенияДляВосстановления) Тогда КаталогРасширений.ВосстановитьРасширенияВНовойОбласти(РасширенияДляВосстановления); КонецЕсли; КаталогРасширений.ЗаписатьДанныеВосстанавливаемыхРасширенийОбласти(РасширенияДляВосстановления); КонецПроцедуры Процедура ЗаписатьСобытиеОтсутствияЗаписиПредыдущегоСостояния(ИдентификаторСостояния) ЗаписьЖурналаРегистрации( НСтр("ru = 'Выгрузка загрузка данных. Не найдена запись предыдущего состояния'", ОбщегоНазначения.КодОсновногоЯзыка()), УровеньЖурналаРегистрации.Предупреждение,, ИдентификаторСостояния, НСтр("ru = 'Восстановление состояния пропущено'")); КонецПроцедуры Функция ХешСуммаИсточника(Архив) ИмяФайлаСодержимого = ПолучитьИмяФайла(PackageContents()); ВременныйКаталог = ПолучитьИмяВременногоФайла(); СоздатьКаталог(ВременныйКаталог); РаспаковатьФайлАрхива(Архив, ВременныйКаталог, ИмяФайлаСодержимого); ХешированиеДанных = Новый ХешированиеДанных(ХешФункция.CRC32); ХешированиеДанных.ДобавитьФайл( ВременныйКаталог + ПолучитьРазделительПути() + ИмяФайлаСодержимого); УдалитьФайлы(ВременныйКаталог); Возврат ХешированиеДанных.ХешСумма; КонецФункции Функция ХешСуммаПараметров(ПараметрыЗагрузки) КонтролируемыеПараметрыЗагрузки = Новый Структура( "ЗагружатьНастройкиПользователей, ЗагружатьПользователей, СвернутьРазделенныхПользователей"); ЗаполнитьЗначенияСвойств(КонтролируемыеПараметрыЗагрузки, ПараметрыЗагрузки); ХешированиеДанных = Новый ХешированиеДанных(ХешФункция.CRC32); ХешированиеДанных.Добавить( ОбщегоНазначения.ЗначениеВСтрокуXML(КонтролируемыеПараметрыЗагрузки)); Возврат ХешированиеДанных.ХешСумма; КонецФункции Функция НоваяТаблицаКоличестваОбрабатываемыхОбъектов() ТаблицаКоличестваОбрабатываемыхОбъектов = Новый ТаблицаЗначений; ТаблицаКоличестваОбрабатываемыхОбъектов.Колонки.Добавить("ПолноеИмя", Новый ОписаниеТипов("Строка")); ТаблицаКоличестваОбрабатываемыхОбъектов.Колонки.Добавить("ЧислоОбъектов", Новый ОписаниеТипов("Число")); Возврат ТаблицаКоличестваОбрабатываемыхОбъектов; КонецФункции Функция ТаблицаКоличестваВыгружаемыхОбъектовПоПодзапросам(Подзапросы) РазделительПодзапросов = Символы.ПС + " ОБЪЕДИНИТЬ ВСЕ " + Символы.ПС; Запрос = Новый Запрос(СтрСоединить(Подзапросы, РазделительПодзапросов)); Возврат Запрос.Выполнить().Выгрузить(); КонецФункции Процедура ДополнитьТаблицуКоличестваОбрабатываемыхОбъектов(ТаблицаКоличестваОбрабатываемыхОбъектов, ТаблицаДополнения) Для Каждого СтрокаТаблицыДополнения Из ТаблицаДополнения Цикл ЗаполнитьЗначенияСвойств(ТаблицаКоличестваОбрабатываемыхОбъектов.Добавить(), СтрокаТаблицыДополнения); КонецЦикла; КонецПроцедуры #Область ПараллельнаяВыгрузкаЗагрузка // Обработать сообщения потоков. // // Параметры: // ТаблицаСообщений - см. НоваяТаблицаСообщенийПотоков // Контейнер - ОбработкаОбъект.ВыгрузкаЗагрузкаДанныхМенеджерКонтейнера - Текущий контейнер Процедура ОбработатьСообщенияПотоков(ТаблицаСообщений, Контейнер) Если Не ЗначениеЗаполнено(ТаблицаСообщений) Тогда Возврат; КонецЕсли; ТаблицаСообщений.Сортировать("ДатаОтправки, НомерСообщения"); Для Каждого СтрокаТаблицы Из ТаблицаСообщений Цикл Контейнер.ОбработатьСообщениеПотока(СтрокаТаблицы.ИмяМетода, СтрокаТаблицы.ДанныеСообщения); КонецЦикла; КонецПроцедуры // Получить сообщения потока. // // Параметры: // ТаблицаСообщений - см. НоваяТаблицаСообщенийПотоков // Задание - ФоновоеЗадание - Задание выполняющее выгрузку \ загрузку // ИдентификаторПроцесса - УникальныйИдентификатор - Идентификатор процесса выгрузки \ загрузки Процедура ПолучитьСообщенияПотока(ТаблицаСообщений, Задание, ИдентификаторПроцесса) СообщенияПотока = Задание.ПолучитьСообщенияПользователю(Истина); Если Не ЗначениеЗаполнено(СообщенияПотока) Тогда Возврат; КонецЕсли; ЧтениеСообщенияПотока = Новый ЧтениеJSON(); Для Каждого Сообщение Из СообщенияПотока Цикл Если Сообщение.ИдентификаторНазначения <> ИдентификаторПроцесса Тогда Продолжить; КонецЕсли; ЧтениеСообщенияПотока.УстановитьСтроку(Сообщение.Текст); СообщениеПотока = ПрочитатьJSON(ЧтениеСообщенияПотока); СтрокаТаблицы = ТаблицаСообщений.Добавить(); ЗаполнитьЗначенияСвойств(СтрокаТаблицы, СообщениеПотока); СтрокаТаблицы.КлючЗадания = Задание.Ключ; КонецЦикла; ЧтениеСообщенияПотока.Закрыть(); КонецПроцедуры // Задание потока завершено. // // Параметры: // Задание - ФоновоеЗадание - Задание выполняющее выгрузку \ загрузку // ТаблицаСообщений - см. НоваяТаблицаСообщенийПотоков // // Возвращаемое значение: // Булево Функция ЗаданиеПотокаЗавершено(Задание, ТаблицаСообщений) ПараметрыОтбора = Новый Структура(); ПараметрыОтбора.Вставить("ИмяМетода", ИмяМетодаСообщенияПотока_ЗавершениеВыгрузки()); ПараметрыОтбора.Вставить("КлючЗадания", Задание.Ключ); НайденныеСтроки = ТаблицаСообщений.НайтиСтроки(ПараметрыОтбора); Возврат ЗначениеЗаполнено(НайденныеСтроки); КонецФункции // Новая таблица сообщений потоков. // // Возвращаемое значение: // ТаблицаЗначений - Новая таблица сообщений потоков: // * ДатаОтправки - Число - Универсальная дата в миллисекундах // * ИмяМетода - Строка - Имя метода // * ДанныеСообщения - Структура - Данные сообщения // * КлючЗадания - Строка - Ключ фонового задания отправителя Функция НоваяТаблицаСообщенийПотоков() ТипЧисло = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(32, 0, ДопустимыйЗнак.Неотрицательный)); ТипСтрока = Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(256, ДопустимаяДлина.Переменная)); ТаблицаСообщений = Новый ТаблицаЗначений(); ТаблицаСообщений.Колонки.Добавить("ДатаОтправки", ТипЧисло); ТаблицаСообщений.Колонки.Добавить("НомерСообщения", ТипЧисло); ТаблицаСообщений.Колонки.Добавить("ИмяМетода", ТипСтрока); ТаблицаСообщений.Колонки.Добавить("ДанныеСообщения"); ТаблицаСообщений.Колонки.Добавить("КлючЗадания", ТипСтрока); Возврат ТаблицаСообщений; КонецФункции // Ключ задания выгрузки загрузки данных. // // Параметры: // Контейнер - ОбработкаОбъект.ВыгрузкаЗагрузкаДанныхМенеджерКонтейнера // // Возвращаемое значение: // Строка - Ключ задания выгрузки загрузки данных Функция КлючЗаданияВыгрузкиЗагрузкиДанных(Контейнер) Возврат СтрШаблон( "%1_Поток_%2", Контейнер.ИдентификаторПроцесса(), Контейнер.СледующийНомерПотока()); КонецФункции // Номер потока из ключа задания. // // Параметры: // КлючЗадания - Строка - Ключ задания // // Возвращаемое значение: // Строка - Номер потока из ключа задания Функция НомерПотокаИзКлючаЗадания(КлючЗадания) НомерПотока = ""; ЧастиКлюча = СтрРазделить(КлючЗадания, "_", Ложь); Если ЧастиКлюча.Количество() = 3 Тогда НомерПотока = ЧастиКлюча[2]; КонецЕсли; Возврат НомерПотока; КонецФункции // Запустить дополнительные потоки выгрузки загрузки данных. // // Параметры: // Задания - Массив из ФоновоеЗадание - Запущенные задания // ПараметрыПроцесса - Структура - Для загрузки данных см. обработку ВыгрузкаЗагрузкаДанныхМенеджерЗагрузкиДанныхИнформационнойБазы.НовыеПараметрыПроцессаЗагрузкиДанныхИнформационнойБазы // Для выгрузки данных см. обработку ВыгрузкаЗагрузкаДанныхМенеджерВыгрузкиДанныхИнформационнойБазы.НовыеПараметрыПроцессаВыгрузкиДанныхИнформационнойБазы Процедура ЗапуститьДополнительныеПотокиВыгрузкиЗагрузкиДанных(Задания, ПараметрыПроцесса) Возврат; КонецПроцедуры #КонецОбласти // См. СтандартныеПодсистемыСервер.ПриОпределенииМетодовРазрешенныхДляВызоваКакПроизвольныйКод Процедура ПриОпределенииМетодовРазрешенныхДляВызоваКакПроизвольныйКод(Методы) Экспорт Методы.Вставить("ВыгрузкаЗагрузкаДанныхИнформационнойБазыВПотоке", Истина); Методы.Вставить("НачатьЗагрузкуДанныхТекущейОбластиИзАрхива", Истина); КонецПроцедуры #КонецОбласти