gifts2017

РИБ на v 8: Фильтрация данных по узлам распределенной информационной базы.

Опубликовал Андрей Скляров (coder1cv8) в раздел Администрирование - Распределенная БД (УРИБ, УРБД)

Часто, при работе в распределенной информационной базе, существует необходимость в выборочной миграции данных по узлам, когда поведение по умолчанию (т.е. любое изменение элемента данных, произведенное в любом из узлов, стремится распространиться по всем остальным узлам) не подходит.
Часто, при работе в распределенной информационной базе, существует необходимость в выборочной миграции данных по узлам, когда поведение по умолчанию (т.е. любое изменение элемента данных, произведенное в любом из узлов, стремится распространиться по всем остальным узлам) не подходит.
В общем случае, существует два подхода к решению этой задачи:
1. Отключение для всех объектов с выборочной миграцией авто регистрации и проверка при записи необходимости регистрации изменения объекта (для последующей отправки в узел).
2. Фильтрация данных непосредственно при записи сообщения обмена.
Здесь я хотел бы рассмотреть второй способ, который, на мой взгляд, является более интересным. Фильтрация данных обычно происходит по признаку «принадлежности» этих данных к организации, подразделению, складу и т.д. Таким образом, нужно при записи сообщения обмена, определить (по какому-либо из реквизитов записываемых в текущий момент данных) необходимость отправки этих данных в текущий узел «получатель».
Приведу пример. Существует распределенная информационная база, имеющая один корневой узел и некоторое количество периферийных узлов, используется типовая конфигурация «Бухгалтерия предприятия». Задача заключается в реализации схемы обмена, при которой за каждым из периферийных узлов «закреплена» одна или несколько организаций, по которым в этом узле ведется учет. Соответственно, необходимо, что бы в периферийные узлы попадали данные только по определенной организации (нескольким организациям), а в центральном узле «собирались» все данные.
Для решения этой задачи, в плане обмена добавим табличную часть "ОрганизацииУзла", имеющую одну колонку "Организация", тип "СправочникСсылка.Организации". Далее, в модуле плана обмена, в процедуре ПриОтправкеДанныхПодчиненному(), добавим следующий текст:
Процедура
ПриОтправкеДанныхПодчиненному
(
ЭлементДанных
,
ОтправкаЭлемента
) Если
ТипЗнч
(
ЭлементДанных
)=
Тип
("УдалениеОбъекта") Тогда Возврат
;
  	
КонецЕсли
;
  	ОбъектМетаданных
=
ЭлементДанных
.Метаданные()
;
  	
Если Метаданные.
Документы
.
Содержит
(
ОбъектМетаданных
) Тогда Если
ЕстьРеквизитДокумента
("Организация",
ОбъектМетаданных
) Тогда Если
глТекущийУзел
.
ОрганизацииУзла
.
Найти
(
ЭлементДанных
.
Организация
,"Организация")=
Неопределено 
Тогда
ОтправкаЭлемента
=
ОтправкаЭлементаДанных
.
Игнорировать;
    			
КонецЕсли
;
   		
КонецЕсли
;
  	
ИначеЕсли Метаданные.
РегистрыНакопления
.
Содержит
(
ОбъектМетаданных
) ИЛИ Метаданные.
РегистрыБухгалтерии
.
Содержит
(
ОбъектМетаданных
) Тогда
Регистратор
=
ЭлементДанных
.
Отбор
.
Регистратор
.
Значение;
   		
Если
ЕстьРеквизитДокумента
("Организация",
Регистратор
.Метаданные()) Тогда Если
глТекущийУзел
.
ОрганизацииУзла
.
Найти
(
Регистратор
.
Организация
,"Организация")=
Неопределено 
Тогда
ОтправкаЭлемента
=
ОтправкаЭлементаДанных
.
Игнорировать;
    			
КонецЕсли
;
   		
КонецЕсли
;
  	
ИначеЕсли Метаданные.
РегистрыСведений
.
Содержит
(
ОбъектМетаданных
) Тогда Если
ЭлементДанных
.
Отбор
.
Найти
("Регистратор")<>
Неопределено 
Тогда
Регистратор
=
ЭлементДанных
.
Отбор
.
Регистратор
.
Значение;
    			
Если
ЕстьРеквизитДокумента
("Организация",
Регистратор
.Метаданные()) Тогда Если
глТекущийУзел
.
ОрганизацииУзла
.
Найти
(
Регистратор
.
Организация
,"Организация")=
Неопределено 
Тогда
ОтправкаЭлемента
=
ОтправкаЭлементаДанных
.
Игнорировать;
     				
