Реализация обмена данными в цикле обработки

1. Skellar 27 30.10.12 15:20 Сейчас в теме
Всем доброго времени суток, столкнулся с такой задачей - мне нужно из одной базы делать выгрузки по разным правилам в несколько других баз.
Сделал обработку, в ней в цикле пускаю :

Обработка = Обработки.УниверсальныйОбменДаннымиXML.Создать();
......
Обработка.ВыполнитьВыгрузку();

При этом для одной(любой) базы обработка работает, для двух и более - нет. Более того, чтобы сделать выгрузку в другую базу приходится открывать и закрывать текущую, потом запускать обработку заново.

Подскажите, что делать? Может мне деструктора какого не хватает, или временные файлы не убиваются?
По теме из базы знаний
Вознаграждение за ответ
Показать полностью
Найденные решения
26. lgg 20 05.11.12 18:18 Сейчас в теме
Приблизительно так:
//В эту комендную строку можно включить любуе дополнительные параметры,
//которые передаются как параметры запуска сеанса
//мой параметр имеет имя КодНастройкиОбменаДанными и передаю я код узла обмена,
//но можно и по-другому
ДополнительнаяКоманднаяСтрока = "/C" + "КодНастройкиОбменаДанными=""" + СокрЛП(КодУзлаОбменаКоторыйНужноЗапуститьПослеПерезапускаСеанса);

//Выполняем перезапуск клиента с последующим повторным чтение сообщения
ЗавершитьРаботуСистемы(Истина, Истина, ДополнительнаяКоманднаяСтрока);

//В модуле приложения ПриНачалеРаботыСистемы() этот параметр нужно обработать:
Если Найти(ПараметрЗапуска, "КодНастройкиОбменаДанными") > 0 Тогда
// Проверим необходимость обмена
ПроцедурыОбменаДанными.ПроверкаНеобходимостиОбмена();
КонецЕсли;
//В модуле ПроцедурыОбменаДанными
Процедура ПроверкаНеобходимостиОбмена()
// Если в параметре запуска ничего не передано...
Если ПараметрЗапуска = "" Тогда
Возврат;
КонецЕсли;
// Формируем доп. командную строку для перезапуска клиента
СтрокаПараметра = ПараметрЗапуска;

// Если в параметре командной строки не передан код элемента справочника НастройкиОбменаДанными
//КодНастройкиОбменаДанными

КодУзлаОбмена = ИзвлечьПараметрИзСтрокиПараметраКоманднойСтроки("КодНастройкиОбменаДанными", СтрокаПараметра);
Если КодНастройкиОбменаДанными = Неопределено Тогда
Возврат;
КонецЕсли;

//Вызываем необходимые процедуры обмена
//.....


КонецПроцедуры


Функция ИзвлечьПараметрИзСтрокиПараметраКоманднойСтроки(ИмяПараметра, Знач СтрокаПараметра)

Префикс = СтрДлина(ИмяПараметра + "=""");
ДлинаПрефикса = СтрДлина(ИмяПараметра + "=""");
ПозицияИмяПараметра = Найти(СтрокаПараметра, ИмяПараметра);
ДлинаСтрокаПараметра = СтрДлина(СтрокаПараметра);
Если ДлинаСтрокаПараметра <= ДлинаПрефикса ИЛИ ПозицияИмяПараметра = 0 Тогда
Возврат Неопределено;
КонецЕсли;

ПозицияЗапятой = Найти(СтрокаПараметра, """,");
Пока 1=1 Цикл
Если ПозицияЗапятой = 0 ИЛИ ПозицияЗапятой > ПозицияИмяПараметра Тогда
Прервать;
КонецЕсли;
//СтрокаПараметра = Лев(СтрокаПараметра, ПозицияЗапятой - 1) + Сред(СтрокаПараметра, ПозицияЗапятой + 1,


КонецЦикла;
ДлинаКода = ?(ПозицияЗапятой = 0, СтрДлина(СтрокаПараметра), ПозицияЗапятой - 1) - ДлинаПрефикса;

Возврат Сред(СтрокаПараметра, ДлинаПрефикса + 1, ДлинаКода);

КонецФункции
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
7. sergik_nsk 148 31.10.12 14:07 Сейчас в теме
(1) Skellar, все должно работать, проверь "что именно" ты создаещь, подобные вещи когда то давно делал, все было в порядке, жалко код не сохранился, отладчик в зубы и проверяй где валиться, будет конкретика - будут ответы!
2. znaher 30.10.12 15:34 Сейчас в теме
Ну может организовать регистр какой-нить, где будет хранится Правила_Обмена и пути куда сейвить. Будешь читать этот регистр и по циклу проходить что то типо:
Результат = Запрос.Выполнить();
Пока Результат.Следующий() Цикл
Обработка = Обработки.УниверсальныйОбменДаннымиXML.Создать();


Обработка.ИмяФайлаПравилОбмена = Результат.ИмяВременногоФайлаПравилОбмена;
Обработка.ЗагрузитьПравилаОбмена();

Обработка .ИмяФайлаОбмена = Результат.ФайлВыгрузки;
......
Обработка.ВыполнитьВыгрузку();
.....
3. Skellar 27 30.10.12 16:38 Сейчас в теме
А что это изменит? У меня обмен не через файл и Имена правил обмена всегда уникальные :

Обработка.НепосредственноеЧтениеВИБПриемнике = Истина;


Если правило = "1" тогда

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

Обработка.КаталогИнформационнойБазыДляПодключения = ПутьК_БД1;


КонецЕсли;

Если правило = "2" тогда

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

Обработка.КаталогИнформационнойБазыДляПодключения = ПутьК_БД2;


КонецЕсли;


Обработка.ЗагрузитьПравилаОбмена();
Обработка.ВыполнитьВыгрузку();
4. Skellar 27 31.10.12 12:28 Сейчас в теме
Ну же, никто не знает? При попытке использования стандартную Обработку УниверсальныйОбменДаннымиXML при прямой передаче поочередно в несколько баз тоже появляется ошибка.
5. deniseek77 86 31.10.12 12:56 Сейчас в теме
Может Обработка = Обработки.УниверсальныйОбменДаннымиXML.Создать(); перед циклом писать?..
6. Skellar 27 31.10.12 13:26 Сейчас в теме
Пробовал создавать обработку в цикле и там же делать Обработка=Неопределено, пробовал создать 1 обработку до цикла, а в цикле менять параметры. В стандартной выгрузке создаются COM объекты, но почему-то они получаются разными: на 1ом шаге-правильно, на 2ом шаге-не правильно.
8. Skellar 27 31.10.12 14:35 Сейчас в теме
Валится в куске 1совской стандартной обработки УниверсальныйОбменДаннымиXML:

ОбъектПодключения = "V82"+".COMConnector";
ТекCOMПодключение = Новый COMОбъект(ОбъектПодключения);
ТекCOMОбъект = ТекCOMПодключение.Connect(СтрокаПодключения);

РезультатПодключения=ТекCOMОбъект.Обработки.УниверсальныйОбменДаннымиXML.Создать();
..
мОбработкаДляЗагрузкиДанных = РезультатПодключения;

Только вот получается, что при втором проходе у созданного кома "сдвинутые" свойства, что и провоцирует ошибки, видимо.

Если интересно - приложил картинки получающихся комов (1- на 1ом шаге,правильно, 2-на 2ом шаге,не правильно).
1-
2-
9. sergik_nsk 148 31.10.12 14:39 Сейчас в теме
а это что такое?
(8) Skellar,
РезультатПодключения=ОбъектПодключения.Обработки.УниверсальныйОбменДаннымиXML.Создать();
разве
ОбъектПодключения не строка?
10. Skellar 27 31.10.12 14:42 Сейчас в теме
(9) sergik_nsk, Ошибся когда сообщение писал, ОбъектПодключения - COM
13. sergik_nsk 148 31.10.12 15:04 Сейчас в теме
да есть конечно, ну так вы же свой цикл сами писали, проблема не в стандартной обработке а в вашем цикле вот его и покажите в (8) только кусок
14. Skellar 27 31.10.12 15:16 Сейчас в теме
(13)Процедура в цикле
Процедура ВыполнитьОбменЗаказчиков(правило)

Обработка = Обработки.УниверсальныйОбменДаннымиXML.Создать();


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



Если правило = "1" тогда

Обработка.ИмяФайлаПравилОбмена = "1.xml";

Обработка.КаталогИнформационнойБазыДляПодключения = Путь1;


КонецЕсли;



Если правило = "2" тогда

Обработка.ИмяФайлаПравилОбмена = "2.xml";

Обработка.КаталогИнформационнойБазыДляПодключения = Путь2;


КонецЕсли;


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

Строка = Обработка.ТаблицаНастройкиПараметров.Найти("РаспределениеУслуг");

Попытка
Строка.Значение = РаспределениеУслуг;
Исключение
КонецПОпытки;

Обработка.АутентификацияWindowsИнформационнойБазыДляПодключения=Ложь;
Обработка.ПользовательИнформационнойБазыДляПодключения = "Dump";
Обработка.ПарольИнформационнойБазыДляПодключения = "Dump";
обработка.ВерсияПлатформыИнформационнойБазыДляПодключения="V82";

Обработка.НепосредственноеЧтениеВИБПриемнике = Истина;

Обработка.ВыводВПротоколСообщенийОбОшибках = Ложь;
Обработка.ДописыватьДанныеВПротоколОбмена = Истина;
обработка.ЗагружатьДанныеВРежимеОбмена = Истина;
Обработка.ТипИнформационнойБазыДляПодключения=ложь;



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

Обработка=неопределено;

КонецПроцедуры



Здесь я просто вызываю стандартную обработку, все варится уже в ней. Собственно у меня и просто запущенная обработка не работает если попробовать 2 раза подряд выгрузить в разные базы. Выгружаю из БП 1.6 в БП 1.6 и БП 2.0
11. sergik_nsk 148 31.10.12 14:48 Сейчас в теме
хотелось бы тогда увидеть весь кусок по созданию кома, хотя уже есть подазрения, что надо делать не так
12. Skellar 27 31.10.12 14:56 Сейчас в теме
(11) sergik_nsk, у вас под рукой есть какая-нибудь типовая база? Бухгалтерия, или Торговля 10, например. У них есть типовая обработка УниверсальныйОбменДаннымиXML, там все начинается на строке 12485 (мОбработкаДляЗагрузкиДанных = ВыполнитьПодключениеКИБПриемнику(); ).
Могу и сюда куски кода выкладывать, но боюсь получится сложночитаемо.
15. sergik_nsk 148 31.10.12 15:29 Сейчас в теме
для начала проверь так
обработка.ЗагружатьДанныеВРежимеОбмена = Ложь;
17. Skellar 27 31.10.12 15:50 Сейчас в теме
(15) sergik_nsk, нет, не помогло) Всегда одна и та же ошибка: {Обработка.УниверсальныйОбменДаннымиXML(12351)}: Ошибка при вызове метода контекста (ВыполнитьДействияПослеЗавершенияЧтенияДанных)
мОбработкаДляЗагрузкиДанных.ВыполнитьДействияПослеЗавершенияЧтенияДанных();
по причине:
Параметр не опциональный
(16) deniseek77, ну это не совсем цикл. По нажатию на кнопку идет проход нескольких "Если", при удачном "Если" вызывается моя функция.
16. deniseek77 86 31.10.12 15:45 Сейчас в теме
А сам цикл как у тебя выглядит? Для Индекс=0 по ...количество()-1 ? Что то типа этого?
18. sergik_nsk 148 31.10.12 16:03 Сейчас в теме
скажу кратко. бежать уже надо,
1. добейся что бы был проход сначало по чистой выгрузке, это когда из 1 источника во многие приемники, чтение из этих приемников должен пропускать, это посмотри в модуле обработки, какие условия надо поставить чтоб он не читал.
2. после чего добивать получение из многих приемников в источник - танцы с бубном, по закрытию кома первого и созданию нового на каждую базу, переопределение от разных баз теоретически должно работать но есть много "НО", исключить это "НО" все сразу - создав на каждую базу по своему кому.
19. SamNeSvoy 8 31.10.12 16:29 Сейчас в теме
Такое чувство, что к следующему соединению предыдущее соединение не успевает закрыться.. и из-за этого получается конфликт. Может как вариант воткнуть паузу?

есть такой вариант:
Процедура Пауза(Сек)
scr = Новый COMОбъект("WScript.Shell");
scr.Run("sleep "+СокрЛП(Число(Сек)),0,1);
КонецПроцедуры;

Хотя опять же сом...
20. Skellar 27 31.10.12 16:52 Сейчас в теме
(19) SamNeSvoy, А есть возможность отследить открытые COM?
Ваш вариант не сработал - ошибка на Run вылезла. Вставлял предупреждения с таймером и делал:
Процедура Пауза()
всхОбъект = новый COMОбъект("WScript.Shell");
Сообщить(ТекущаяДата());
всхОбъект.Run("ping -n 10 127.0.0.1", 0, 1);
Сообщить(ТекущаяДата());
КонецПроцедуры;

Особых результатов не дало.
21. lgg 20 31.10.12 18:42 Сейчас в теме
Создание COM-объектов из приложения 1C:Предприятие 8 выполняется из STA (Singlethreaded Apart). Поэтому все действия с COM - соединением и созданными им объектами Внешнее соединение будут выполняться в одном потоке. Цитирую:
"Если метод Connect не сможет на первом проходе найти подходящее или создать новое Внешнее соединение, то выполнение этого метода зациклится, так как освободить уже, возможно, ненужное другое Внешнее соединение будет нельзя по той причине, что операция освобождения объекта Внешнее соединение должна быть выполнена в том же потоке, в котором уже выполняется метод Connect."
Поэтому и не удается программно из одного сеанса освободить одно соединение и создать другое.
"Нормальные герои всегда идут в обход":
  • можно программно перезапустить сеанс с нужными параметрами;
  • можно запустить несколько сеансов и пусть каждый из них выполняет свой обмен.
Успехов!
22. sergik_nsk 148 01.11.12 10:46 Сейчас в теме
(21) lgg, про COMConnector пишите или про Application?
24. Skellar 27 01.11.12 12:00 Сейчас в теме
(21) lgg, Спасибо, как программно работать с сеансами я пока не знаю, но попробую покопать в эту сторону.
(23) deniseek77, мОбработкаДляЗагрузкиДанных - COMобъект, в самой обработке есть мОбработкаДляЗагрузкиДанных = Неопределено;, этого по идее должно быть достаточно. С Close() не вышло, "Метод объекта не обнаружен (Close)".
23. deniseek77 86 01.11.12 10:58 Сейчас в теме
Раз уж дело в COM, то нужно закрывать экземпляр, после отработки его... комобъект.Close();
25. Skellar 27 01.11.12 16:42 Сейчас в теме
Может есть у кого пример с программным запуском сеанса(сеансов)?
26. lgg 20 05.11.12 18:18 Сейчас в теме
Приблизительно так:
//В эту комендную строку можно включить любуе дополнительные параметры,
//которые передаются как параметры запуска сеанса
//мой параметр имеет имя КодНастройкиОбменаДанными и передаю я код узла обмена,
//но можно и по-другому
ДополнительнаяКоманднаяСтрока = "/C" + "КодНастройкиОбменаДанными=""" + СокрЛП(КодУзлаОбменаКоторыйНужноЗапуститьПослеПерезапускаСеанса);

//Выполняем перезапуск клиента с последующим повторным чтение сообщения
ЗавершитьРаботуСистемы(Истина, Истина, ДополнительнаяКоманднаяСтрока);

//В модуле приложения ПриНачалеРаботыСистемы() этот параметр нужно обработать:
Если Найти(ПараметрЗапуска, "КодНастройкиОбменаДанными") > 0 Тогда
// Проверим необходимость обмена
ПроцедурыОбменаДанными.ПроверкаНеобходимостиОбмена();
КонецЕсли;
//В модуле ПроцедурыОбменаДанными
Процедура ПроверкаНеобходимостиОбмена()
// Если в параметре запуска ничего не передано...
Если ПараметрЗапуска = "" Тогда
Возврат;
КонецЕсли;
// Формируем доп. командную строку для перезапуска клиента
СтрокаПараметра = ПараметрЗапуска;

// Если в параметре командной строки не передан код элемента справочника НастройкиОбменаДанными
//КодНастройкиОбменаДанными

КодУзлаОбмена = ИзвлечьПараметрИзСтрокиПараметраКоманднойСтроки("КодНастройкиОбменаДанными", СтрокаПараметра);
Если КодНастройкиОбменаДанными = Неопределено Тогда
Возврат;
КонецЕсли;

//Вызываем необходимые процедуры обмена
//.....


КонецПроцедуры


Функция ИзвлечьПараметрИзСтрокиПараметраКоманднойСтроки(ИмяПараметра, Знач СтрокаПараметра)

Префикс = СтрДлина(ИмяПараметра + "=""");
ДлинаПрефикса = СтрДлина(ИмяПараметра + "=""");
ПозицияИмяПараметра = Найти(СтрокаПараметра, ИмяПараметра);
ДлинаСтрокаПараметра = СтрДлина(СтрокаПараметра);
Если ДлинаСтрокаПараметра <= ДлинаПрефикса ИЛИ ПозицияИмяПараметра = 0 Тогда
Возврат Неопределено;
КонецЕсли;

ПозицияЗапятой = Найти(СтрокаПараметра, """,");
Пока 1=1 Цикл
Если ПозицияЗапятой = 0 ИЛИ ПозицияЗапятой > ПозицияИмяПараметра Тогда
Прервать;
КонецЕсли;
//СтрокаПараметра = Лев(СтрокаПараметра, ПозицияЗапятой - 1) + Сред(СтрокаПараметра, ПозицияЗапятой + 1,


КонецЦикла;
ДлинаКода = ?(ПозицияЗапятой = 0, СтрДлина(СтрокаПараметра), ПозицияЗапятой - 1) - ДлинаПрефикса;

Возврат Сред(СтрокаПараметра, ДлинаПрефикса + 1, ДлинаКода);

КонецФункции
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот