КД 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; Прервать; КонецЕсли; КонецЦикла;