Friday, July 22, 2011

обработка по обмену через xml

Обработку писал в быстром темпе, для одинаковых баз данных, ее задача выбрать объект и все связанные с ним элементы и перенести в другую базу.

Перем СписокДляВыгрузки,СписокОбщий,Запись;

Процедура КнопкаВыполнитьНажатие(Кнопка)
 // Вставить содержимое обработчика.
КонецПроцедуры

Процедура ОбработкаМетаданных(СсылкаРекурсии)
 Если НЕ СписокДляВыгрузки.Найти(СсылкаРекурсии,"Ссылка")=НЕопределено тогда
  возврат;
 КонецЕсли;
 
 Если НЕ СписокОбщий.Найти(СсылкаРекурсии,"Ссылка")=НЕопределено тогда // проверка на общий список
  возврат;
 КонецЕсли;
 Если СсылкаРекурсии.Пустая() тогда
  возврат;
 КонецЕсли;
 
 Для Каждого ОбъектМетаданных  ИЗ СсылкаРекурсии.Метаданные().Реквизиты Цикл
  Если Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(СсылкаРекурсии[ОбъектМетаданных.Имя])) И (НЕ СсылкаРекурсии[ОбъектМетаданных.Имя]=Неопределено) и (не СсылкаРекурсии[ОбъектМетаданных.Имя].Пустая()) И (НЕ СсылкаРекурсии[ОбъектМетаданных.Имя]=СсылкаРекурсии) тогда
   ОбработкаМетаданных(СсылкаРекурсии[ОбъектМетаданных.Имя]);
   СписокДляВыгрузки.Добавить()["Ссылка"]=СсылкаРекурсии[ОбъектМетаданных.Имя];
  КонецЕсли;
  Если Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(СсылкаРекурсии[ОбъектМетаданных.Имя])) И (НЕ СсылкаРекурсии[ОбъектМетаданных.Имя]=Неопределено) И (не СсылкаРекурсии[ОбъектМетаданных.Имя].Пустая()) И (НЕ СсылкаРекурсии[ОбъектМетаданных.Имя]=СсылкаРекурсии) тогда
   ОбработкаМетаданных(СсылкаРекурсии[ОбъектМетаданных.Имя]);
   СписокДляВыгрузки.Добавить()["Ссылка"]=СсылкаРекурсии[ОбъектМетаданных.Имя];
  КонецЕсли;
  
  
  СписокОбщий.Добавить()["Ссылка"]=СсылкаРекурсии[ОбъектМетаданных.Имя]; // Добавляем с список для ограничений общих рекурсий
 КонецЦикла; 
КонецПроцедуры


