Имя: Пароль:
1C
1С v8
РИБ, Бухгалтерия предприятия
0 Just
 
29.07.12
12:57
Есть несколько вопросов, разбираться детально самому особо некогда...
1. Возможно ли настроить обмен между 2-мя подчиненными базами?

Я так понял, что нельзя, создать ссылки на другие переферийные базы можно, настроить коды и т.д. Но при выполнении процедуры обмена вываливается ошибка "Ошибка при чтении изменений при обмене РИБ: {ОбщийМодуль.ПроцедурыОбменаДанными(1598)}: Ошибка при вызове метода контекста (ПрочитатьИзменения): Ошибка формата представления изменений"

А строка 1598, собственно, выглядит так: "ПланыОбмена.ПрочитатьИзменения(ЧтениеСообщения, СтруктураНастроекОбменаДанными.КоличествоЭлементовВТранзакцииНаЗагрузкуДанных);
"

2. При одновременном изменении документа в Главной и Подчиненной базе приоритет изменений всегда стоит по Главной. Может есть уже стандартное решение, код, чтобы процедура обмена отслеживала такие объекты и:
- либо отслеживала несовпадения и предлагала пользователю выбрать загружать или не загружать объект;
- либо сообщала список несовпадений и просто не загружала.
1 Живой Ископаемый
 
29.07.12
13:00
1. Можно, но это будет не РИБ а обмен по правилам.
2. Отслеживать можно, код есть, но на счет загружать или не загружать, боюсь по-человечески можно просто показывать после загрузки и предлагать вернуться к предыдущей версии если включено версионирование.
2 Just
 
29.07.12
13:12
2. А если это "Бухгалтерия предприятия, редакция 1.6 (1.6.23.2)" на платформе 8.1?

В принципе, если это возможно, то первый вопрос уже не так интересен...
3 Живой Ископаемый
 
29.07.12
13:14
2(2) Можно перед загрузкой из центра сливать все изменения зарегенные ДЛЯ центра в ХМЛ. Ну и потом озадачиться сравнением.
4 Just
 
29.07.12
13:24
Пытался сейчас в скайпе до тебя достучаться - не вышло...
Дак код, говоришь, есть для реализации подобных функций? Для какой платформы? Какой функционал реализован, сколько будет стоить поделиться этим кодом?
5 Just
 
29.07.12
14:01
И еще вопрос.
Список объектов, которые подлежат выгрузке при следующем обмене я нашел - Сервис/Распределенная информационная база (РИБ)/Монитор обмена данными закладка Дополнительно "Основной обмен:" кнопка "Подбробно". Там можно и пометить объекты для выгрузки и снять такую пометку...

А есть ли где-то список объектов, которые были загружены?
6 Живой Ископаемый
 
29.07.12
14:23
2(5) В общем случае - нет. Можно конечно завести фейковый узел специально для таких целей, перед обменом удалять для него все зарегистрированные изменения, и тогда все принятое из центра будет зарагено в нем как бы для еще более подчиненного узла.
Либо переписать создание сообщения обмена таким образом, чтобы там передавался и список объектов (ну или просто при загрузке запоминать их в какой-то структуре)
7 Живой Ископаемый
 
29.07.12
20:47
http://screencast.com/t/kObHLfQTX7pz

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

       тзБуф = Запрос.Выполнить().Выгрузить();
       Если тзБуф.Количество()>0 Тогда
           //обнаржена коллизия, оказывается мы примаем элемент от узла, для которого мы уже зарегили изменения
           //Хотим проинорировать его получение
           ПолучениеЭлемента = ПолучениеЭлементаДанных.Игнорировать;
       КонецЕсли;
       ЗаписьЖурналаРегистрации("ПланыОбмена.ПолучениеДанныхОтПодчиненного",,,ЭлементДанных.ССылка,"Принят от главного "+ЭлементДанных+";"+ПолучениеЭлемента+";"+ОтправкаНазад+";"+XMLТипЗнч(ЭлементДанных).ИмяТипа);  
   КонецЕсли;

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


Над чем осталось подумать - над кодом который будет однозначно определять для принимаемого элемента зарегистрированы ли по нему изменения для узла, из которого он принимается.  Потому что в общем случае приниматься будут не только элементы справочника валюты, да и вообще не только ссылочные данные но и набора записей.
8 Just
 
30.07.12
08:36
Спасибо за код. Я его слегка модифицировал под более универсальную форму.

Процедура ПриПолученииДанныхОтГлавного(ЭлементДанных, ПолучениеЭлемента, ОтправкаНазад)
   ИТ=XMLТипЗнч(ЭлементДанных).ИмяТипа;
   Если Лев(ИТ,15)="DocumentObject." Тогда
       ИТ=СокрЛП(ИТ); ТД=Сред(ИТ,16,255);
       Запрос = Новый Запрос("ВЫБРАТЬ
                            |    ОИ.Узел,
                            |    ОИ.НомерСообщения,
                            |    ОИ.Ссылка
                            |ИЗ
                            |    Документ."+ТД+".Изменения КАК ОИ
                            |ГДЕ
                            |    ОИ.Ссылка = &Ссылка
                            |    И ОИ.Узел = &Узел");
       Запрос.УстановитьПараметр("Ссылка",ЭлементДанных.ССылка); //Для этого узла (от которого принимаем изменения)
       Запрос.УстановитьПараметр("Узел",ЭтотОбъект.ССылка);//именно этот элемент
       
       тзБуф = Запрос.Выполнить().Выгрузить();
       Если тзБуф.Количество()>0 Тогда
           //обнаржена коллизия, оказывается мы примаем элемент от узла, для которого мы уже зарегили изменения
           //Спросим проинорировать ли его получение?
           Режим = РежимДиалогаВопрос.ДаНет;
           Ответ = Вопрос(СокрЛП(ЭлементДанных)+" изменен в обоих базах. Продолжить выполнение операции?", Режим, 0);
           Если Ответ = КодВозвратаДиалога.Нет Тогда
               ПолучениеЭлемента = ПолучениеЭлементаДанных.Игнорировать;
               Сообщить("Не загружен документ, измененный в обоих базах "+ЭлементДанных,СтатусСообщения.Внимание);
           КонецЕсли;
       КонецЕсли;
       ЗаписьЖурналаРегистрации("ПланыОбмена.ПолучениеДанныхОтГлавного",,,ЭлементДанных.ССылка,"Принят от главного "+ЭлементДанных+";"+ПолучениеЭлемента+";"+ОтправкаНазад+";"+XMLТипЗнч(ЭлементДанных).ИмяТипа);
   Иначе
       ЗаписьЖурналаРегистрации("ПланыОбмена.ПолучениеДанныхОтГлавного",,,ЭлементДанных,"Принят от главного "+ЭлементДанных+";"+ПолучениеЭлемента+";"+ОтправкаНазад+";"+XMLТипЗнч(ЭлементДанных).ИмяТипа);
   КонецЕсли;
КонецПроцедуры

Процедура ПриПолученииДанныхОтПодчиненного(ЭлементДанных, ПолучениеЭлемента, ОтправкаНазад)
   ЗаписьЖурналаРегистрации("ПланыОбмена.ПолучениеДанныхОтПодчиненного",,,ЭлементДанных,"Принят от подчиненного "+ЭлементДанных+";"+ПолучениеЭлемента+";"+ОтправкаНазад+";"+XMLТипЗнч(ЭлементДанных).ИмяТипа);
КонецПроцедуры

Но в итоге все равно получилось не то, что надо, так как меня это интересовало в первую очередь в отношении документов. А кроме самих документов передаются также и движения регистров от документа. Получается при приеме их тоже надо это дело отслеживать. Причем бывает что сперва в файле фигурируют движения, а потом сам документ...

Итого получаем процедуру в 2 этапа:
1.1 Пытаемся загрузить и составляем список "коллизий", сами документы и движения с ними связанные не загружаем
1.2 Спрашиваем пользователя что делать с этими документами
2. Загружаем повторно уже зная что делать с документом и связанными с ним движениями...
9 Живой Ископаемый
 
30.07.12
08:48
ой нет... это совсем плохо...
во-первых такому:
Ответ = Вопрос(СокрЛП(ЭлементДанных)+" изменен в обоих базах. Продолжить выполнение операции?", Режим, 0);

не место в коде, который вполне может выполняться интерактивно.. во-вторых
Если Лев(ИТ,15)="DocumentObject." Тогда - определить что элемент - документ можно и наверное в этом случае нужно по-другому, через метадданые типвсе ссылки.
но если потом узнавать о факте регистрации изменения для этого объекта запросом, то да, видимо ХМЛТипЗнч не избежать, но запрос - не единственный способ.
Будешь ставить задачу программисту, учти все это.. или пусть он учтет
10 Serg_1960
 
30.07.12
09:47
(0) Зачем так сложно-то?

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

PS: про приоритеты не забудь - когда один и тот-же объект изменяют в обоих узлах между сеансами обмена.
11 Живой Ископаемый
 
30.07.12
09:58
2(10) а как выставить приоритет в таких peer-узлах?
12 Serg_1960
 
30.07.12
10:05
(11) Приоритет изменений между подчиненными узлами легко "разрулить", если в центральном узле контролировать порядок получения сообщений от них.
13 Живой Ископаемый
 
30.07.12
10:26
а.. ну да.. кто последний, тот и папа
14 Serg_1960
 
30.07.12
10:49
Ты хотел сказать - "мама" :) Я бы по другому сказал - "Кто первый встал - того и тапочки"(с)
15 Живой Ископаемый
 
30.07.12
11:13
2(14) э... нет, я хотел сказать именно папа.
ну и "Кто первый встал - того и тапочки" как раз не отражает сути, потому что кто последний сделал, того изменения и учлись
16 Just
 
30.07.12
14:00
(10) Ну это получается дополнительные процедуры обмена будут - не хочется пока так усложнять...
Всем спасибо за помощь. Пока остановился на таком варианте - все заргужаем, только сообщаем, если документ был изменен также и в переферийной базе. Посмотрим часто ли будет возникать эта ситуация, и исходя из этого, может, что-то еще сделаем...
17 Just
 
30.07.12
18:23
Еще немного покопался, можно было код с записями в журнал регистрации всех полученных объектов не городить - они и так прописываются... (теперь в двойном экземпляре...) :)
18 Живой Ископаемый
 
30.07.12
18:29
и что там прописывается? что объект был изменен даже если проигнорен? :)
Пользователь не знает, чего он хочет, пока не увидит то, что он получил. Эдвард Йодан