gifts2017

Конвертация реквизитов Проведен и ПометкаУдаления из 8 в 7.7

Опубликовал Дмитрий Башинский (bashinsky) в раздел Обмен - Перенос данных из 1С7.7 в 1C8.X

Все кто сталкивался с переносом данных из 8 в 77 через конвертацию данных, знают что перенести значение реквизитов Проведен и ПометкаУдаления без танцев с бубнами, ни как не получится, При загрузке обработка ругается, что реквизит Проведен или ПометкаУдаления у документа нет. И это правда, вместо этих реквизитов у документов есть аналогичные методы, которые только возвращают значение. Точно такие танцы пришлось выполнить и мне, хотя все оказалось проще...

Предистория

Сначало была семерка, производство, файловый вариант, вся переписанная, куча новых объектов. База росла и у нее стали возникать частые транзакции, из-за которых приходилось перегружать сервер несколько раз на дню. Затем решили перейти на восьмерку, серверный вариант, конфигурация УНФ.  Причина выбора: относительно небольшая конфигурация для добавления новых объектов. Но из-за огромного количество документов и справочников и куча отчетов, решили переходить на восьмерку отделами, т.е. организовать выборочный перенос документов и и справочников туда и обратно.  Создали документ в 7, перенесли в 8, на основании создали в 8 другой документ и его перенесли в 7. И в семерке по этим докуметам пока строить отчеты.


Выполнение 

Использовав конфигурацию Конвертация данных,  версия 2.1.7.1, я стал создавать план обмена для переноса. С конвертацией начал ть впервые, возникали разные трудности, решение которых я с легкостью находил на просторах интернета. и Вот я столкнулся с переносом признака Проведен и ПометкаУдаления из 8 в 7. В конвертации при загрузки структуры семерочной базы, создает эти признаки как реквизиты объекта. И соответсвено из 7 в 8 позволяет переносить эти значения, а обратно нет. Но для начала обратно мне не надо было переносить. Но со временем потребность появилась. Начал все с признака Проведение, перерыл весь интернет и ничего, кроме как создать дополнительный реквизит (например "_Проведен") в семерке и передавать туда значение и при загрузки в семерке проверять, если истина (в семерке это 1), проводить документ. Создал реквизит у документа, написал код проверки после загрузки, все  хорошо ет, документы проводятся.

Потом потребовалось перенести ПометкуУдаления. Создал реквизит, написал код проверки. Переношу помеченные документы, а в семерке они не помечаются. Залезаю в отладчик, код отрабатывает верно, после записи документа, пометка стоит, а потом смотрю в списке документов, он не помечен. Непонятно почему!?. Лезу в отладчик, смотрю какой код выполняется после записи объекта, и вижу что 1с механизм установки этого признака сделала, а доть до рабочего варианта так и не смогла.

И вот, я решил поделиться рабочим вариантом кода со всеми.

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


Доработка обработки загрузки

Код который нужно доть находится в Процедуре ЗагрузитьДокументV8(Объект, Вид, ИмяПравила)

Отрывок кода (Полный код процедуры находится в конце статьи, а полный код обработчиков выгрузки находится в приложенном файле):

Код 1 

//--------- Заполняем реквизиты --------------------------------------------
	
	Реквизиты	=	Объект.ВыбратьУзлы("Свойство");
	Для Сч = 0 По Реквизиты.КоличествоУзлов() - 1 Цикл
		
		Реквизит					=	Реквизиты.ПолучитьУзел(Сч);
		ИдРеквизита					=	Реквизит.ПолучитьАтрибут("Имя");
		НеЗамещатьРеквизит			=	Реквизит.ПолучитьАтрибут("НеЗамещать");
		//РеквизитОперации			=	0;

		ТипОбъектаРеквизита		=	"Документ";
		ВидОбъектаРеквизита		=	Вид;
		
		//Если ПустоеЗначение(РеквизитОперации) = 1 Тогда
		//	ТипОбъектаРеквизита		=	"Документ";
		//	ВидОбъектаРеквизита		=	Вид;
		//Иначе
		//	Если ОбъектБД.СуществуетОперация() = 0 Тогда
		//		ЗаписатьОшибку("У документа вида - " + Вид + " - не существует операции!", "!!");
		//		Продолжить;
		//	КонецЕсли;
		//	ТипОбъектаРеквизита		=	"Операция";
		//	ВидОбъектаРеквизита		=	"";
		//КонецЕсли;
		
		Значение					=	УстановитьРеквизитV8(Реквизит, ТипОбъектаРеквизита, ВидОбъектаРеквизита, ИдРеквизита);
		ТипРеквизита				=	"";
		ПрочитатьИнформациюОТипеРеквизита(ТипОбъектаРеквизита, ВидОбъектаРеквизита, ИдРеквизита, ТипРеквизита);
		
		
		Если Значение = "#НеУстановлен" Тогда
			ЗаписатьОшибку("Не установлен реквизит.  Документ." + Вид + ": " + ОбъектБД + "  Реквизит: " + ИдРеквизита);
			Продолжить;
		КонецЕсли;
		

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

	ВремяДокумента = "";
	ДатаДокумента  = ДатаИзXML(Реквизит.ВыбратьУзел("Значение").Значение, ВремяДокумента);
		
 
И видим проверку если ИдРеквизита равно ПометкаУдаления, то обработка присваивает реквизиту ПометкаУдаление значение полученое из восьмерки. Но так ка у нас выдавало ошибку, дальнейший код не отрабатывался. Теперь он у нас будет отрабатываться, после того как мы изменили условие в коде 1.
Идем дальше. Смотрим где же у нас встречается реквизит ПометкаУдаления.
Код 4
	ЗаписатьОбъект(ОбъектБД);
	
	Если ПустоеЗначение(ПометкаУдаления) = 1 Тогда
		Если ОбъектБД.ПометкаУдаления() = 1 Тогда	ОбъектБД.СнятьПометкуУдаления();	КонецЕсли;
	Иначе
		Если ОбъектБД.ПометкаУдаления() = 0 Тогда	ОбъектБД.Удалить(0);				КонецЕсли;
	КонецЕсли;	                                  
	
КонецПроцедуры		//	ЗагрузитьДокументV8()
А он встречается в конце процедуры после записи объекта. Помните почему у меня в списке документ оказывался без пометки, потому-что отрабатывался данный код, т.к. реквизит ПометкаУдаления был пустым, то выполнялся код снятии пометки удаления
Если ПустоеЗначение(ПометкаУдаления) = 1 Тогда
		Если ОбъектБД.ПометкаУдаления() = 1 Тогда	ОбъектБД.СнятьПометкуУдаления();	КонецЕсли;
Чтобы исправить это меняем код 4 на 
 
Если ПустоеЗначение(ПометкаУдаления) = 0 Тогда 
	Если ПометкаУдаления = 0 Тогда
		Если ОбъектБД.ПометкаУдаления() = 1 Тогда	ОбъектБД.СнятьПометкуУдаления();	КонецЕсли;
	ИначеЕсли ПометкаУдаления = 1 Тогда
		Если ОбъектБД.ПометкаУдаления() = 0 Тогда	ОбъектБД.Удалить(0);		КонецЕсли;  
	КонецЕсли
КонецЕсли;
 
Теперь у нас пометка удаления ет как надо.
Но чтоже делать с проведение?
Добавим в код 3 условие
 
ИначеЕсли ИдРеквизита = "Проведен " Тогда //bdv
			
	Проведен = Значение;
 Реквизиту Проведен присвоим значение из восьмерки. Теперь код 3 выглядит так:
Если ИдРеквизита = "ПометкаУдаления" Тогда
			
	ПометкаУдаления = Значение;
// Добавленый код
ИначеЕсли ИдРеквизита = "Проведен" Тогда 			
	Проведен = Значение;
// Добавленый код
ИначеЕсли	ИдРеквизита = "ДатаДок" Тогда

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

	УзелСсылки = Объект.ВыбратьУзел("Ссылка");


	Если ПустоеЗначение(УзелСсылки) = 0 Тогда
		ТекущийОбъект = УстановитьДокументПоСсылкеV8(УзелСсылки, Вид, СозданНовыйОбъект, НовыеНеСоздавать, ОбъектМД, Объект);
		
		
		Если ТекущийОбъект = "Ошибка" Тогда Возврат КонецЕсли;
		                                           
		ОбъектБД	=	СоздатьОбъект("Документ." + Вид);    
		
		Если ПустоеЗначение(ТекущийОбъект) = 0 Тогда

			НеЗамещатьНайденные = Объект.ПолучитьАтрибут("НеЗамещать");
			
			Если СозданНовыйОбъект = 0 Тогда
				Если ПустоеЗначение(НеЗамещатьНайденные) = 0 Тогда
					Если ТекущийОбъект.ПометкаУдаления() = 0 Тогда	//	этот объект не создан по ссылке из реквизитов других объектов
						Возврат;	//	найденные не замещаем
					КонецЕсли;
				КонецЕсли;
			КонецЕсли;
			
			СтатусПроведения	=	гТабКэшПараметровЗагрузки.СтатусПроведения;
			ОтменитьПроведение	=	Число(Объект.ПолучитьАтрибут("ОтменитьПроведение"));
			
			ОбъектБД.НайтиДокумент(ТекущийОбъект);

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

		ЗначениеНомераДокумента = "";
		УзелНомераДокумента		= Объект.ВыбратьУзел("Свойство[@Имя=""НомерДок""]");
		Если ПустоеЗначение(УзелНомераДокумента) = 0 Тогда
			//ЗначениеНомераДокумента		=	УзелНомераДокумента.ПолучитьАтрибут("Значение");
			ЗначениеНомераДокумента = УстановитьРеквизитV8(УзелНомераДокумента, "Документ", Вид, "НомерДок");
		КонецЕсли;
		Если ПустоеЗначение(ЗначениеНомераДокумента) = 0 Тогда
			ОбъектБД.НомерДок			=	ЗначениеНомераДокумента;
		Иначе
			ЗначениеДатыДокумента		=	"";
			УзелДатыДокумента			=	Объект.ВыбратьУзел("Свойство[@Имя=""ДатаДок""]");
			Если ПустоеЗначение(УзелДатыДокумента) = 0 Тогда
				//ЗначениеДатыДокумента	=	Дата(УзелДатыДокумента.ПолучитьАтрибут("Значение"));
				ЗначениеДатыДокумента	=	УстановитьРеквизитV8(УзелДатыДокумента, "Документ", Вид, "ДатаДок");
			КонецЕсли;
			Если ПустоеЗначение(ЗначениеДатыДокумента) = 1 Тогда ЗначениеДатыДокумента = ФормДатаКон КонецЕсли;
			ОбъектБД.ДатаДок			=	ЗначениеДатыДокумента;
			ОбъектБД.УстановитьНовыйНомер();
		КонецЕсли;
		
	КонецЕсли;
	
	// Локальный обработчик "ПриЗагрузке"
	НомерСтроки = 0;
	Если ТаблицаПравилКонвертации.НайтиЗначение(ИмяПравила, НомерСтроки, "Код") = 1 Тогда
		ТаблицаПравилКонвертации.ПолучитьСтрокуПоНомеру(НомерСтроки);
		Если ТаблицаПравилКонвертации.ЕстьОбработчикПриЗагрузке = 1 Тогда
			Отказ = Шаблон("[ПКО_ПриЗагрузке_" + ИмяПравила + "(ОбъектБД, ИмяПравила, Объект)]");
			Если (ТипЗначенияСтр(Отказ) = "Строка") И (Отказ <> "0") Тогда
				Сообщить("Функция не обнаружена (" + Отказ + ")");
				Протокол.ДобавитьСтроку("     Функция не обнаружена (" + Отказ + ")");
			КонецЕсли;
			Если Число(Отказ) = 1 Тогда
				Возврат;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;                          
	
	ЕстьКонтроль				=	ОбъектМД.КонтрольУникальности;
	Уникальность				=	ОбъектМД.ПериодичностьНомера;
	АвтоНумерация				=	ОбъектМД.АвтоНумерация - 1;
	                    

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

		ТипОбъектаРеквизита		=	"Документ";
		ВидОбъектаРеквизита		=	Вид;
		
		//Если ПустоеЗначение(РеквизитОперации) = 1 Тогда
		//	ТипОбъектаРеквизита		=	"Документ";
		//	ВидОбъектаРеквизита		=	Вид;
		//Иначе
		//	Если ОбъектБД.СуществуетОперация() = 0 Тогда
		//		ЗаписатьОшибку("У документа вида - " + Вид + " - не существует операции!", "!!");
		//		Продолжить;
		//	КонецЕсли;
		//	ТипОбъектаРеквизита		=	"Операция";
		//	ВидОбъектаРеквизита		=	"";
		//КонецЕсли;
		
		Значение					=	УстановитьРеквизитV8(Реквизит, ТипОбъектаРеквизита, ВидОбъектаРеквизита, ИдРеквизита);
		ТипРеквизита				=	"";
		ПрочитатьИнформациюОТипеРеквизита(ТипОбъектаРеквизита, ВидОбъектаРеквизита, ИдРеквизита, ТипРеквизита);
		
		
		Если Значение = "#НеУстановлен" Тогда
			ЗаписатьОшибку("Не установлен реквизит.  Документ." + Вид + ": " + ОбъектБД + "  Реквизит: " + ИдРеквизита);
			Продолжить;
		КонецЕсли;
		

		
		Если (ПустоеЗначение(ТипРеквизита) = 1) И (ИдРеквизита <> "ПометкаУдаления") И (ИдРеквизита <> "Проведен") Тогда
			
			ПредставлениеРеквизита		=	ТипОбъектаРеквизита + "." + ВидОбъектаРеквизита + "." + ИдРеквизита;
			ЗаписатьОшибку("Неверное имя реквизита:" + ПредставлениеРеквизита);
			Продолжить;
			
		ИначеЕсли	ТипРеквизита = "Неопределенный" Тогда
			
			//ТипЗнач			=	Реквизит.ПолучитьАтрибут("ТипЗначения");
			//ВидЗнач			=	Реквизит.ПолучитьАтрибут("ВидЗначения");
			//Точность		=	0;
			//Если ТипЗнач = "Число" Тогда
			//	СтрТочность	=	Значение;
			//	Точность	=	СтрДлина(	ОтделитьРазделителем(СтрТочность, ".")	);
			//КонецЕсли;
			//Если	ПустоеЗначение(РеквизитОперации) = 1	Тогда
			//	ОбъектБД.НазначитьТип(ИдРеквизита, ТипЗнач + ?(ПустоеЗначение(ВидЗнач)=1, "", "." + ВидЗнач), СтрДлина(Значение) + 10, Точность);
			//Иначе
			//	ОбъектБД.Операция.НазначитьТип(ИдРеквизита, ТипЗнач + ?(ПустоеЗначение(ВидЗнач)=1, "", "." + ВидЗнач), СтрДлина(Значение) + 10, Точность);
			//КонецЕсли;
			
			ТипЗнач  = ОпределитьСтроковыйТип(Реквизит.ПолучитьАтрибут("Тип"));
			Точность = 0;
			Если ТипЗнач = "Число" Тогда
				СтрТочность	=	Значение;
				Точность	=	СтрДлина(	ОтделитьРазделителем(СтрТочность, ".")	);
			КонецЕсли;
			ОбъектБД.НазначитьТип(ИдРеквизита, ТипЗнач, СтрДлина(Значение) + 10, Точность);
			
		КонецЕсли;


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

		
		Если ИдРеквизита = "ПометкаУдаления" Тогда
			
			ПометкаУдаления = Значение;
			
		ИначеЕсли ИдРеквизита = "Проведен" Тогда
			
			Проведен = Значение;
			
		ИначеЕсли		ИдРеквизита = "ДатаДок" Тогда

			ВремяДокумента = "";
			ДатаДокумента  = ДатаИзXML(Реквизит.ВыбратьУзел("Значение").Значение, ВремяДокумента);
			

			Если ОбъектБД.Проведен() = 1 Тогда
				Если (ДатаДокумента <> ОбъектБД.ДатаДок) Или (ОбъектБД.ПолучитьВремя() <> ВремяДокумента) Тогда
					ЗаписатьОшибку("Изменены дата или время проведенного документа - " + ОбъектБД + "!
									|Проведение документа отменено.", "!");
					ОбъектБД.СделатьНеПроведенным();
				Иначе
					Продолжить;
				КонецЕсли; 
			КонецЕсли;
			
			
			//Если СозданНовыйОбъект = 0 Тогда	//	Найден
			//	Если ОбъектБД.ПолучитьВремя() = Значение Тогда Продолжить КонецЕсли;	//	значение не изменилось
			//	Если ОбъектБД.Проведен() = 1 Тогда
			//		ЗаписатьОшибку("Изменено время проведенного документа - " + ОбъектБД + "!
			//						|Проведение документа отменено.", "!");
			//		ОбъектБД.СделатьНеПроведенным();
			//	КонецЕсли;
			//КонецЕсли;

			ОбъектБД.ДатаДок = ДатаДокумента;
			ОбъектБД.АвтоВремяОтключить();
		    ОбъектБД.УстановитьВремя(Число(Сред(ВремяДокумента, 1, 2)), Число(Сред(ВремяДокумента, 4, 2)), Число(Сред(ВремяДокумента, 7, 2)));
		
		//ИначеЕсли	ПустоеЗначение(РеквизитОперации) = 1	Тогда
		Иначе
			
			ОбъектБД.УстановитьАтрибут(ИдРеквизита, Значение);
			
		//Иначе
		//			  
		//	Если СозданНовыйОбъект = 0 Тогда	//	Найден
		//		Если ОбъектБД.Операция.ПолучитьАтрибут(ИдРеквизита) = Значение Тогда Продолжить КонецЕсли;	//	значение не изменилось
		//	КонецЕсли;
		//	
		//	ОбъектБД.Операция.УстановитьАтрибут(ИдРеквизита, Значение);
			
		КонецЕсли;
		
	КонецЦикла;


	
	//--------- ТабличнаяЧасть ----------------------------------------------------------

	
	ТЧ = Объект.ВыбратьУзел("ТабличнаяЧасть");

	Если ПустоеЗначение(ТЧ) = 0 Тогда
	
		НеЗамещатьТЧ    = ТЧ.ПолучитьАтрибут("НеЗамещать");

		Строки			=	ТЧ.ВыбратьУзлы("Запись");
		КоличествоСтрок	=	Строки.КоличествоУзлов();
		
		Если ПустоеЗначение(НеЗамещатьТЧ) = 1 Тогда
			Если ПустоеЗначение(КоличествоСтрок) = 0 Тогда ОбъектБД.УдалитьСтроки() КонецЕсли;
		КонецЕсли;
		
		Для СчСтрок = 0 По КоличествоСтрок - 1 Цикл
			СтрокаДокумента	=	Строки.ПолучитьУзел(СчСтрок);

			Реквизиты		=	СтрокаДокумента.ВыбратьУзлы("Свойство");
			КолвоРеквизитов	=	Реквизиты.КоличествоУзлов();
			               
			Если ПустоеЗначение(КолвоРеквизитов) = 0 Тогда
				ОбъектБД.НоваяСтрока();
			Иначе
				Продолжить;
			КонецЕсли;

			
			Для Сч = 0 По КолвоРеквизитов - 1 Цикл
				Реквизит					=	Реквизиты.ПолучитьУзел(Сч);
				ИдРеквизита					=	Реквизит.ПолучитьАтрибут("Имя");
				Значение					=	УстановитьРеквизитV8(Реквизит, "Документ", Вид, ИдРеквизита);
				
				Если Значение = "#НеУстановлен" Тогда
					ЗаписатьОшибку("Не установлен реквизит.  Документ." + Вид + ": " + ОбъектБД + "  Реквизит: " + ИдРеквизита);
					Продолжить;
				КонецЕсли;

				
				ТипРеквизита				=	"";
				ПрочитатьИнформациюОТипеРеквизита("Документ", Вид, ИдРеквизита, ТипРеквизита);
				Если 		ПустоеЗначение(ТипРеквизита) = 1 Тогда
					ПредставлениеРеквизита		=	"Документ." + Вид + "." + ИдРеквизита;
					ЗаписатьОшибку("Неверное имя реквизита:" + ПредставлениеРеквизита);
					Продолжить;
				ИначеЕсли	ТипРеквизита = "Неопределенный" Тогда
					//ТипЗнач			=	Реквизит.ПолучитьАтрибут("ТипЗначения");
					//ВидЗнач			=	Реквизит.ПолучитьАтрибут("ВидЗначения");
					//Точность		=	0;
					//Если ТипЗнач = "Число" Тогда
					//	СтрТочность	=	Значение;
					//	Точность	=	СтрДлина(	ОтделитьРазделителем(СтрТочность, ".")	);
					//КонецЕсли;
					//ОбъектБД.НазначитьТип(ИдРеквизита, ТипЗнач + ?(ПустоеЗначение(ВидЗнач)=1, "", "." + ВидЗнач), СтрДлина(Значение) + 10, Точность);
					ТипЗнач  = ОпределитьСтроковыйТип(Реквизит.ПолучитьАтрибут("Тип"));
					Точность = 0;
					Если ТипЗнач = "Число" Тогда
						СтрТочность	=	Значение;
						Точность	=	СтрДлина(	ОтделитьРазделителем(СтрТочность, ".")	);
					КонецЕсли;
					ОбъектБД.НазначитьТип(ИдРеквизита, ТипЗнач, СтрДлина(Значение) + 10, Точность);
				КонецЕсли;
				ОбъектБД.УстановитьАтрибут(ИдРеквизита, Значение);
			КонецЦикла;
			
		КонецЦикла;

	КонецЕсли; // загрузка табл. части
	
	//--------------------------------------------------------------------------
	
	Если ПроверкаУникальностиДокумента(ОбъектБД, ЕстьКонтроль, Уникальность, АвтоНумерация) = 0 Тогда Возврат КонецЕсли;
	                         
	// Глобальный обработчик "ПослеЗагрузкиОбъекта"
	Если мКонвертацияПослеЗагрузкиОбъекта = 1 Тогда
		Отказ = Шаблон("[Конвертация_ПослеЗагрузкиОбъекта(ОбъектБД, ИмяПравила)]");
		Если Число(Отказ) = 1 Тогда
			Возврат;
		КонецЕсли;
	КонецЕсли;
                                
	// Локальный обработчик "ПослеЗагрузки"
	НомерСтроки = 0;
	Если ТаблицаПравилКонвертации.НайтиЗначение(ИмяПравила, НомерСтроки, "Код") = 1 Тогда
		ТаблицаПравилКонвертации.ПолучитьСтрокуПоНомеру(НомерСтроки);
		Если ТаблицаПравилКонвертации.ЕстьОбработчикПослеЗагрузки = 1 Тогда
			Отказ = Шаблон("[ПКО_ПослеЗагрузки_" + ИмяПравила + "(ОбъектБД, ИмяПравила, Объект)]"); 
			Если (ТипЗначенияСтр(Отказ) = "Строка") И (Отказ <> "0") Тогда
				Сообщить("Функция не обнаружена (" + Отказ + ")");
				Протокол.ДобавитьСтроку("     Функция не обнаружена (" + Отказ + ")");
			КонецЕсли;
			Если Число(Отказ) = 1 Тогда
				Возврат;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;                          

	ЗаписатьОбъект(ОбъектБД);
        Если ПустоеЗначение(Проведен) = 0 Тогда
		Если Проведен = 1 Тогда 
			ОбъектБД.Провести();
		ИначеЕсли Проведен = 0 Тогда  
			Если ОбъектБД.Проведен() = 1 Тогда	ОбъектБД.СделатьНеПроведенным();	КонецЕсли;  
		КонецЕсли;
	КонецЕсли;
	
	Если ПустоеЗначение(ПометкаУдаления) = 0 Тогда 
		Если ПометкаУдаления = 0 Тогда
			Если ОбъектБД.ПометкаУдаления() = 1 Тогда	ОбъектБД.СнятьПометкуУдаления();	КонецЕсли;
		ИначеЕсли ПометкаУдаления = 1 Тогда
			Если ОбъектБД.ПометкаУдаления() = 0 Тогда	ОбъектБД.Удалить(0);				КонецЕсли;  
		КонецЕсли
	КонецЕсли;
 	                                  
	
КонецПроцедуры		//	ЗагрузитьДокументV8()
 

Скачать файлы

Наименование Файл Версия Размер
Полный текст обработчиков 3
.txt 188,54Kb
03.03.14
3
.txt 188,54Kb Скачать

См. также

Подписаться Добавить вознаграждение
Комментарии
1. Дмитрий Башинский (bashinsky) 12.12.13 17:55
Эта статья рассчитана на тех, кто уже немного знаком с конфигурацией Конвертация данных. Если у кого-нибудь есть другое решение расскажите.
2. NickKrsk (nick_krsk) 13.12.13 05:03
А что если производить установку пометки удаления в обработчике "После загрузки"?
3. Дмитрий Башинский (bashinsky) 13.12.13 09:24
обработка будет ругается, Неверное имя реквизита: ПометкаУдаления. Потому-что сначала идет проверка на ТипРеквизита, а так как это не реквизит, обработка возвращает пустое значение и пропускает код ниже. После проверки выполнятся обработчик "После загрузки".
4. Веселов Александр (aves) 18.12.13 10:52
(1) - Общий реквизит = -1=Удален\0=норм\1=проведен
После загрузки документа - добавляем его в массив для обработки.
После обработки конвертации - обработка всех документов массива
2 года on-line - полет нормальный
5. Дмитрий Башинский (bashinsky) 18.12.13 12:47
(4) aves, Общий реквизит - это в документе? Если да, то его нужно добавлять в каждый документ.
6. Веселов Александр (aves) 18.12.13 14:46
(5) в 77 есть общие реквизиты документов :-)
8. Евгений (gep) 13.02.15 20:37
Здравствуйте!
Во-первых, спасибо за ценную информацию - очень помогло.
Во-вторых, хочу добавить небольшую поправку:
Если документ проведен в базе-приемнике, а в базе-источнике снято проведение, то при обмене не произойдет отмена проведения в приемнике (во всяком случае при обмене м/у 7.7->7.7), т.к. в строках:
    Если ПустоеЗначение(Проведен) = 0 Тогда
        Если Проведен = 1 Тогда 
            ОбъектБД.Провести();
        ИначеЕсли Проведен = 0 Тогда  
            Если ОбъектБД.Проведен() = 1 Тогда    ОбъектБД.СделатьНеПроведенным();    КонецЕсли;  
        КонецЕсли;
    КонецЕсли;
...Показать Скрыть

Пустое значение и 0 в 7.7 - одно и тоже (а булево из 8-ки конвертируется в 0/1)
Следовательно если документ не проведен в источнике, и проведен в приемнике - ничего не произойдет, т.к. выражение ПустоеЗначение(Проведен) вернет 1, хотя Проведен не пуст, а равен 0. (7.7 такая 7.7)
Доработка проста. В строках:
ИначеЕсли ИдРеквизита = "Проведен" Тогда             
    Проведен = Значение;

меняем на
ИначеЕсли ИдРеквизита = "Проведен" Тогда             
    Проведен = Значение + 1;

И соответственно:
    Если ПустоеЗначение(Проведен) = 0 Тогда
        Если Проведен = 2 Тогда 
            ОбъектБД.Провести();
        ИначеЕсли Проведен = 1 Тогда  
            Если ОбъектБД.Проведен() = 1 Тогда    ОбъектБД.СделатьНеПроведенным();    КонецЕсли;  
        КонецЕсли;
    КонецЕсли;
...Показать Скрыть
9. Дмитрий Башинский (bashinsky) 16.02.15 11:56
(8) gep, Спасибо, что нашли ошибку. У себя я ее давно исправил, но сюда внести изменения не было времени.