gifts2017

Анализ журнала регистрации для автонастройки списка выгружаемых объектов в обработке ВыгрузкаЗагрузкаДанныхXML82.epf

Опубликовал q_i в раздел Администрирование - Журнал регистрации

Сказ о том, как с помощью слегка модифицированной обработки ВыгрузкаЗагрузкаДанныхXML82.epf решить задачу "Выгрузить из базы-источника все объекты, которые заданный пользователь изменил в указанный период".
Данная публикация может быть интересна тем, кто хочет узнать: а) как программно анализировать журнал регистрации и б) как программно настраивать список выгружаемых объектов в обработке ВыгрузкаЗагрузкаДанныхXML82.epf.

История такая. Есть две базы - одна рабочая, другая тестовая копия. Так получилось (не будем обсуждать почему), что некий пользователь проделал большой объём работы в тестовой базе - он изменил в старых периодах около тысячи существующих документов и создал несколько новых. Работал он день и ночь на протяжении нескольких дней, не спал и не ел (по крайней мере примерно так мне описала ситуацию главный бухгалтер). В общем, в итоге возникла необходимость перенести эти изменённые документы из тестовой базы обратно в рабочую. Переносить ручками было нереально (большой объём, точных сведений что и где менялось нет), поэтому нужно было как-то заавтоматизировать процесс переноса.

Чтобы выполнить эту задачу, нужно было ответить на два вопроса - что переносить и чем переносить? Над вторым вопросом долго думать не пришлось, так как есть палочка-выручалочка под названием ВыгрузкаЗагрузкаДанныхXML82.epf. Теперь нужно было ответить на первый вопрос - что? Предоставить список изменённых документов пользователь, разумеется, не смог. Поэтому единственный способ узнать что же нужно переносить - это проанализировать журнал регистрации (нужно выгрузить все объекты, которые этот пользователь изменил/создал в указанный период времени).

По итогам в обработку ВыгрузкаЗагрузкаДанныхXML82.epf версии 2.1.8 была добавлена ещё одна кнопка с незамысловатым названием Кнопка1 и нарисован такой обработчик её нажатия:

