При настройке правил обмена в конфигурации «1С:Конвертация данных 2.1» (КД 2.1) регулярно возникает задача передачи данных в приемник, структура которого отличается от источника. Распространенный сценарий — выгрузка реквизита ссылочного типа (например, СправочникСсылка.Контрагенты) из документа или справочника источника в реквизит с типом Строка в приемнике, в котором соответствующий справочник отсутствует вовсе.
Рассмотрим, почему при обращении к свойствам реквизита в ПКС возникают ошибки вроде «Поле объекта не обнаружено», разберем контекст исполнения кода в обработчиках и проанализируем проверенные способы конвертации ссылок в строковое представление.
Частая ошибка разработчиков заключается в путанице между переменными контекста в обработчике Перед выгрузкой Правила конвертации свойств (ПКС):
Источник в ПКС указывает не на само конвертируемое свойство, а на родительский объект (например, документ ДокументСсылка.РеализацияТоваровУслуг), которому принадлежит данное свойство. Если попытаться обратиться к Источник.Наименование, платформа выдаст ошибку, так как у документа нет реквизита Наименование.Значение в ПКС уже содержит значение выгружаемого реквизита (если в настройках ПКС указано поле «Источник»).Поэтому попытка написать код вида Значение = Справочники.Контрагенты.Наименование или обращение к несвойственным объекту-источнику реквизитам вызывает отказ выполнения выгрузки.
ЗначениеПосмотрим на наиболее простой и эффективный вариант. Если в настройках ПКС заполнено поле «Источник» (указан реквизит шапки Контрагент), то при входе в обработчик Перед выгрузкой в переменной Значение уже находится выгружаемая ссылка. Нам достаточно привести её к строке:
Значение = Строка(Значение);
Функция Строка() возвращает наименование справочника или представление любого другого ссылочного объекта 1С.
Проанализируем ситуацию, когда необходимо явно обратиться к объекту-источнику (переменная Источник) и взять конкретный реквизит шапки (например, Контрагент):
Если ЗначениеЗаполнено(Источник.Контрагент) Тогда
Значение = Строка(Источник.Контрагент);
Иначе
Значение = "";
КонецЕсли;
Или в виде краткого выражения:
Значение = ?(ЗначениеЗаполнено(Источник.Контрагент), Строка(Источник.Контрагент), "");
В этом примере Источник — это выгружаемый документ, а Источник.Контрагент — реквизит этого документа, содержащий ссылку на справочник.
Если в строковое поле приемника требуется записать не текстовое представление (наименование), а уникальный идентификатор ссылки для последующего поиска или связывания программным путем, используем функцию XMLСтрока():
Если ЗначениеЗаполнено(Источник.Контрагент) Тогда
Значение = XMLСтрока(Источник.Контрагент);
Иначе
Значение = "";
КонецЕсли;
Разберем случай, когда выгружаемый ссылочный реквизит находится не в шапке документа или справочника, а в строке табличной части. В обработчиках ПКС табличных частей переменная Источник по-прежнему указывает на сам документ, а текущая строка табличной части доступна через переменную ОбъектКоллекции.
Код в ПКС для реквизита табличной части будет выглядеть следующим образом:
Значение = ?(ЗначениеЗаполнено(ОбъектКоллекции.Номенклатура), Строка(ОбъектКоллекции.Номенклатура), "");
Рассмотрим защиту от ошибок при наличии в базе «битых» ссылок (указателей на удаленные объекты). Функция ЗначениеЗаполнено() для битой ссылки вернет Истина, но обращение к ее свойствам может вызвать сбой. Чтобы гарантировать корректность выгрузки, выполним проверку существования объекта в базе:
СсылкаНаОбъект = Источник.Контрагент;
Если ЗначениеЗаполнено(СсылкаНаОбъект) И СсылкаНаОбъект.ПолучитьОбъект() <> Неопределено Тогда
Значение = Строка(СсылкаНаОбъект);
Иначе
Значение = "";
КонецЕсли;
Строка.ПараметрыОбъекта.