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