КД 2.х Передача произвольного параметра с объектом выгрузки при переносе 7.7-8.х

Последнее время часто стали появляться ветки с вопросами как передать какую-то произвольную информацию с объектом выгрузки. Вот и я на днях столкнулся как раз с этим вопросом. После небольшого мозгового штурма воплотил вот такую идею.
исходник:http://kb.mista.ru/article.php?id=811

Метод довольно прост в реализации, хотя придется все таки немного поправить обработку обмена в 1С v.8

1. Для передачи параметра (или параметров, количество передаваемого может быть произвольным)

в обработчике Правила Конвертации Объекта(ПКО) ПриВыгрузке пишем следующее

//передача одного параметра с именем "Клиент" и значением - строковым представлением реквизита объекта Клиент
        УзелПараметра = DOMDocument.createNode(1, "ЗначениеПараметра", "");
        УзелПараметра.setAttribute("ИмяПараметрПКО", "Клиент"); 
        УзелПараметра.setAttribute("ЗначениеПараметрПКО", Строка(Источник.Клиент));
        Приемник.appendChild(УзелПараметра);

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

««ИмяПараметрПКО» и «ЗначениеПараметрПКО» - имена обязательные, потому что по ним потом будет поиск в при загрузке.

«Клиент» и Строка(Источник.Клиент) - величины произвольные.

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

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

Открываем в конфигурации модуль объекта обработки и ищем

Функция ПрочитатьОбъект().

Идем от начала в низ, пропускаем обработчики ПередЗагрузкой и находим вот такой кусок кода

    Пока ФайлОбмена.Прочитать() Цикл
        
        ИмяУзла = ФайлОбмена.ЛокальноеИмя;
                
        Если ИмяУзла = "Свойство"
            ИЛИ ИмяУзла = "ЗначениеПараметра" Тогда
            
            ЭтоПараметрДляОбъекта = (ИмяУзла = "ЗначениеПараметра");

Для начала перед циклом

     Пока ФайлОбмена.Прочитать() Цикл

поставим свою строчку :

     ПараметрыПКО=Новый Соответствие;

Дальше в цикле нас интересует именно переменная ЭтоПараметрДляОбъекта. Поэтому быстренько проверив ее заполняем наше свежерожденное соответствие:

    Если ЭтоПараметрДляОбъекта Тогда
         ИмяПараметраПКО     = одАтрибут(ФайлОбмена, одТипСтрока, "ИмяПараметрПКО");
         ЗначениеПараметраПКО= одАтрибут(ФайлОбмена, одТипСтрока, "ЗначениеПараметрПКО");
         ПараметрыПКО.Вставить(ИмяПараметраПКО, ЗначениеПараметраПКО);
    КонецЕсли;

Вот собственно и все. Соответствие ПараметрыПКО доступно в обработчиках ПриЗагрузке и ПослеЗагрузки. А там - вспоминайте уже сами какими именами вы называли ваши параметры и доставайте их из него. Например :

МойПараметр1=ПараметрыПКО.Получить("МоеИмяПараметра1");
МойПараметр2=ПараметрыПКО.Получить("МоеИмяПараметра2");
МойПараметр3=ПараметрыПКО.Получить("МоеИмяПараметра3");

P.S:

В ПКС есть хитрая галка «Передавать данные в параметр». И казалось бы сам бог велел ее использовать. НО…
ЭТО ТОЛЬКО ДЛЯ ОБМЕНА V8 - V8 И ОБРАБОТКИ ВЫГРУЗКИ И ЗАГРУЗКИ НЕ НИЖЕ 2.0.18.1
Данный функционал позволяет передавать дополнительные параметры в информационную базу приемник из источника.

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

3. Передача глобальных параметров при конвертации 7.7 ==> 8 без правки штатных модулей

Кратко суть проблемы можно озвучить цитатой из документации:
«Передача параметра из источника в приемник доступна только при обмене между информационными базами на платформе 1С:Предприятие 8».

Ниже излагается способ передачи глобальных параметров при таком обмене без правки выгруженного из КД 2 модуля выгрузки и без правки самой КД 2. Итак:

в обработчике ПередВыгрузкойДанных пишем код:

УзелПарам=СоздатьУзел("ЗначениеПараметра");
УстановитьАтрибут(УзелПарам,"Имя","НашПараметр1"); 
УстановитьАтрибут(УзелПарам,"Тип","Строка");
ЗаписатьЭлемент(УзелПарам,"Значение","Значение нашего параметра 1");
ДобавитьПодчиненный(rootNode,УзелПарам);

УзелПарам=СоздатьУзел("ЗначениеПараметра");
УстановитьАтрибут(УзелПарам,"Имя","НашПараметр2"); 
УстановитьАтрибут(УзелПарам,"Тип","Булево");
ЗаписатьЭлемент(УзелПарам,"Значение","true");
ДобавитьПодчиненный(rootNode,УзелПарам);

После этого данные параметры будут абсолютно штатно загружены в стандартной обработке «Универсальный обмен данными в формате XML (2.1.5)».

Ещё хотелось бы заметить, что содержимое обработчика ПослеЗагрузкиПараметров при таком обмене также не выгружается в файл обмена. Исправить данную оплошность можно так же, записав в обработчике ПередВыгрузкойДанных:

АлгПослеЗагрузкиПараметров=
"СтрокаКода1;"+РазделительСтрок+
"СтрокаКода2;"+РазделительСтрок+
"СтрокаКода3;";
ЗаписатьЭлемент(rootNode,"АлгоритмПослеЗагрузкиПараметров",АлгПослеЗагрузкиПараметров);

Нюанс: чтобы иметь параметры на ранних стадиях загрузки (предшествующих загрузке параметров), например, в обработчиках ПередЗагрузкойДанных или ПередОбработкой в ПОД (правилах очистки данных), нужно каким-то образом устанавливать параметры на этапе выполнения ПередЗагрузкойДанных. Как это сделать, не меняя штатный механизм (т.е. без исправления модулей выгрузки/загрузки)? Можно, например, так: дописываем в ПередВыгрузкойДанных следующий код:

ИмяПараметра="НашПараметр1";
ТипПараметра="Строка";
ЗначениеПараметра="Значение нашего параметра 1";

// Устанавливаем значение параметра в обработчике ПередЗагрузкойДанных
УзелПравил=rootNode.getElementsByTagName("ПравилаОбмена").item(0);
УзелПередЗагрузкой=УзелПравил.getElementsByTagName("ПередЗагрузкойДанных").item(0);
КоллУзлов=УзелПередЗагрузкой.childNodes;
Для НомУзла=0 По КоллУзлов.length-1 Цикл
    ТекУзел=КоллУзлов.item(НомУзла);
    Если (ТекУзел.nodeType=3) Тогда
        // текст элемента
        ТекУзел.nodeValue=РазделительСтрок+"Параметры."+ИмяПараметра+"="+?(ТипПараметра="Строка","""","")+
            ЗначениеПараметра+?(ТипПараметра="Строка","""","")+";"+РазделительСтрок+РазделительСтрок+
            ТекУзел.nodeValue;
        Прервать;
    КонецЕсли;
КонецЦикла;