Автоматизация обмена между базами используя обработку "Универсальный обмен данными в формате XML"

Обмен - Обмен через XML

В основу данной публикации положены найденные мною материалы по созданию обмена между двумя базами с использованием обработки "Универсальный обмен данными в формате XML". Но предлагается вариант автоматизации решения задачи, которая позволяет выполнять обмен неквалифицированным пользователям, либо по регламенту. Скажем, такой обмен применим, если вы не можете по ряду причин использовать РБД, либо у вас совсем разные конфигурации баз (случаи бывают разные, а хочется максимально настраиваемой гибкости).

Вначале, безусловно, воспользуемся конфигурацией "Конвертация данных", чтобы создать необходимые нам правила обмена (как - это отдельная тема).

Итак, собственно сама ВЫГРУЗКА: 

 Обработка = Обработки.УниверсальныйОбменДаннымиXML.Создать();
 
Обработка.РежимОбмена = "Выгрузка";
 
Обработка.ВыводВОкноСообщенийИнформационныхСообщений = Истина;

При необходимости можно задать период выгрузки (как пример):

 Обработка.ДатаНачала  = ТекущаяДата();
 
Обработка.ДатаОкончания   = ТекущаяДата();

 
Обработка.ИмяФайлаПравилОбмена = "D:\ПравилаОбменаДанными.xml";

 Источник = ЭтотОбъект.Ссылка;
 ИмяФайла = Строка(ТипЗнч(Источник)) + " " + Строка(Источник.Номер);
 
Обработка.ИмяФайлаОбмена = "D:\E\"+ Источник +".xml";
 

 Обработка.ЗагрузитьПравилаОбмена(); 

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

Обработка.ВыполнитьВыгрузку();

Настройка ОТБОРА:
Тут надо обратить внимание на массив "ВременнаяТаблицаПравил.Строки[1]" и в частности на индекс массива строк,
1 - это ветка "Справочники". Ну и так далее по аналогии              

ВременнаяТаблицаПравил = Обработка.ТаблицаПравилВыгрузки.Скопировать();
 Для Каждого
СтрокаУровня2 Из ВременнаяТаблицаПравил.Строки[1].Строки Цикл
    
Наименование = СтрокаУровня2.Имя;
     Если
Наименование <> "ПеремещениеТоваров00001" Тогда
        
СтрокаУровня2.Включить = 0;
     КонецЕсли;
 КонецЦикла;
 Для Каждого
СтрокаУровня2 Из ВременнаяТаблицаПравил.Строки[2].Строки Цикл
    
Наименование = СтрокаУровня2.Имя;
     Если
Наименование <> "ПеремещениеТоваров00001" Тогда
        
СтрокаУровня2.Включить = 0;
     КонецЕсли;
 КонецЦикла;

Здесь вы определяете искомое правило выгрузки, которое нужно оставить включенным на определенной ветке (сами можете варьировать чего и сколько):

 Для Каждого СтрокаУровня2 Из ВременнаяТаблицаПравил.Строки[0].Строки Цикл
   
Наименование = СтрокаУровня2.Имя;
    Если
Наименование = "ПеремещениеТоваров00001" Тогда
       
СтрокаУровня2.Включить = 1;
    Иначе
       
СтрокаУровня2.Включить = 0;
    КонецЕсли;
 КонецЦикла;
 
Обработка.ТаблицаПравилВыгрузки = ВременнаяТаблицаПравил.Скопировать();

Теперь настраиваем ОТБОР, смысл которого в том, чтобы передать в нашу выгрузку ссылку на документ(ты) который(е) хотим выгрузить:

Для Каждого СтрокаУровня2 Из ВременнаяТаблицаПравил.Строки[0].Строки Цикл
 
Наименование = СтрокаУровня2.Имя;
  Если
Наименование = "ПеремещениеТоваров00001" Тогда
 
ТекущееПВД = СтрокаУровня2;

    
Построитель = Новый ПостроительОтчета;
     Если
ТекущееПВД.ИмяОбъектаДляЗапроса <> Неопределено Тогда

        
Построитель.Текст =
        
"ВЫБРАТЬ Разрешенные _.* ИЗ " + ТекущееПВД.ИмяОбъектаДляЗапроса + " КАК _
          |
          |
          |{ГДЕ _.Ссылка.* КАК "
+ СтрЗаменить(ТекущееПВД.ИмяОбъектаДляЗапроса, ".", "_") + "}";
     КонецЕсли;

    
Отбор = Построитель.Отбор;

     Если
Отбор.Найти("Документ_ПеремещениеТоваров") = Неопределено Тогда
       
Отбор.Добавить("Документ_ПеремещениеТоваров");
     КонецЕсли;

    
Массив = Новый Массив;
    
Массив.Добавить(Тип("ДокументСсылка.ПеремещениеТоваров"));
    
ОписаниеТиповС = Новый ОписаниеТипов(Массив, , );

    
Отбор["Документ_ПеремещениеТоваров"].Использование = Истина;
    
Отбор["Документ_ПеремещениеТоваров"].Значение = ЭтотОбъект.Ссылка;
    
Отбор["Документ_ПеремещениеТоваров"].ВидСравнения = ВидСравнения.Равно;

    
ДоступностьПостроителя = Истина;
     Если
Построитель.Отбор.Количество() > 0 Тогда
         
ТекущееПВД.НастройкиПостроителя = Построитель.ПолучитьНастройки();
        
ТекущееПВД.ИспользоватьОтбор    = ИСТИНА;
     КонецЕсли;
  КонецЕсли;
КонецЦикла;

Обработка.ТаблицаПравилВыгрузки = ВременнаяТаблицаПравил.Скопировать();

Ну и, собственно, запускаем саму выгрузку и получаем файл для загрузки:

  Обработка.АрхивироватьФайл = Истина;
  Обработка.ВыполнитьВыгрузку();

Далее процесс загрузки:
Он довольно прост

МассивФайлов = НайтиФайлы("D:\E\", "*.zip");
Для Каждого
Стм Из МассивФайлов Цикл
ТекстВопроса = "Загрузить - " + Стм.ПолноеИмя;
Ответ = Вопрос(ТекстВопроса, РежимДиалогаВопрос.ДаНет,, КодВозвратаДиалога.Да);
    Если
Ответ = КодВозвратаДиалога.Да Тогда
       
Обработка  = Обработки.УниверсальныйОбменДаннымиXML.Создать();
       
Обработка.ИмяФайлаОбмена = Стм.ПолноеИмя;
       
Обработка.РежимОбмена    = "Загрузка";
       
Обработка.ЗаписыватьРегистрыНаборамиЗаписей = Истина;
       
Обработка.ЗаписыватьВИнформационнуюБазуТолькоИзмененныеОбъекты = Истина;
       
Обработка.ЗагружатьДанныеВРежимеОбмена = Истина;
       
Обработка.ВыполнитьЗагрузку();
       
УдалитьФайлы(Стм.ПолноеИмя);
    КонецЕсли;
КонецЦикла;

Расширение .zip для файлов обмена пусть вас не смущает, обработка самостоятельно упакует .xml файл в архив:

 Обработка.АрхивироватьФайл = Истина;

И также самостоятельно уже без дополнительных указаний распакует и загрузит. Это существенно уменьшает размеры файла обмена.

Вот примерно так можно поступить.

Продолжение темы :

//infostart.ru/public/87057/

Скачать файлы

Наименование Файл Версия Размер
Вариант статьи для скачивания
.doc 44,00Kb
30.06.11
297
.doc 44,00Kb 297 Скачать

См. также

Вознаграждение за ответ
Показать полностью
Комментарии
1. Владимир Самойлов (samamoiloff) 858 12.06.11 19:23 Сейчас в теме
Отбор["Документ_ПеремещениеТоваров"].Значение = ЭтотОбъект.Ссылка;

Пример выгрузки из документа получается?
2. Владислав Лаврухин (wiranata) 238 13.06.11 20:31 Сейчас в теме
Завтра выложу пример (обработку).

(1)Не совсем понял в чем вопрос, если вы имеете ввиду вигрузку только табличной части документа (скажем товары) в другой документ либо такой же но с обработкой этих данных - то это надо описывать в обработчиках событий в Конвертации данных (когда будите писать правила обмена). Я только показал как сделать некий регламент обмена а не запрограммировать его логику (это отдельная тема).
3. Владимир (ARL) 252 16.06.11 18:06 Сейчас в теме
Информация удобная, автору благодарность.
Мне потребовалось выгружать по плану обмена. Поэтому немного добавлю:
НашУзел = ПланыОбмена.ХХХХ.НайтиПоКоду("2");
УстановитьУзелОбменаУСтрокДерева(Обработка.ТаблицаПравилВыгрузки.Строки, НашУзел);
Процедуру УстановитьУзелОбменаУСтрокДерева просто копируем из формы обработки.
antonio_i; tatarenko.an; +2 Ответить
4. Дмитрий Гомзин (plevakin) 20.06.11 16:32 Сейчас в теме
(1)Не совсем понял в чем вопрос

Насколько я понял данный пример в отборе отбирает только один документ, что на практике бывает редко. Попробовал изменить строки на
Отбор["Документ_РеализацияТоваровУслуг"].ВидСравнения = ВидСравнения.ВСписке;
Отбор["Документ_РеализацияТоваровУслуг"].Значение = Массив;

где Массив это мой программно создаваемый список значений заполненный ссылками на документ. Ничего не получилось.
Завтра выложу пример (обработку).

Можно в качестве примера указать выгрузку списка документов. Думаю формирование списка каждый может сделать под себя, и по дате и по контрагенту и по чему угодно.
5. Владимир (ARL) 252 24.06.11 13:38 Сейчас в теме
(4) Отбор["Документ_РеализацияТоваровУслуг"].Значение = Массив.Скопировать();
где Массив имеет тип СписокЗначений.
6. Дмитрий Гомзин (plevakin) 24.06.11 13:53 Сейчас в теме
 Отбор = Построитель.Отбор;

     Если Отбор.Найти("Документ_РеализацияТоваровУслуг") = Неопределено Тогда
        Отбор.Добавить("Документ_РеализацияТоваровУслуг");
     КонецЕсли;

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

После этих строк смотрю в отладчике отбор и вижу



Выгружено объектов 0.
skiller3000; +1 Ответить 1
7. Владислав Лаврухин (wiranata) 238 24.06.11 18:47 Сейчас в теме
(6) Как я понял проблема настроить отбор в варианте "ВСписке" программно... обработку не буду ради это писать... но где то так:

Структура = Новый СписокЗначений;

Запрос = Новый Запрос();
Запрос.Текст =
"ВЫБРАТЬ
| ПеремещениеТоваров.Ссылка,
| ПеремещениеТоваров.Дата
|ИЗ
| Документ.ПеремещениеТоваров КАК ПеремещениеТоваров
|ГДЕ
| ПеремещениеТоваров.Дата МЕЖДУ &датаНачала И &датаКонца";

Запрос.УстановитьПараметр("ДатаНачала", НачалоМесяца(ТекущаяДата()));
Запрос.УстановитьПараметр("ДатаКонца", ТекущаяДата());
Структура = Запрос.Выполнить().Выгрузить();


Отбор["Документ_ПеремещениеТоваров"].Использование = Истина;
Отбор["Документ_ПеремещениеТоваров"].ВидСравнения = ВидСравнения.ВСписке;//Равно;
Отбор["Документ_ПеремещениеТоваров"].Значение.ЗагрузитьЗначения(Структура.ВыгрузитьКолонку("Ссылка"));//Источник;


Вот так список значений заполняется, я детально не встраивал в обработку но вызвав форму обработки видел что список значений заполнился ссылками, по ошибке ничего не вывалилось.
8. Мира Александрова (mirkomp) 22.12.11 00:26 Сейчас в теме
Данная методика будет работать с выгрузкой из базы в которой две организации (ИП и ООО)? конф УТ ред 11 (управляемое приложение)
9. Харьков Харьков (xaker1C) 22.12.11 04:51 Сейчас в теме
спасибо очень помогло правда пришлось с легка модифицировать
10. Владислав Лаврухин (wiranata) 238 23.12.11 22:02 Сейчас в теме
(8) Данная методика будет работать не зависимо от форм отганизационно-правовой формы. Но на версии УТ 11 я ее не тестировал за неимением (Конфигурации где будет работать написаны в заголовке).
11. 1CProfessional (Paul_Nevada) 05.01.12 23:41 Сейчас в теме
Привет! Спасибо за тему - очень актуальная для меня оказалась. Такой вопрос - можно ли этот "кусок" развить до полуавтоматического общения двух идентичных БД via e-mail?
12. Владислав Лаврухин (wiranata) 238 07.01.12 13:39 Сейчас в теме
(11) Привет! количества вариантов (автоматического, например как у меня по регламенту... много, надо будет дописать схему реализации) ограниченно лишь функционалом самой 1С. Там есть возможность авто пересылки сообщений и их автоматического приема и обработки НО! данная обработка "вытаскивает" весь объект вместе с подчиненными ссылками и в итоге мы получаем файл где то на 60 метров (и это в архиве!).
Можно правилами обмена пробовать ограничивать объем выгрузки но тогда не факт что мы в пакете обмена будем иметь весь объем необходимой инфы.
По этому почта возможна но... как неполноценный по эффективности вариант когда имеет дело с файлом сформированным описанной обработкой... но попытка не пытка, это лишь мое мнение.
13. Макс Такойто (Maks888) 1 01.02.12 09:42 Сейчас в теме
Хочу поблагодарить автора! Очень и очень замечательную вещь выложили! Буквально меня спасли =) очень сократил время на разработку! + 10 !!!
16. Нина (нинас) 03.04.12 09:22 Сейчас в теме
17. Денис Новосёлов (binex) 213 28.05.12 15:24 Сейчас в теме
Я не пойму зачем нужно копировать ТаблицуПравилВыгрузки? Почему бы сразу в неё изменения не вносить?
18. Владислав Лаврухин (wiranata) 238 29.05.12 10:32 Сейчас в теме
(17) Публикация не подвергалась оптимизации если вам так удобнее то почему нет.. тут лишь изложена одна из идей обмена а не обработки данных в процессе этого обмена.
19. Денис Новосёлов (binex) 213 29.05.12 10:36 Сейчас в теме
Спасибо! Статья помогла.
20. Галя (galyausik1) 11.07.12 16:22 Сейчас в теме
Спасибо! Очень полезная статейка
21. Андрей Гореликов (alon) 162 31.07.12 17:08 Сейчас в теме

Обработка.ВыполнитьЗагрузку();
УдалитьФайлы(Стм.ПолноеИмя);


У вас не возникает ошибки совместного доступа к файлу в последней строке?
22. Владислав Лаврухин (wiranata) 238 31.07.12 20:33 Сейчас в теме
(21)Нет не возникает, а должно?
23. uri1978 uri1978 (uri1978) 107 16.10.13 12:27 Сейчас в теме
Спасибо за статью. Подтолкнули на мысль, использовал в работе. Очень пригодилось.
24. Александр Жерздев (Al777) 04.12.14 10:22 Сейчас в теме
Спасибо за статью! Как раз возникла необходимость постоянной перегрузки документов из одной базы в другую через универсальный отчет.
25. andrey dyak (dyak84) 04.01.15 09:55 Сейчас в теме
Спасибо буду пробовать, интересная статья
26. Игорь Steelvan (Steelvan) 30 05.02.15 12:53 Сейчас в теме
...применим если вы не можите...

*можЕте
27. Виталий Васильев (orfos) 28 14.02.15 15:47 Сейчас в теме
А как настроить отбор только по справочникам (у)??
28. Ден (lion11) 139 24.08.15 16:36 Сейчас в теме
Можете подсказать, как сделать то же самое, но только в УФ? Есть внешняя обработка на УФ с кнопкой выгрузить, по нажатию на которую нужно выгрузить по правилу обмена используя обработку УниверсальныйОбменДаннымиXML на УФ, например, в БП3.
Не актуально, разобрался.
29. василий василюк (nef744) 02.09.15 18:54 Сейчас в теме
30. Гость 02.03.16 14:38 Сейчас в теме
Всё работает, но возникает проблема с добавлением отбора на регистр сведений, у кого нибудь есть пример кода?
31. Олег Шокин (skiller3000) 120 13.07.16 15:32 Сейчас в теме
(7) wiranata, еще дело может быть в отсутствии галочки у корневых разделов ПВД (Справочники, Документы), при установленной галке в строках этих разделов.
32. Александр Бисюков (AlekSo) 07.10.16 10:46 Сейчас в теме
(30) Гость,
Вряд ли кто нибудь теперь уже ответит.
Тоже бьюсь над этим - как отобрать независимые регистры сведений?
В частности нужно отобрать по периоду или по дате ключевого документа.
33. Александр Бисюков (AlekSo) 11.10.16 08:37 Сейчас в теме
Если кому ещё интересно.

В самой обработке универсального обмена в модуле формы есть процедура НастроитьПостроитель().
Оттуда можно выдернуть нужные строки.

коротко вот пример для независимого периодического регистра сведений:

Функция УстановитьОтборПериодическимРС(ВнешняяОбработкаОбмена, ИмяРегистра)
	СтрокаГруппыДокументов = ВнешняяОбработкаОбмена.ТаблицаПравилВыгрузки.Строки.Найти("РегистрыСведений");
	СтрокаПВД = СтрокаГруппыДокументов.Строки.Найти(ИмяРегистра);
	
        ИмяПВД = СтрокаПВД.ИмяОбъектаДляЗапросаРегистра;

	Построитель.Текст = "ВЫБРАТЬ Разрешенные
	 |   *,
	 |	NULL КАК Активность,
	 |	NULL КАК Регистратор,
	 |  NULL КАК НомерСтроки       
	 |
	 |ИЗ "+ИмяПВД;
	 
	Построитель.ЗаполнитьНастройки();
	
	ЭлемОтбора = Построитель.Отбор.Добавить("Период");
	Если ЭлемОтбора = Неопределено Тогда
		Сообщить("Не удалось настроить ОТбор по документам");
	КонецЕсли;
	
	ЭлемОтбора.ВидСравнения  = ВидСравнения.ИнтервалВключаяГраницы;
	ЭлемОтбора.ЗначениеС     = НачПериода;
	ЭлемОтбора.ЗначениеПо    = КонПериода;
	ЭлемОтбора.Использование = Истина;
	
	СтрокаПВД.НастройкиПостроителя = Построитель.ПолучитьНастройки();
	СтрокаПВД.ИспользоватьОтбор    = ИСТИНА;
	
	Возврат Истина;
КонецФункции
...Показать Скрыть

Здесь важно брать именно ИмяОбъектаДляЗапросаРегистра.
34. Артём Шалнев (88wau24ru) 10 26.03.17 20:54 Сейчас в теме
Для Каждого СтрокаУровня1 Из ТаблицаПравилВыгрузки.Строки Цикл
	Для Каждого СтрокаУровня2 Из ТаблицаПравилВыгрузки.Строки[0].Строки Цикл
		Наименование = 	СтрокаУровня2.Имя;
		Если Наименование = "ВозвратТоваровОтПокупателя" Тогда
			Построитель = Новый ПостроительОтчета;
			Если СтрокаУровня2.ИмяОбъектаДляЗапроса <> Неопределено Тогда
			Построитель.Текст =
			"ВЫБРАТЬ Разрешенные _.* ИЗ " + СтрокаУровня2.ИмяОбъектаДляЗапроса + " КАК _
			|{ГДЕ _.Ссылка.* КАК " + СтрЗаменить(СтрокаУровня2.ИмяОбъектаДляЗапроса, ".", "_") + "}";
			КонецЕсли;
			Отбор = Построитель.Отбор;
			Если Отбор.Найти("Документ_ВозвратТоваровОтПокупателя") = Неопределено Тогда
				Отбор.Добавить("Документ_ВозвратТоваровОтПокупателя");
			КонецЕсли;
			СписокДокументов = Новый СписокЗначений;
			Отбор["Документ_ВозвратТоваровОтПокупателя"].Использование	= Истина;
			Отбор["Документ_ВозвратТоваровОтПокупателя"].ВидСравнения	= ВидСравнения.ВСписке;
			Отбор["Документ_ВозвратТоваровОтПокупателя"].Значение		= СписокДокументов;
			ДоступностьПостроителя = Истина;
			Если Построитель.Отбор.Количество() > 0 Тогда
				СтрокаУровня2.НастройкиПостроителя = Построитель.ПолучитьНастройки();
				СтрокаУровня2.ИспользоватьОтбор    = Ложь;
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
КонецЦикла;
...Показать Скрыть

Работает, Спасибо! А нет возможности добавить реквизит в отбор?
Примерно следущее?
Отбор["Документ_ВозвратТоваровОтПокупателя.Организация"].Использование	= Истина;
Отбор["Документ_ВозвратТоваровОтПокупателя.Организация"].ВидСравнения	= ВидСравнения.ВСписке;
Отбор["Документ_ВозвратТоваровОтПокупателя.Организация"].Значение		= ПланыОбмена.ОбменУправлениеТорговлейБухгалтерияКОРП.НайтиПоКоду("002").Организации.ВыгрузитьКолонку("Организация");
35. Артём Шалнев (88wau24ru) 10 27.03.17 07:57 Сейчас в теме
Если Отбор.Найти("Документ_ВозвратТоваровОтПокупателя.Организация") = Неопределено Тогда
   Отбор.Добавить("Документ_ВозвратТоваровОтПокупателя.Организация");
КонецЕсли;

Отбор добавляется но при
Отбор["Документ_ВозвратТоваровОтПокупателя.Организация"].Использование    = Истина;

выводится ошибка
36. Артур Андреевич (Butuff) 15.04.17 12:45 Сейчас в теме
(33) а есть пример выгрузки только измененных записей регистра сведений? (не периодического и без регистратора)
Оставьте свое сообщение