Процедура Кнопка1Нажатие(Элемент)
	
	Дата1 = Дата(2015, 08, 01); // Отбор записей ЖР по периоду: дата начала периода (или Неопределено)
	Дата2 = Дата(2015, 08, 31);	// Отбор записей ЖР по периоду: дата окончания периода (или Неопределено)
	Пользователь = "Иванов И.И.";	// Отбор записей ЖР по пользователю: имя пользователя (или Неопределено)
	
	// {{ Получаем таблицу значений с записями ЖР
	ТЗ = Новый ТаблицаЗначений;
	Фильтр = Новый Структура;
	Если ЗначениеЗаполнено(Дата1) Тогда
		Фильтр.Вставить("ДатаНачала", НачалоДня(Дата1));	
	КонецЕсли; 
	Если ЗначениеЗаполнено(Дата2) Тогда
		Фильтр.Вставить("ДатаОкончания", КонецДня(Дата2));
	КонецЕсли; 
	Если ЗначениеЗаполнено(Пользователь) Тогда
		Фильтр.Вставить("Пользователь", Пользователь);
	КонецЕсли; 
	МассивСобытий = Новый Массив;
	МассивСобытий.Добавить("_$Data$_.New");
	МассивСобытий.Добавить("_$Data$_.Post");
	МассивСобытий.Добавить("_$Data$_.Unpost");
	МассивСобытий.Добавить("_$Data$_.Update");
	Фильтр.Вставить("Событие", МассивСобытий);
	МассивМетаданных = Новый Массив;
	Для Каждого МетаДок Из Метаданные.Документы Цикл
		МассивМетаданных.Добавить(МетаДок);
	КонецЦикла; 
	Фильтр.Вставить("Метаданные", МассивМетаданных);
	ВыгрузитьЖурналРегистрации(ТЗ, Фильтр, "Дата, Пользователь, Событие, Метаданные, Данные, ПредставлениеДанных");
	// Получаем таблицу значений с записями ЖР }}
	
	// Для целей отладки можно посмотреть содержимое таблицы с записями ЖР: 
	//Если ТЗ.ВыбратьСтроку() = Неопределено Тогда
	//	Возврат;
	//КонецЕсли;
	
	ТЗ.Свернуть("Метаданные, Данные"); // удаляем дубли
	
	// {{ Формируем соответствие, у которого в качестве ключей - тип метаданных,
	// а в качестве значений - массивы ссылок на объекты
	// (возможно, лучше было бы использовать ДеревоЗначений, но уже лень переделывать)
	ВремСоотв = Новый Соответствие;
	Для Каждого СтрокаТЗ Из ТЗ Цикл
		МассивДанных = ВремСоотв[СтрокаТЗ.Метаданные];
		Если МассивДанных = Неопределено Тогда
			МассивДанных = Новый Массив; 
		КонецЕсли; 
		МассивДанных.Добавить(СтрокаТЗ.Данные);
		ВремСоотв[СтрокаТЗ.Метаданные] = МассивДанных;
	КонецЦикла; 
	// Формируем соответствие, у которого в качестве ключей - тип метаданных,
	// а в качестве значений - массивы ссылок на объекты }}
	
	КолвоОшибок = 0;
	
	// {{ Настраиваем какие типы объектов выгружать и какие при этом отборы использовать
	Для Каждого КлючИЗначение Из ВремСоотв Цикл
		ТекИмяМетаданных = КлючИЗначение.Ключ;
		ТекМассивСсылок = КлючИЗначение.Значение;
		
		ТекОбъектМД = Метаданные.НайтиПоПолномуИмени(ТекИмяМетаданных);
		
		ТекущаяСтрока = ДеревоМетаданных_КопияФормы.Строки.Найти(ТекОбъектМД, "Метаданные", Истина);
		Если ТекущаяСтрока = Неопределено Тогда
			Сообщить("Не найдена строка дерева метаданных для " + ТекИмяМетаданных);
			КолвоОшибок = КолвоОшибок + 1; 
			Продолжить;
		КонецЕсли; 
		ЭлементыФормы.ДеревоМетаданных.ТекущаяСтрока = ТекущаяСтрока;
		ДеревоМетаданныхПриАктивизацииСтроки(Неопределено); // выполним стандартную настройку построителя 
		// Очищаем существующие отборы построителя
		КолвоОтборов = Построитель.Отбор.Количество();
		Для ОбратныйИндекс = 1 По КолвоОтборов Цикл
			ТекИндекс = КолвоОтборов - ОбратныйИндекс;
			Построитель.Отбор.Удалить(ТекИндекс);
		КонецЦикла;
		// Добавляем отбор по списку ссылок
		ЭлемОтбора = Построитель.Отбор.Добавить("Ссылка");
		ЭлемОтбора.ВидСравнения = ВидСравнения.ВСписке;
		ЭлемОтбора.Значение = Новый СписокЗначений;
		ЭлемОтбора.Значение.ЗагрузитьЗначения(ТекМассивСсылок);
		ЭлемОтбора.Использование = Истина;
		ТекущаяСтрока.НастройкиПостроителя = Построитель.ПолучитьНастройки();
		ТекущаяСтрока.ИспользоватьОтбор    = ИСТИНА;
		ТекущаяСтрока.Выгружать = Истина; // устанавливаем флажок "Выгружать" для текущего типа объектов
		// Для целей отладки можно вывести какие объекты попали в отбор:
		//Сообщить("Для объектов с типом " + ТекИмяМетаданных + " добавлен отбор по ссылке со следующим списком значений:");
		//Для Каждого ЭлемСЗ Из СЗ Цикл
		//	Сообщить(" - " + ЭлемСЗ.Значение);
		//КонецЦикла; 
	КонецЦикла;
	// Настраиваем какие типы объектов выгружать и какие при этом отборы использовать }}
	
	Сообщить("Настройка отборов завершена! Ошибок: " + КолвоОшибок);

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

На выходе получили требуемый XML, который и загрузили в рабочую базу.

P.S. Кстати говоря, в модификации самой обработки ВыгрузкаЗагрузкаДанныхXML82.epf особой нужды, скорее всего, нет. Полагаю, что можно нарисовать отдельную обработку-обёртку, которая получит из ЖР необходимые данные, создаст объект штатной обработки ВыгрузкаЗагрузкаДанныхXML82.epf и программно настроит у неё список выгружаемых объектов. Но это уже совсем другая история...

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Никита Коротаев (bforce) 12.08.15 14:54
Мне понравилась сама идея чтения журнала регистрации для отлова изменившихся объектов. Ранее она мне в голову не приходила. Спасибо!
infostart user; +1 Ответить
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа