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

Все кто сталкивался с переносом данных из 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()
 

11 Comments

  1. bashinsky

    Эта статья рассчитана на тех, кто уже немного знаком с конфигурацией Конвертация данных. Если у кого-нибудь есть другое решение расскажите.

    Reply
  2. nick_krsk

    А что если производить установку пометки удаления в обработчике «После загрузки»?

    Reply
  3. bashinsky

    обработка будет ругается, Неверное имя реквизита: ПометкаУдаления. Потому-что сначала идет проверка на ТипРеквизита, а так как это не реквизит, обработка возвращает пустое значение и пропускает код ниже. После проверки выполнятся обработчик «После загрузки».

    Reply
  4. aves

    (1) — Общий реквизит = -1=Удален=норм1=проведен

    После загрузки документа — добавляем его в массив для обработки.

    После обработки конвертации — обработка всех документов массива

    2 года on-line — полет нормальный

    Reply
  5. bashinsky

    (4) aves, Общий реквизит — это в документе? Если да, то его нужно добавлять в каждый документ.

    Reply
  6. aves

    (5) в 77 есть общие реквизиты документов 🙂

    Reply
  7. Xershi
  8. gep

    Здравствуйте!

    Во-первых, спасибо за ценную информацию — очень помогло.

    Во-вторых, хочу добавить небольшую поправку:

    Если документ проведен в базе-приемнике, а в базе-источнике снято проведение, то при обмене не произойдет отмена проведения в приемнике (во всяком случае при обмене м/у 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 Тогда    ОбъектБД.СделатьНеПроведенным();    КонецЕсли;
    КонецЕсли;
    КонецЕсли;
    Reply
  9. bashinsky

    (8) gep, Спасибо, что нашли ошибку. У себя я ее давно исправил, но сюда внести изменения не было времени.

    Reply
  10. M_Volkov

    (1) bashinsky, не могли бы помочь по вопросу https://www.forum.mista.ru/topic.php?id=833289?

    Reply
  11. compaud

    На строчке

    ОбъектБД.УстановитьВремя(Число(Сред(ВремяДокумента, 1, 2)), Число(Сред(ВремяДокумента, 4, 2)), Число(Сред(ВремяДокумента, 7, 2)));

    Возникает ошибка

    {путьдообработки(2879)}: Не выбран документ!

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *