Полезные приемы при работе с Конвертацией данных 2.1. Логирование, интерактивное управление, дозаполнение и постпроведение документов

Публикация № 1038581

Обмен - Перенос данных из 1C8 в 1C8

конвертация данных КД 2.1 обмены доработки

42
Некоторые полезные приемы для КД 2.1, которые могут пригодиться как при доработке типовых правил, так и самописных.

Очень часто приходится делать/дорабатывать конвертации разного плана. В связи с этим появилось несколько шаблонов, решающих общие для всех обменов задачи, с которыми хотелось бы поделиться.

1. Интерактивное управление обменами.

Типовые обмены и большинство рукописных не позволяют интерактивно управлять правилами. Например, на время сдачи отчетности необходимо отключить в обмене несколько видов документов. Обычно это решают либо изменением правил регистрации либо изменением самих правил конвертации. Я на нескольких обменах сделал следующее:

- создал расширение, в котором заведен регистр сведений (непериодический, независимый) и перечисление (перечисление на самом деле не обязательно, можно например и строку использовать). Структура регистра на рис.

Измерение - ТипОбъекта (перечисление либо строка)

Ресурс  - Выгружать (булево)

После этого в режиме предприятия заполняем флаги обмена.

Далее в самой конвертации:

//Перед выгрузкой данных
//Получаем список флагов на выгрузку
Запрос = Новый Запрос;
Запрос.Текст = "Выбрать 
| УправлениеОбменомСБП.ТипОбъекта КАК ТипОбъекта,
| УправлениеОбменомСБП.Выгружать
|ИЗ РегистрСведений. УправлениеОбменомСБП КАК УправлениеОбменомСБП";
Выборка = Запрос.Выполнить().Выбрать();
тзОбъектов = Новый ТаблицаЗначений;
тзОбъектов.Колонки.Добавить("ТипОбъекта");
тзОбъектов.Колонки.Добавить("Выгружать");
Пока Выборка.Следующий() Цикл
		нСтрока = тзОбъектов.Добавить();
		нСтрока.ТипОбъекта = ВРег(СтрЗаменить(Выборка.ТипОбъекта, " ",""));
		нСтрока.Выгружать =  Выборка.Выгружать;
КонецЦикла;
Параметры.Вставить("тзОбъектовНаВыгрузку", тзОбъектов);

Теперь у нас есть таблица с описанием типа данных и флагом выгрузки.

Далее нам просто необходимо в обработчиках выгрузки добавить проверку.

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

Если флаг выгрузки не установлен, то делаем Отказ=Истина. При необходимости  здесь же можно удалять объект с узла.

Таким образом, если нам нужно быстро отключить выгрузку некоторых типов объектов, мы в регистре просто устанавливаем значение Выгружать в Ложь.

2. Произвольное логирование обменов

Для того, чтобы собирать логи выгрузки и загрузки нам потребуется два массива строк. На примере выгрузки создаем массив пМассивЛогов и добавляем его в параметры.

Обработчик ПередВыгрузкойДанных

пМассивЛогов = Новый Массив;
Параметры.Вставить("пМассивЛогов",	пМассивЛогов);

Далее в нужных обработчиках выгрузки формируем нужные нам сообщения, добавляем их в массив

 

СообщениеЛога - формируем некое сообщение

Параметры.пМассивЛогов.Добавить(СообщениеЛога);  

      

В обработчике ПослеВыгрузкиДанных на основании массива делаем лог-файл в указанной папке.я указал папку жестко, но можно например завести константу в базе и путь к папке хранить там.

    пМассивЛогов = Параметры.пМассивЛогов;
	Если пМассивЛогов.Количество()>0 Тогда
		ДатаВыгрузки = СтрЗаменить(СтрЗаменить(СтрЗаменить(Строка(ТекущаяДата()), ".","")," ", ""),":", "");
		Каталог = "\\test\BP1C\log\";
		Назначение = "Бп_Онли";
		пИмяФайлаЛога = ""+ДатаВыгрузки+"_"+"ВыгрузкаВ_"+Назначение +".txt";
		ПИмяФайлаЛогаПолное = Каталог+ пИмяФайлаЛога;
		ТекстовыйФайл = Новый ТекстовыйДокумент;			
		Для Каждого строкаЛога Из пМассивЛогов Цикл  
			ТекстовыйФайл.ДобавитьСтроку(строкаЛога);
		КонецЦикла;
		ТекстовыйФайл.Записать(
		ПИмяФайлаЛогаПолное, // путь для сохранения
		КодировкаТекста.UTF8, // кодировка
		Символы.ВК + Символы.ПС // разделитель строк
		);
	КонецЕсли;

В результате после выгрузки в указанной папке формируется файл лога. Для загрузки процедура такая же в принципе.

3. Проверка даты запрета

В обработчике Перед загрузкой данных получаем дату запрета для нужного списка пользователей (групп). В данном примере только для текущего пользователя, так как регламентное задание настроено с указанием конкретного пользователя, заведенного для обмена. Это также удобно, когда нужно найти что-то, связанное с обменом, в журнале регистрации.

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

//-----------------------------------------------------------------------------------------------

В обработчике ПослеЗагрузки делаем проверку. Ниже пример обработчика для документа РеализацияТоваровУслуг (БП 3.0).

Если Объект.Дата<Параметры.ДатаЗапрета)Тогда
	Отказ = Истина;
	ОбъектМодифицирован = Ложь;	
	СообщениеЛога = "Дата объекта меньше разрешенной. Загрузка объекта " + Объект +" отменена!";
	Параметры.пМассивЛоговЗагрузка.Добавить(СообщениеЛога);
	Сообщить(СообщениеЛога);	
