Имя: Пароль:
1C
1С v8
Порядок выгрузки данных через план обмена
0 SergoZD
 
15.05.14
17:12
Доброго дня.
Есть Управление Торговлей 10.3, 1С 8.2.19.90, настроены РИБ.

Запись сообщения XML при обмене по плану обмена Полный (предназначеный для обмена между РИБ) производится штатными средствами УТ, непосредственно вызовом ПланыОбмена.ЗаписатьИзменения(...), при этом в XML данные выгружаются в непонятном порядке, движения по регистрам документов проходят, раньше чем сами эти документы.

Есть ли возможность упорядочить данные в этом XML-файле, как минимум - чтобы документы были в тексте раньше, чем их движения?
1 acsent
 
15.05.14
17:20
только если самому писать сообщения, но это муторно
2 SergoZD
 
15.05.14
18:13
Вроде бы написал. Кто-то может прокомментировать на предмет криворукости кода? Желательно с указанием кривых мест.


                // для РИБ изменения в информационной базе
                Если ПланыОбмена.ГлавныйУзел() = Неопределено Тогда
                    ПланыОбмена.ЗаписатьИзменения(ЗаписьСообщения, СтруктураНастроекОбменаДанными.КоличествоЭлементовВТранзакцииНаВыгрузкуДанных);
                Иначе
                    КоличествоЗаписанныхОбъектов = 0;
                    КоличествоНайденныхДляЗаписиОбъектов = 0;
                    НачатьТранзакцию();
                    Попытка
                        СписокДоков=Новый Массив;
                        Для Каждого Док Из Метаданные.Справочники Цикл
                            СписокДоков.Добавить(Док);
                        КонецЦикла;
                        ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения, СписокДоков);
                        Пока ВыборкаИзменений.Следующий() Цикл
                            Данные = ВыборкаИзменений.Получить();
                            ЗаписатьXML(ЗаписьXML, Данные);
                            КоличествоНайденныхДляЗаписиОбъектов = КоличествоНайденныхДляЗаписиОбъектов + 1;
                            Если КоличествоНайденныхДляЗаписиОбъектов % 100 = 0 Тогда
                                #Если Клиент Тогда
                                    Состояние("Запись изменений для узла """ + УзелОбмена.Наименование + """. Записано объектов: " + Строка(КоличествоНайденныхДляЗаписиОбъектов));
                                #КонецЕсли
                            КонецЕсли;
                            КоличествоЗаписанныхОбъектов = КоличествоЗаписанныхОбъектов + 1;
                            Если (СтруктураНастроекОбменаДанными.КоличествоЭлементовВТранзакцииНаВыгрузкуДанных > 0)
                                И (КоличествоЗаписанныхОбъектов = СтруктураНастроекОбменаДанными.КоличествоЭлементовВТранзакцииНаВыгрузкуДанных) Тогда
                                ЗафиксироватьТранзакцию();
                                НачатьТранзакцию();
                                КоличествоЗаписанныхОбъектов = 0;
                            КонецЕсли;
                        КонецЦикла;
                        СписокДоков=Новый Массив;
                        Для Каждого Док Из Метаданные.Документы Цикл
                            СписокДоков.Добавить(Док);
                        КонецЦикла;
                        ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения, СписокДоков);
                        Пока ВыборкаИзменений.Следующий() Цикл
                            Данные = ВыборкаИзменений.Получить();
                            ЗаписатьXML(ЗаписьXML, Данные);
                            КоличествоНайденныхДляЗаписиОбъектов = КоличествоНайденныхДляЗаписиОбъектов + 1;
                            Если КоличествоНайденныхДляЗаписиОбъектов % 100 = 0 Тогда
                                #Если Клиент Тогда
                                    Состояние("Запись изменений для узла """ + УзелОбмена.Наименование + """. Записано объектов: " + Строка(КоличествоНайденныхДляЗаписиОбъектов));
                                #КонецЕсли
                            КонецЕсли;
                            КоличествоЗаписанныхОбъектов = КоличествоЗаписанныхОбъектов + 1;
                            Если (СтруктураНастроекОбменаДанными.КоличествоЭлементовВТранзакцииНаВыгрузкуДанных > 0)
                                И (КоличествоЗаписанныхОбъектов = СтруктураНастроекОбменаДанными.КоличествоЭлементовВТранзакцииНаВыгрузкуДанных) Тогда
                                ЗафиксироватьТранзакцию();
                                НачатьТранзакцию();
                                КоличествоЗаписанныхОбъектов = 0;
                            КонецЕсли;
                        КонецЦикла;
                        СписокДоков=Новый Массив;
                        Для Каждого Док Из Метаданные.РегистрыНакопления Цикл
                            СписокДоков.Добавить(Док);
                        КонецЦикла;
                        Для Каждого Док Из Метаданные.РегистрыСведений Цикл
                            СписокДоков.Добавить(Док);
                        КонецЦикла;
                        ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения, СписокДоков);
                        Пока ВыборкаИзменений.Следующий() Цикл
                            Данные = ВыборкаИзменений.Получить();
                            ЗаписатьXML(ЗаписьXML, Данные);
                            КоличествоНайденныхДляЗаписиОбъектов = КоличествоНайденныхДляЗаписиОбъектов + 1;
                            Если КоличествоНайденныхДляЗаписиОбъектов % 100 = 0 Тогда
                                #Если Клиент Тогда
                                    Состояние("Запись изменений для узла """ + УзелОбмена.Наименование + """. Записано объектов: " + Строка(КоличествоНайденныхДляЗаписиОбъектов));
                                #КонецЕсли
                            КонецЕсли;
                            КоличествоЗаписанныхОбъектов = КоличествоЗаписанныхОбъектов + 1;
                            Если (СтруктураНастроекОбменаДанными.КоличествоЭлементовВТранзакцииНаВыгрузкуДанных > 0)
                                И (КоличествоЗаписанныхОбъектов = СтруктураНастроекОбменаДанными.КоличествоЭлементовВТранзакцииНаВыгрузкуДанных) Тогда
                                ЗафиксироватьТранзакцию();
                                НачатьТранзакцию();
                                КоличествоЗаписанныхОбъектов = 0;
                            КонецЕсли;
                        КонецЦикла;
                        ЗафиксироватьТранзакцию();
                    Исключение
                        ОтменитьТранзакцию();
                        #Если Клиент Тогда
                            ОбщегоНазначения.СообщитьОбОшибке("" + ОписаниеОшибки());
                        #КонецЕсли
                    КонецПопытки;
                КонецЕсли;
3 SergoZD
 
15.05.14
18:16
В данной ситуации для выгрузки из центральной базы используется стандартный метод, который не вызывает накладок, и, главное, добавляет регистрацию изменений конфигурации.

Для выгрузки из периферийных баз в центральную уже используется приведенный выше код. Сперва в XML выгружаются изменения всех справочников, потом всех документов, потом только регистры. В моей ситуации другие данные в удаленных базах не изменяются и этого на первый взгляд достаточно.
4 Spieluhr
 
15.05.14
22:18
А зачем Вам понадобился такой порядок, если не секрет?
5 Лаврентий Берия
 
15.05.14
22:42
(0) НЕ таскать движения. /рукалицо/
6 SergoZD
 
16.05.14
10:53
Spieluhr, удаленных баз несколько, в них выгружаются не полные копии, а только те данные, которые соответствуют филиалу. Проверка ведется на уровне реквизитов документов (склад/подразделение/контрагент и т.п.).

Когда из филиала в центральную базу загружается документ, измененный в этой базе - проверкой реквизитов определяется, в какие ещё базы нужно отправить эти изменения. При загрузке движений - идет проверка по регистратору движений.

Если загружается новый документ из филиала, и сперва грузятся движения по нему, то при проверке - регистратор объект не найден и движения никуда не отправляются. Потом подгружается документ - который в филиалы отправляется, но уже без движений.

В принципе такая ситуация редка (в одном филиале для другого обычно документы не делаются) и решается это перепроведением документа, но хотелось бы избавиться от проблемы.
7 SergoZD
 
16.05.14
10:55
(4) не понял, разъясните?
8 hhhh
 
16.05.14
11:03
(6) глупо делать проверку на уровне регистратора. Это нереальные тормоза, запрос в цикле и прочая фигня. Он вам надо? Делай проверку по движениям регистра, там есть ведь и склад и контрагент и так далее.
9 SergoZD
 
16.05.14
14:13
(8) Реализация товаров и услуг. Движения по регистру Товары на складах - склад чужой, контрагент наш. В итоге в базе будет документ с половиной движений. Когда прорабатывали этот механизм, решили - что такой вариант не по феншую.

Более того, если в такой ситуации этот документ пометить на удаление во второй базе - то удалится только присутствующая половина движений, и после загрузки в центральную базу, там повиснет помеченый на удаление документ, по которому будут висеть движения, не выгруженные изначально во вторую базу. А это уже фейл.
10 duh
 
16.05.14
14:17
МассивВыгружаемыхМетаданных_ПоТипам = Новый Массив();
        МассивВыгружаемыхМетаданных_ПоТипам.Добавить(Новый Массив()); //ПланСчетов  
        МассивВыгружаемыхМетаданных_ПоТипам.Добавить(Новый Массив()); //Справочники
        МассивВыгружаемыхМетаданных_ПоТипам.Добавить(Новый Массив()); //Все остальное
        
        //МассивВыгружаемыхМетаданных = Новый Массив();
        //МассивВыгружаемыхМетаданных.Добавить(Метаданные.РегистрыСведений.СоответствиеОбъектовДляОбмена);
        
        //ИмяОбъектаДляЗапроса
        // дополняем массив только теми метаданными по которым есть правила выгрузки - остальные метаданные нас не интересуют
        Для Каждого СтрокаПравилаВыгрузки Из ВременныйМассивПравилВыгрузкиДанных Цикл
            
            МетаданныеПВД = Метаданные.НайтиПоТипу(СтрокаПравилаВыгрузки.ОбъектВыборки);
            Если Метаданные.ПланыСчетов.Содержит(МетаданныеПВД) Тогда
                МассивВыгружаемыхМетаданных_ПоТипам[0].Добавить(МетаданныеПВД);
            ИначеЕсли Метаданные.Справочники.Содержит(МетаданныеПВД) Тогда  
                МассивВыгружаемыхМетаданных_ПоТипам[1].Добавить(МетаданныеПВД);
            Иначе
                МассивВыгружаемыхМетаданных_ПоТипам[2].Добавить(МетаданныеПВД);
            КонецЕсли;    
            //МассивВыгружаемыхМетаданных.Добавить(МетаданныеПВД);
            
        КонецЦикла;
        
        Для Каждого СтрокаТипа Из МассивВыгружаемыхМетаданных_ПоТипам Цикл
            МассивВыгружаемыхМетаданных = СтрокаТипа;    
            Если МассивВыгружаемыхМетаданных.Количество() = 0 Тогда
                 Продолжить;
            конецЕсли;    
            // выбираем не все, а только то что указано для выгрузки в правилах выгрузки
            ВыборкаИзменений = ПланыОбмена.ВыбратьИзменения(ЗаписьСообщения.Получатель, ЗаписьСообщения.НомерСообщения, МассивВыгружаемыхМетаданных);
            
            Пока ВыборкаИзменений.Следующий() Цикл
                
                Данные = ВыборкаИзменений.Получить();
Есть два вида языков, одни постоянно ругают, а вторыми никто не пользуется.