Имеем следующее: Работающая информационная база на основе конфигурации «Управление торговлей для Казахстана, ред. 3», в основном используемая для торговых операций в городе А. Решили открыть филиал в городе Б. Выбирали между 3 вариантами:
1. работа в режиме управляемого приложения (тонкий клиент) (отпал из-за неустойчивого канала связи)
2. работа в терминальном режиме (отпал из-за возможного постоянного конфликта блокировок, проблемы с обновлением)
3. РИБ
Выбрали РИБ (по нашему мнению самый отлаженный и надёжный способ работы при больших нагрузках). Реализацию возложили на меня.
Требования вкратце: документы, регистры должны кочевать с региональной привязкой по организации, справочники, константы, планы видов характеристик общие
Описываю алгоритм:
1) Работа в режиме конфигуратор. Скопировал план обмена «Полный» (так как есть объекты которые должны быть только в региональных базах). Переименовал в «План обмена». Добавил реквизит «организация» с типом справочникссылка. организация
2) Откорректировал состав обмениваемых данных. В общих объектах (справочники, константы, планы видов характеристик) поставил авторегистрация=разрешить. В остальных поставил авторегистрация=запретить.
3) В общих модулях создал глобальный общий модуль «ОбменПоОрганизации» . Текст модуля в файле «Общий модуль». Для выкладывания текст большой.
Процедура обРегистрацияИзменений(Объект) Экспорт
ГлавныйУзел = ПланыОбмена.ГлавныйУзел();
Если ГлавныйУзел=Неопределено Тогда //это центральная база
ПланОбмена = ПланыОбмена.ПланОбмена.Выбрать();
Пока ПланОбмена.Следующий() Цикл
//В сам себя не отправляем
Если ПланОбмена = ПланыОбмена.ПланОбмена.ЭтотУзел() тогда
Продолжить;
КонецЕсли;
Если ПланОбмена.НомерОтправленного = 0 и ПланОбмена.НомерПринятого = 0 Тогда
// Похоже на главный. Хотя не факт.
Продолжить;
КонецЕсли;
//Некое хитрое условие
Если обОтправлятьОбъектВУзел(Объект, ПланОбмена) Тогда
//Объект.ОбменДанными.Получатели.Добавить(ПланОбмена.Ссылка);
Попытка
Объект.ОбменДанными.Получатели.Добавить(ПланОбмена.Ссылка);
//ПланыОбмена.ЗарегистрироватьИзменения(ПланОбмена.Ссылка,Объект);
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
попытка
Объект.ОбменДанными.Получатели.Добавить(ПланыОбмена.ПланОбмена.ЭтотУзел());
исключение
конецпопытки;
Иначе
//изменен периферийный объект в базе создания
Объект.ОбменДанными.Получатели.Добавить(ГлавныйУзел);
//ПланыОбмена.ЗарегистрироватьИзменения(ГлавныйУзел,Объект);
КонецЕсли;
КонецПроцедуры
Функция обОтправлятьОбъектВУзел(Объект, ПланОбмена)
Если Метаданные.Справочники.Найти(Метаданные.НайтиПОТипу(ТипЗнч(Объект)).Имя) <> Неопределено Тогда
// Это справочник. Поэтому отправляем.
Возврат Истина;
ИначеЕсли Метаданные.РегистрыНакопления.Найти(Метаданные.НайтиПоТипу(ТипЗнч(Объект)).Имя) <> Неопределено Тогда
// Это регистр накопления. Посмотрим какая организация у него в регистраторе. И есть ли она вообще.
Рег = Объект.Отбор.Регистратор.Значение.ПолучитьОбъект();
Если Рег = Неопределено Тогда
//Если регистратор неопределен, то не отправляем никуда
Возврат ложь
КонецЕсли;
Если Метаданные.НайтиПоТипу(ТипЗнч(Объект)).Имя = "ТоварыВПути" Тогда
Если ТипЗнч(Рег) = Тип("ДокументОбъект.Транзит") Тогда
Если Рег.ОрганизацияПолучатель = ПланОбмена.Организация или планыобмена.ГлавныйУзел()=ПланОбмена Тогда
Возврат Истина;
Иначе
Возврат Ложь;
КонецЕсли;
Иначе
Если Рег.Организация = ПланОбмена.Организация или планыобмена.ГлавныйУзел()=ПланОбмена Тогда
Возврат Истина;
Иначе
Возврат Ложь;
КонецЕсли;
КонецЕсли;
Иначе
Если ЕстьРеквизитДокумента("Организация", Объект) Тогда
Если Рег.Организация = ПланОбмена.Организация Тогда
Возврат Истина;
Иначе
Возврат Ложь;
КонецЕсли;
Иначе
// Нет реквизита организация значит уходит однозначно.
Возврат Истина;
КонецЕсли;
КонецЕсли;
ИначеЕсли Метаданные.РегистрыСведений.Найти(Метаданные.НайтиПоТипу(ТипЗнч(Объект)).Имя) <> Неопределено Тогда
// Это регистр сведений. Посмотрим какая организация у него в регистраторе. И есть ли она вообще.
Попытка
Рег = Объект.Отбор.Регистратор.Значение.ПолучитьОбъект();
Исключение
Конецпопытки;
Если Рег = Неопределено Тогда
//Если регистратор неопределен, то не отправляем никуда
Если ЕстьРеквизитДокумента("Организация", Объект) Тогда
Если Объект.Отбор.Организация.Значение = ПланОбмена.Организация Тогда
Возврат Истина;
Иначе
Возврат Ложь;
КонецЕсли;
Иначе
// Нет реквизита организация значит уходит однозначно.
Возврат Истина;
КонецЕсли;
Иначе
Если ЕстьРеквизитДокумента("Организация", Объект) Тогда
Если Рег.Организация = ПланОбмена.Организация Тогда
Возврат Истина;
Иначе
Возврат Ложь;
КонецЕсли;
Иначе
// Нет реквизита организация значит уходит однозначно.
Возврат Истина;
КонецЕсли;
КонецЕсли;
Иначе
// Это документ. Его мы проверяем на организацию.
Если ЕстьРеквизитДокумента("Организация", Объект) тогда
Если Объект.Организация = ПланОбмена.Организация или планыобмена.ГлавныйУзел()=ПланОбмена Тогда
Возврат Истина;
Иначе
Если ЕстьРеквизитДокумента("ОрганизацияПолучатель", Объект) Тогда
Если Объект.ОрганизацияПолучатель = ПланОбмена.Организация или планыобмена.ГлавныйУзел()=ПланОбмена Тогда
Возврат Истина;
Иначе
Возврат Ложь;
КонецЕсли;
Иначе
Возврат Ложь;
КонецЕсли;
КонецЕсли;
Иначе
// Нет реквизита организация значит уходит однозначно.
Возврат Истина;
КонецЕсли;
КонецЕсли;
КонецФункции
// Позволяет определить есть ли среди реквизитов шапки документа
// реквизит с переданным именем.
//
// Параметры:
// ИмяРеквизита - строковое имя искомого реквизита,
// МетаданныеДокумента - объект описания метаданных документа, среди реквизитов которого производится поиск.
//
// Возвращаемое значение:
// Истина - нашли реквизит с таким именем, Ложь - не нашли.
//
Функция ЕстьРеквизитДокумента(ИмяРеквизита, Объект) Экспорт
ТипОбъекта = ОпределитьТипОбъекта(Объект);
МетаданныеДокумента = Объект.Метаданные();
Если ТипОбъекта="Документ" тогда
Если МетаданныеДокумента.Реквизиты.Найти(ИмяРеквизита) = Неопределено Тогда
Возврат Ложь;
Иначе
Возврат Истина;
КонецЕсли;
ИначеЕсли ТипОбъекта="РегистрСведений" тогда
Если МетаданныеДокумента.Измерения.Найти(ИмяРеквизита) = Неопределено Тогда
Если МетаданныеДокумента.Реквизиты.Найти(ИмяРеквизита) = Неопределено Тогда
Возврат Ложь;
Иначе
Возврат Истина;
КонецЕсли;
Иначе
Возврат Истина;
КонецЕсли;
ИначеЕсли ТипОбъекта="РегистрНакопления" тогда
Если МетаданныеДокумента.Реквизиты.Найти(ИмяРеквизита) = Неопределено Тогда
Возврат Ложь;
Иначе
Возврат Истина;
КонецЕсли;
Иначе
Возврат Ложь;
КонецЕсли;
КонецФункции // ЕстьРеквизитДокумента()
Функция ОпределитьТипОбъекта(Объект)
Класс = Объект.Метаданные().ПолноеИмя();
Класс = Лев(Класс, Найти(Класс, ".")-1);
Возврат Класс;
КонецФункции
4) Затем в объектах, где данные нужно фильтровать и объект включен в состав обмена (документы, регистры) необходимо в модулях объектов в процедуре приЗаписи добавить вызов процедуры обРегистрацияИзменений().
Если ЭтотОбъект.ОбменДанными.Получатели.АвтоЗаполнение и не ЭтотОбъект.ОбменДанными.Загрузка Тогда
обРегистрацияИзменений(ЭтотОбъект) ;
КонецЕсли;
5) Подчиненный узел создал копированием оригинала и удалением документов, юзеров. Затем сделал рокировку планов обмена (подмена кодов узла). Установил главный узел.
6) Почистил регистрацию изменений на всякий случай. Нужно учитывать если объект хоть где-то удаляется, то он удаляется и в остальных узлах!!!
7) Затем при первоначальном начале работы подчиненного узла убрал вызов помощника настройки обмена.
И все в принципе. Думаю можно это можно использовать в любых конфигурациях, надо немного дописать для регистров бухгалтерии и расчетов. А так для торговых уже готово.
Понравился подход, можно подробнее о пунктах 5,6,7?
(1) Bor_ka, по пункту 5. В оригинале базы создал подчиненные узлы. Сделал копию выгрузив базу в *.DT. Загрузил в чистую базу. В планах обмена в новой базе удалил лишние узлы осталось только 2. Поменял коды узлов местами. Откорректировал реквизит «Организация» в соответствии с реальностью.
пункт 6. Все объекты имеют уникальный идентификатор. Если в филиале №1 в справочнике контрагенты произойдет непосредственное удаление элемента, то после обмена с центром этот объект удалится в центральной базе. Затем когда центральная база сделает обмен с филиалом №2, то объект удалится и в этой базе.
пункт 7. при развертке РИБ в типовой конфигурации при первом запуске базы автоматически запускается помощник настройки обмена. он работает косячно. я не стал разбираться, просто отключил его.
базы работают уже полгода никаких проблем с обменом.
Калайсын,Айтуар? красавчик, буны сен енгизип един эпл ситиде?
(3) kumga99, Жаксы. Сам как? Да эпл март кой. Кайда жумыс истеп журсин?