Функция ОпределитьНаличиеДвиженийПоРегистратору(ДокументСсылка)
 ТекстЗапроса = ""; 
 // для исключения падения для документов, проводящимся более чем по 256 таблицам
 счетчик_таблиц = 0;
 
 МетаданнныеДокумента = ДокументСсылка.Метаданные();
 
 Если МетаданнныеДокумента.Движения.Количество() = 0 Тогда
  Возврат Новый ТаблицаЗначений;
 КонецЕсли;
 
 Для Каждого Движение ИЗ МетаданнныеДокумента.Движения Цикл
  // в запросе получаем имена регистров, по которым есть хотя бы одно движение
  // например,
  // ВЫБРАТЬ Первые 1 «РегистрНакопления.ТоварыНаСкладах»
  // ИЗ РегистрНакопления.ТоварыНаСкладах
  // ГДЕ Регистратор = &Регистратор
  
  // имя регистра приводим к Строка(200), см. ниже
  ТекстЗапроса = ТекстЗапроса + "
  |" + ?(ТекстЗапроса = "", "", "ОБЪЕДИНИТЬ ВСЕ ") + "
  |ВЫБРАТЬ ПЕРВЫЕ 1 ВЫРАЗИТЬ(""" + Движение.ПолноеИмя() 
  +  """ КАК Строка(200)) КАК Имя ИЗ " + Движение.ПолноеИмя() 
  + " ГДЕ Регистратор = &Регистратор";
  
  // если в запрос попадает более 256 таблиц – разбиваем его на две части
  // (вариант документа с проведением по 512 регистрам считаем нежизненным)
  счетчик_таблиц = счетчик_таблиц + 1;
  Если счетчик_таблиц = 256 Тогда
   Прервать;
  КонецЕсли;
  
 КонецЦикла;
 
 Запрос = Новый Запрос(ТекстЗапроса);
 ЗАпрос.УстановитьПараметр("Регистратор", ДокументСсылка);
 // при выгрузке для колонки «Имя» тип устанавливается по самой длинной строке из запроса
 // при втором проходе по таблице новое имя может не «влезть», по этому сразу в запросе
 // приводится к строка(200)
 ТаблицаЗапроса = Запрос.Выполнить().Выгрузить();
 
 // если количество таблиц не превысило 256 – возвращаем таблицу
 Если счетчик_таблиц = МетаданнныеДокумента.Движения.Количество() Тогда
  Возврат ТаблицаЗапроса;   
 КонецЕсли;
 
 // таблиц больше чем 256, делаем доп. запрос и дополняем строки таблицы.
 
 ТекстЗапроса = "";
 Для Каждого Движение ИЗ МетаданнныеДокумента.Движения Цикл
  
  Если счетчик_таблиц > 0 Тогда
   счетчик_таблиц = счетчик_таблиц - 1;
   Продолжить;
  КонецЕсли;
  
  ТекстЗапроса = ТекстЗапроса + "
  |" + ?(ТекстЗапроса = "", "", "ОБЪЕДИНИТЬ ВСЕ ") + "
  |ВЫБРАТЬ ПЕРВЫЕ 1 """ + Движение.ПолноеИмя() +  """ КАК Имя ИЗ " 
  + Движение.ПолноеИмя() + " ГДЕ Регистратор = &Регистратор"; 
  
  
 КонецЦикла;
 Запрос.Текст = ТекстЗапроса;
 Выборка = Запрос.Выполнить().Выбрать();
 Пока Выборка.Следующий() Цикл
  СтрокаТаблицы = ТаблицаЗапроса.Добавить();
  ЗаполнитьЗначенияСвойств(СтрокаТаблицы, Выборка);
 КонецЦикла;
 
 Возврат ТаблицаЗапроса;
 
КонецФункции


Процедура ВыгрузкаДвижениеПоДокументу(Документ)
 
 //ДвиженияДокумента = Документ.Метаданные().Движения;
 
 
 Для каждого НаборЗаписей Из Документ.ПолучитьОбъект().Движения Цикл
  НаборЗаписей.Прочитать();
       СериализаторXDTO.ЗаписатьXML(Запись, НаборЗаписей);
   
 
 КонецЦикла;
 
 
 //ТаблицаДвижений = ОпределитьНаличиеДвиженийПоРегистратору(Документ);
 //
 //Для Каждого СтрокаТаблицыДвижений Из ТаблицаДвижений Цикл
 // 
 // СтрокаТаблицыДвижений.Имя = Врег(СокрЛП(СтрокаТаблицыДвижений.Имя));
 // 
 //КонецЦикла;
 //
 //Для Каждого СвойстваОбъекта Из ДвиженияДокумента Цикл
 // СтрокаВТаблицеРегистров = ТаблицаДвижений.Найти(Врег(СвойстваОбъекта.ПолноеИмя()), "Имя");
 // Если СтрокаВТаблицеРегистров = Неопределено Тогда
 //  Продолжить;
 // КонецЕсли;
 // 
 // 

 // //СериализаторXDTO.ЗаписатьXML(Запись, СтрокаВТаблицеРегистров);
 //КонецЦикла;
КонецПроцедуры

Процедура ОсновныеДействияФормыКнопкаВыгрузить(Кнопка)
 ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
 ДиалогОткрытияФайла.Заголовок = "Выберите файл xml";
 ДиалогОткрытияФайла.Фильтр = "Формат xml(*.xml)|*.xml";
 ДиалогОткрытияФайла.ПроверятьСуществованиеФайла = Истина;
 Если Не ДиалогОткрытияФайла.Выбрать() тогда
  возврат;
 КонецЕсли;
 
 
 
 
 Запись = Новый ЗаписьXML; 
 
 Запись.ОткрытьФайл(ДиалогОткрытияФайла.ПолноеИмяФайла);
 
 //записываем объявление xml файла:  
 Запись.ЗаписатьОбъявлениеXML(); 
 
 //записываем корневой элемент, по спецификации xml он может быть только один, назовем его "Данные" 
 Запись.ЗаписатьНачалоЭлемента("Данные"); 
 
 //для того чтобы пространства имен не объявлялись сериализатором в кажом элементе, пишем их в корневой элемент 
 //они будут работать на все вложеные элементы 
 //пространство имен по-умолчанию 
 Запись.ЗаписатьСоответствиеПространстваИмен("", "http://v8.1c.ru/8.1/data/enterprise/current-config"); 
 
 //пространства имен остальные префиксы 
 Запись.ЗаписатьСоответствиеПространстваИмен("xsd", "http://www.w3.org/2001/XMLSchema"); 
 Запись.ЗаписатьСоответствиеПространстваИмен("xsi", "http://www.w3.org/2001/XMLSchema-instance"); 
 Если ФлажокВыгрузкаСВязанных тогда
  ОбработкаМетаданных(ОбъектдляВыгрузки);
 КонецЕсли;
 
 
 Если  ФлажокВыгружатьПодчиненные тогда
  
  Запрос = Новый Запрос;
  Запрос.Текст = 
  "ВЫБРАТЬ
  | Ссылка
  |ИЗ
  | Справочник."+ОбъектдляВыгрузки.Метаданные().Имя+" КАК ЗапросПоСправочнику
  |ГДЕ
  | Родитель  В ИЕРАРХИИ(&Родитель)";
  
  Запрос.УстановитьПараметр("Родитель", ОбъектдляВыгрузки);
  Результат = Запрос.Выполнить();
  ВыборкаДетальныеЗаписи = Результат.Выбрать();  
  Пока ВыборкаДетальныеЗаписи.Следующий() Цикл   
   ОбработкаМетаданных(ВыборкаДетальныеЗаписи.Ссылка);
   СписокДляВыгрузки.Добавить()["Ссылка"]=(ВыборкаДетальныеЗаписи.Ссылка);
  КонецЦикла;
 КонецЕсли;
 
 Если ФлажокВыгружатьПоВладельцу тогда
  
  Для Каждого МетаданныеСправочника Из метаданные.Справочники Цикл
   Для Каждого Владелец Из МетаданныеСправочника.Владельцы Цикл 
    Если Владелец = ОбъектдляВыгрузки.Метаданные() тогда
     Запрос = Новый Запрос;
     Запрос.Текст = 
     "ВЫБРАТЬ
     | Ссылка
     |ИЗ
     | Справочник."+МетаданныеСправочника.Имя+" КАК ЗапросПоСправочнику
     |ГДЕ
     | Владелец В ИЕРАРХИИ(&Владелец)";
     
     Запрос.УстановитьПараметр("Владелец", ОбъектдляВыгрузки);
     Результат = Запрос.Выполнить();
     ВыборкаДетальныеЗаписи = Результат.Выбрать();  
     Пока ВыборкаДетальныеЗаписи.Следующий() Цикл   
      ОбработкаМетаданных(ВыборкаДетальныеЗаписи.Ссылка);
      СписокДляВыгрузки.Добавить()["Ссылка"]=(ВыборкаДетальныеЗаписи.Ссылка);
     КонецЦикла;
    КонецЕсли;
   КонецЦикла;
  КонецЦикла;
  
 КонецЕсли;
 
 Если ФлажокВыгружатьДвиженияДокумента тогда
  ВыгрузкаДвижениеПоДокументу(ОбъектдляВыгрузки);
 КонецЕсли;
 
 СписокДляВыгрузки.Свернуть("Ссылка");
 Для Каждого СтрокаТаблицы Из  СписокДляВыгрузки Цикл
  СериализаторXDTO.ЗаписатьXML(Запись, СтрокаТаблицы["Ссылка"].ПолучитьОбъект());  
 КонецЦикла;
 
 СериализаторXDTO.ЗаписатьXML(Запись, ОбъектдляВыгрузки.ПолучитьОбъект()); 
 
 
 //записываем конец корневого элемента 
 Запись.ЗаписатьКонецЭлемента(); 
 Запись.Закрыть();
 //Заменить(ФЛ);
 