Иначе
	Отказ = Ложь;		
	Документы.РеализацияТоваровУслуг.ЗаполнитьСчетаУчетаРасчетов(Объект);
	Документы.РеализацияТоваровУслуг.ЗаполнитьСчетаУчетаВТабличнойЧасти(Объект,"Товары");
	Документы.РеализацияТоваровУслуг.ЗаполнитьСчетаУчетаВТабличнойЧасти(Объект,"Услуги");
	Объект.Записать();
	СтрокаТЗ = Параметры.ПроводимыеДокументы.Добавить();
	СтрокаТЗ.Дата		= Объект.Дата;
	СтрокаТЗ.Документ	= Объект.Ссылка;
КонецЕсли;

Если документ находится в закрытом периоде. происходит отказ от записи, в противном случае документ записывается/проводится.

4. Постобработка/проведение документов

Часто возникает необходимость в том, чтобы документы после загрузки провелись в определенной последовательности, либо перезаполнились с учетом данных базы (например проверка остатков и перезаполнение табличной части товаров в соответствие с ними). Для этих целей можно использовать следующий механизм.

В обработчике ПередЗагрузкойДанных заводим параметр типа ТаблицаЗначений

ПроводимыеДокументы = Новый ТаблицаЗначений;
ПроводимыеДокументы.Колонки.Добавить("Дата");
ПроводимыеДокументы.Колонки.Добавить("Документ");
ПроводимыеДокументы.Колонки.Добавить("Приоритет");
Параметры.Вставить("ПроводимыеДокументы", ПроводимыеДокументы);

Далее в обработчиках объектов ПослеЗагрузки добавляем

Объект.Записать();
СтрокаТЗ = Параметры.ПроводимыеДокументы.Добавить();
СтрокаТЗ.Дата		= Объект.Дата;
СтрокаТЗ.Документ	= Объект.Ссылка; 
СтрокаТЗ. Приоритет	= 0;

В обработчике ПослеЗагрузкиДанных

Параметры.ПроводимыеДокументы.Сортировать("Дата"); //либо по Приоритету
	Для Каждого СтрокаТЗ ИЗ Параметры.ПроводимыеДокументы Цикл
			пСсылкаТЧ = СтрокаТЗ.Документ;
			Объект = пСсылкаТЧ.ПолучитьОбъект();
			//Далее постобработка документа. дозаполнение, проверка.
	КонецЦикла;

В обработчике, приведенном выше, можно делать различные операции с документом, а также в зависимости от условий делать проведение/отмену проведения. помечать на удаление и т.д.

При необходимости могу прикрепить пример рабочих правил, где данные методики использовались.

42

См. также

Специальные предложения

Комментарии
Избранное Подписка Сортировка: Древо
1. wowik 579 23.04.19 10:25 Сейчас в теме
+1. "При необходимости могу прикрепить пример рабочих правил, где данные методики использовались." - да, прикрепляйте, всегда лучше пощелкать доработку в КД.
YPermitin; +1 Ответить
2. YPermitin 3281 23.04.19 12:18 Сейчас в теме
(0) Выкладывайте в комментарий или GitHub, очень интересно посмотреть примеры использования.
3. maks_20 60 23.04.19 12:39 Сейчас в теме
Вечером выкину в комментарии пример с рабочего обмена между УТ и БП
YPermitin; +1 Ответить
4. maks_20 60 23.04.19 15:53 Сейчас в теме
Файл с одной из версий правил. Для просмотра размещения обработчиков подойдет, в остальном сильно доработан по сравнению с типовым обменом УТ11 и БП 3.
Прикрепленные файлы:
Правила_в49_дляИнф.xml
5. acsent 1135 23.04.19 17:25 Сейчас в теме
документы к проведению - только в регистр.
иначе если что-то не проведется (хотя бы из-за блокировок)
всь обмен накроется. в лучшем случае утеряем инфу о том что документ нужно все-таки провести
6. maks_20 60 24.04.19 07:49 Сейчас в теме
(5) Можно конечно и через регистр, записывать в него объекты и ошибки при проведении. Но и в данном случае потери никакой не будет, например если при переборе документов проведение делать в попытке, а в исключении писать ошибку в лог либо дополнительно в журнал. Данный метод не только для проведения подходит, но и для какой-то обработки после загрузки.
7. Йожкин Кот 1063 24.04.19 08:54 Сейчас в теме
В п.4 чтобы 2 раза не записывать объект, можно сделать так:
СтрокаТЗ.Документ = ?(Объект.ЭтоНовый(), Объект.ПолучитьСсылкуНового(), Объект.Ссылка);

И я обычно использую глобальный обработчик "После загрузки объекта".
Также, неплохо бы распровести док-т после загрузки, а только потом уже проводить.
8. Йожкин Кот 1063 24.04.19 08:57 Сейчас в теме
Для логирования удобно использовать ЖР:
ЗаписьЖурналаРегистрации(....)
9. maks_20 60 24.04.19 09:08 Сейчас в теме
(8) Ну тут кому как... Например если в базе несколько обменов настроено и объектов грузится довольно много, каждый раз искать по журналу займет больше времени, чем пройтись по файлу лога. А с небольшими объемами да, можно не заморачиваться и просто в нужных местах запись в ЖР делать. Вариантов решения на самом деле много, я предложил только один из многих)
Оставьте свое сообщение