Пример . Необходимо настроить обмен данными между справочниками по сопоставлению артикулов. Соответствие артикулов хранится в регистре сведений базы Приемника. Подразумевается, что в базе приемнике и базе источнике, есть идентичная номенклатура, у которой отличается артикул и наименование.
Решение . В базе приемнике есть номенклатура с отличающимся наименованием и артикулом, но по факту это такой же объект как и в источнике. Соответствие артикулов заполнено в регистре сведений Соответствие Номенклатуры.
Создадим Правило конвертации объекта (ПКО) для справочника Номенклатура, проверим создались ли нужные для нас Правила конвертации свойств (ПКС) и добавим Правило выгрузки данных. Так как нам не надо замещать наименование, то в ПКС Наименование установим флаг Не замещать значение свойств у существующих объектов. А в настройках ПКО Номенклатура снимем флаг Искать объект приемника по внутреннему идентификатору. Из-за того, что у нас сопоставление осуществляется по артикулу, а в приемнике и источнике код может совпадать, то для сохранения уникальности кода установим флаг Автоматически генерировать номер или код, если он не задан (У ПКС Код поставим флаг Отключить обработку правила). В дальнейшем в обработчике Поля Поиска в ПКО Номенклатура для поиска по регистру нам понадобится артикул, поэтому добавим его в поиск. Так как справочники иерархические необходимо проверить наличие поиска по свойству ЭтоГруппа и Наименование.
Так как сопоставление осуществляется по артикулу, то исключим из выгрузки объекты у которых он отсутствует, при это выведем информационное сообщение. Для чего в ПКО Номенклатура в обработчике событий Перед выгрузкой запишем код:
Если Не Источник.ЭтоГруппа Тогда
Если Не ЗначениеЗаполнено(Источник.Артикул) Тогда
Сообщить("Для элемента: "+Источник.Наименование+" Код "+Источник.Код+" не заполнен артикул!!! Выгрузка не выполнена!!!Заполните артикул и повторите выгрузку!!!");
Отказ = Истина;
КонецЕсли;
КонецЕсли;
Теперь нам нужно найти объект (точнее ссылку) по соответствию артикулов в базе приемнике. Это мы сделаем в том же ПКО в обработчике событий Поля поиска, запишем код:
Если Не СвойстваПоиска["ЭтоГруппа"] Тогда
Если ЗначениеЗаполнено(СвойстваПоиска["Артикул"]) Тогда
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка
|ИЗ
| РегистрСведений.СоответствиеНоменклатуры КАК СоответствиеНоменклатуры
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура
| ПО СоответствиеНоменклатуры.АртикулПриемник = Номенклатура.Артикул
|ГДЕ
| СоответствиеНоменклатуры.АртикулИсточник = &АртикулИсточник";
Запрос.УстановитьПараметр("АртикулИсточник", СвойстваПоиска["Артикул"]);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Если ВыборкаДетальныеЗаписи.Следующий() Тогда
СсылкаНаОбъект=ВыборкаДетальныеЗаписи.Ссылка;
Иначе ПрекратитьПоиск = Истина;
КонецЕсли;
КонецЕсли;
Иначе СтрокаИменСвойствПоиска = "ЭтоГруппа, Наименование";
КонецЕсли;
Получается если в регистре сведений есть измерение для сопоставления (АртикулИсточник), а в Приемнике объект, артикул которого соответствует ресурсу данного измерения (АртикулПриемник), то ссылка на объект подставляется в результат поиска. А если соответствия не найдено, то создается новый объект.
Предусмотрим случай если мы передаем объект с артикулом соответствие на который не установлено в регистре сведений. Так как артикула нет в регистре, то каждый раз при передаче будет создаваться новый объект. Чтобы этого избежать необходимо программно создать запись в регистре сведений. Кроме того, чтобы исключить ситуацию, когда запись в регистре появилась, а объект в справочнике не записался (в силу разных причин) создадим транзакцию, внутри которой и поместим эти две записи. Запишем код:
Если Объект.ЭтоНовый() И ЗначениеЗаполнено(Объект.Артикул) Тогда
//Для исключения возможности записи в Регистр без записи объекта, создадим транзакцию.
//А внутри нее запишем и объект и набор записей регистра.
НачатьТранзакцию();
НаборЗаписей = РегистрыСведений.СоответствиеНоменклатуры.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.АртикулИсточник.Установить(Объект.Артикул);
Запись = НаборЗаписей.Добавить();
Запись.АртикулИсточник = Объект.Артикул;
//Проверим уникальность артикула
Если ЗначениеЗаполнено(Справочники.Номенклатура.НайтиПоРеквизиту("Артикул",Объект.Артикул)) Тогда
Сообщить("Артикул объекта: "+ Объект.Наименование+ " не уникален!!!Артикул не перенесен.Задайте новое значение артикула и заполните соответствие номенклатуры!!!");
Объект.Артикул = "";
КонецЕсли;
Запись.АртикулПриемник = Объект.Артикул;
Объект.Записать();
НаборЗаписей.Записать();
ЗафиксироватьТранзакцию();
//Отменим повторную запись объекта
ОбъектМодифицирован = Ложь;
КонецЕсли;
Сохраним изменения и сделаем обмен.
В соответствии с настройками:
- Номенклатура у которой не указан артикул не передалась.
- При при передаче артикула дублирующегося в Базе Приемнике – артикул не создался.