КонецПроцедуры

Процедура ОсновныеДействияФормыКнопкаЗагрузить(Кнопка)
 ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
 ДиалогОткрытияФайла.Заголовок = "Выберите файл xml";
 ДиалогОткрытияФайла.Фильтр = "Формат xml(*.xml)|*.xml";
 ДиалогОткрытияФайла.ПроверятьСуществованиеФайла = Истина;
 Если Не ДиалогОткрытияФайла.Выбрать() тогда
  возврат;
 КонецЕсли;
 Чтение = Новый ЧтениеXML;
 Чтение.ОткрытьФайл(ДиалогОткрытияФайла.ПолноеИмяФайла);
 //прочитаем начало xml файла 
 Чтение.ПерейтиКСодержимому(); 
 
 //прочитаем начало корневого элемента 
 Чтение.Прочитать(); 
 
 //читаем содержимое пока текущим не станет конец корневого элемента, т.к. мы писали туда только целые элементы справочника, 
 //а сериализатор читает каждый из их полностью, то мы упремся именно в конец корневого 
 ЗагруженоОбъектов=0;
 НачатьТранзакцию();
 Пока Чтение.ТипУзла<>ТипУзлаXML.КонецЭлемента Цикл 
  ЗагруженоОбъектов = ЗагруженоОбъектов+1;
  Если ЗагруженоОбъектов%1000 тогда
   ЗафиксироватьТранзакцию();
   НачатьТранзакцию();
  КонецЕсли;
  //читаем очередной элемент справочника 
  Объект = СериализаторXDTO.ПрочитатьXML(Чтение); 
  Объект.ОбменДанными.Загрузка = Истина;
  Объект.Записать();
  //покажем что прочитали, осталось только записать объект 
  Сообщить(""+ТипЗнч(Объект)+" - "+Объект); 
 КонецЦикла; 
 ЗафиксироватьТранзакцию();
 Чтение.Закрыть();
КонецПроцедуры

Процедура ОбъектдляВыгрузкиПриИзменении(Элемент)
 Если Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(ОбъектдляВыгрузки)) тогда
  ЭтаФорма.ЭлементыФормы.ФлажокВыгружатьПодчиненные.Доступность = Истина;
  ЭтаФорма.ЭлементыФормы.ФлажокВыгружатьПоВладельцу.Доступность = Истина;
 Иначе
  ЭтаФорма.ЭлементыФормы.ФлажокВыгружатьПодчиненные.Доступность = Ложь;
  ЭтаФорма.ЭлементыФормы.ФлажокВыгружатьПоВладельцу.Доступность = Ложь;
 КонецЕсли;
КонецПроцедуры


СписокДляВыгрузки = новый ТаблицаЗначений;
СписокДляВыгрузки.Колонки.Добавить("Ссылка");

СписокОбщий = новый ТаблицаЗначений;
СписокОбщий.Колонки.Добавить("Ссылка");

Запись = Новый ЗаписьXML; 

No comments:

Post a Comment