КонецЕсли
;
    			
КонецЕсли
;
   		
КонецЕсли
;
  	
КонецЕсли
;
КонецПроцедуры
Что бы при записи сообщения обмена, можно было определить, для какого узла в данный момент записывается сообщение, необходимо добавить глобальную переменную или параметр сеанса, в данном случае используется переменная глТекущийУзел. В эту переменную предварительно должен быть установлен текущий узел «получатель», так как внутри процедуры ПриОтправкеДанныхПодчиненному() не предусмотрено получение текущего узла. Таким образом, осталось в режиме «Предприятие» установить организации для подчиненных узлов. Следует заметить, что иногда имеет смысл вместо ОтправкаЭлементаДанных.Игнорировать использовать ОтправкаЭлементаДанных.Удалить, что бы удалить в подчиненных узлах ошибочно попавшие туда данные. Например, если из-за ошибки оператора, в документе, изначально неверно был установлен реквизит, по которому происходит фильтрация. Аналогично можно реализовать выборочную миграцию по любому другому реквизиту или даже набору реквизитов.

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Андрей Скляров (coder1cv8) 15.08.07 15:11
Эта... Комментарии приветствуются, что ли.
2. zombie (Zombie11) 03.09.07 11:02
3. il1973 (il1973) 21.05.08 19:32
4. Светлана Комарова (СветикК) 31.05.09 09:30
Эх, а если нужно выгрузить данные, которые сделали движения только по налоговому учету, в этой процедуре ПриОтправкеДанныхПодчиненному() проверку вставить ? (((
5. Светлана Комарова (СветикК) 31.05.09 09:41
еще и при полном варианте выгррузке... (
6. Александр Стародуб (StSanek) 03.06.09 11:02
нормуль, внедрил на Управление Торговлей на первый взляд все внорме. Благодарен.... Спасибо...........
7. Lilya (Lilya) 02.07.09 12:12
8. skylive (skylive) 05.08.09 14:20
Подскажите, как эту вещь внедрить в УТ ред. 10.3:
А именно:
1. Исправить ошибку: Процедура или функция с указанным именем не определена (ЕстьРеквизитДокумента)
2. Как "добавить глобальную переменную или параметр сеанса, в данном случае используется переменная глТекущийУзел. В эту переменную предварительно должен быть установлен текущий узел «получатель»"
9. Андрей Скляров (coder1cv8) 05.08.09 14:38
(8) В УТ 10.3 (насколько я помню) реализовали уже механизм фильтрации через правила обмена, советую пользоваться им...
А по поводу вопросов:
1. Посмотреть в каком модуле теперь распологается эта функция (или, быть может у нее изменилось имя?) и вызывать "через точку" с именем модуля.
2. В конфигураторе добавляем параметр, делаем обработку "обертку" нашего обмена и в ней перед формированием сообщения этот параметр устанавливаем.
10. Ольга (Sova123) 18.08.09 15:35
2. В конфигураторе добавляем параметр, делаем обработку "обертку" нашего обмена и в ней перед формированием сообщения этот параметр устанавливаем. - вот это не понятно, что за "обертку", написала вот так вот на сколько это правильно???
Процедура ПриОтправкеДанныхПодчиненному(ЭлементДанных, ОтправкаЭлемента)


Текущий_Узел_Получатель = ЭтотОбъект.Ссылка;

Если ТипЗнч(ЭлементДанных)=мТипУдалениеДанных Тогда
Возврат;
КонецЕсли;
ОбъектМетаданных=ЭлементДанных.Метаданные();

Организация = ЭлементДанных;

Если ТипЗнч(Организация) = Тип("СправочникОбъект.Организации") Тогда

Если Организации.Найти(Организация.Ссылка, "Организация") = Неопределено Тогда

ОтправкаЭлемента = ОтправкаЭлементаДанных.Удалить;

КонецЕсли;

ИначеЕсли ТипЗнч(Организация) = Тип("СправочникОбъект.ДоговорыКонтрагентов") Тогда

Если Организации.Найти(Организация.Организация.Ссылка, "Организация") = Неопределено Тогда

ОтправкаЭлемента = ОтправкаЭлементаДанных.Удалить;

КонецЕсли;


ИначеЕсли Метаданные.Документы.Содержит(ОбъектМетаданных) Тогда
Если ОбщегоНазначения.ЕстьРеквизитДокумента("Организация",ОбъектМетаданных) Тогда
Если ЭтотОбъект.Организации.Найти(ЭлементДанных.Организация,"Организация")=Неопределено Тогда
//ОтправкаЭлемента=ОтправкаЭлементаДанных.Игнорировать;
ОтправкаЭлемента = ОтправкаЭлементаДанных.Удалить;

КонецЕсли;
КонецЕсли;
ИначеЕсли Метаданные.РегистрыНакопления.Содержит(ОбъектМетаданных) Тогда
Регистратор=ЭлементДанных.Отбор.Регистратор.Значение;
Если ОбщегоНазначения.ЕстьРеквизитДокумента("Организация",Регистратор.Метаданные()) Тогда
Если Текущий_Узел_Получатель.Организации.Найти(Регистратор.Организация,"Организация")=Неопределено Тогда
// ОтправкаЭлемента=ОтправкаЭлементаДанных.Игнорировать;
ОтправкаЭлемента = ОтправкаЭлементаДанных.Удалить;
КонецЕсли;
КонецЕсли;
ИначеЕсли Метаданные.РегистрыСведений.Содержит(ОбъектМетаданных) Тогда
Если ЭлементДанных.Отбор.Найти("Регистратор")<>Неопределено Тогда
Регистратор=ЭлементДанных.Отбор.Регистратор.Значение;
Если ОбщегоНазначения.ЕстьРеквизитДокумента("Организация",Регистратор.Метаданные()) Тогда
Если Текущий_Узел_Получатель.Организации.Найти(Регистратор.Организация,"Организация")=Неопределено Тогда
//ОтправкаЭлемента=ОтправкаЭлементаДанных.Игнорировать;
ОтправкаЭлемента = ОтправкаЭлементаДанных.Удалить;

КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
11. Андрей Скляров (coder1cv8) 19.08.09 11:03
(10) Что значит "насколько правильно"? ) Разве это хоть как-то работает?... )
12. Андрей Скляров (coder1cv8) 19.08.09 11:11
+(11) В аську пишите 366-836-253 попробую "разжевать"...
13. Klavdiya (kvp) 19.10.11 10:45
Спасибо!!! Статья оказалась очень кстати. Внедряю в УТ 10.3.
14. Piter Antares (piterantares) 04.09.12 13:34
Внедрил! Год назад. Спасибо!
Есть минусы, хотя это, похоже не минусы идеи, а минусы реализации 1С )))
Частность.
Накопления по дисконтным картам не мигрируются по магазинам разных организаций
15. Арутюн (harutyunb) 09.02.14 12:22
Можно это же самое для новой версии подсистемы библиотек?
16. Артём Андриянов (CSiER) 17.04.16 16:36
(15) harutyunb, из БСП старой весрии:
// Позволяет определить есть ли среди реквизитов шапки документа реквизит с переданным именем.
Функция ЕстьРеквизитДокумента(ИмяРеквизита, МетаданныеДокумента) Экспорт
	Если МетаданныеДокумента.Реквизиты.Найти(ИмяРеквизита) = Неопределено Тогда
		Возврат Ложь;
	Иначе
		Возврат Истина;
	КонецЕсли; 
КонецФункции // ЕстьРеквизитДокумента()
...Показать Скрыть
17. Ak Uji (Akuji) 29.07.16 11:59
что то не очень по моему вариант 2 "Фильтрация данных непосредственно при записи сообщения обмена"...

я правильно понимаю что документы при выгрузке игнорируются по отбору (тут все ОК)
НО
они (документы) остаются в базе как помеченные для выгрузки и за год их накопится огромная куча - которая будет при каждой выгрузке проверятся?

Я вот еще только начал его внядрять натестил за день кучку документов. Внес в конфигурацию изменения и запустил обновление конфигурации БД.
Уже час наверное висит:
Реструктуризация РегистрСведений.ОбъектыДоступаДокументов таблица регистрации изменений ...
18. Алексей Баринов (kulidge) 26.08.16 09:36
(17) Akuji, При правильной фильтрации ничего копится не должно.
19. Алексей Баринов (kulidge) 26.08.16 09:39
а про накопление по дисконтным картам...можно чтобы во все периферийные базы ходил только регистр, а не документ-регистратор, как вариант - ведь нужны только суммы накоплений