Как изменить значение реквизита табличной части при переносе в «1С:Конвертация данных 2.1»

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При разработке правил обмена в программе «1С:Конвертация данных 2.1» программисты часто сталкиваются с необходимостью кастомизации данных непосредственно в процессе выгрузки. Типичная задача — изменить значение определенной колонки в табличной части документа «на лету». Например, вместо выгрузки полноценной ссылки на справочник Номенклатура в табличной части «Запасы» документа выгрузить только строковый код этой номенклатуры или осуществить по нему поиск в базе-приемнике.

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

Понимание контекста: Разница между переменными Источник и ОбъектКоллекции

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

  1. ПКГС (Правила конвертации группы свойств): сопоставляют табличную часть источника с табличной частью приемника целиком (например, табличную часть «Запасы»).
  2. ПКС (Правила конвертации свойств): сопоставляют конкретные реквизиты (колонки) внутри этой табличной части (например, «Номенклатура», «Количество», «Цена»).

Частая ошибка начинающих разработчиков заключается в попытке обратиться к реквизиту строки через переменную Источник внутри обработчика ПКС табличной части. Выясним причину, почему это не работает.

Переменная Источник на любом уровне вложенности ПКС по-прежнему ссылается на весь документ-владелец целиком (объект источника, например, ДокументОбъект.РеализацияТоваровУслуг). Поэтому попытка написать в ПКС колонки «Номенклатура» код Значение = Источник.Код вернет код самого документа-расходной накладной, а не код номенклатуры в текущей строке.

Для обращения к данным конкретной обрабатываемой строки табличной части предназначена специальная предопределенная переменная — ОбъектКоллекции. Она представляет собой структуру или строку таблицы значений текущей обрабатываемой строки источника.

Практическое решение: Изменение реквизита в ПКС

Рассмотрим по шагам, как решить задачу автора темы: передать вместо ссылки на номенклатуру её текстовый код из строки табличной части.

Для этого в правиле конвертации свойств (ПКС) для реквизита «Номенклатура» в табличной части перейдем в обработчик события «Перед выгрузкой» и напишем следующий код:

Значение = ОбъектКоллекции.Номенклатура.Код;

В данном случае переменная ОбъектКоллекции вернет нам текущую строку табличной части «Запасы». От нее мы через точку получаем реквизит Номенклатура, а у номенклатуры — ее текстовое или числовое свойство Код. Полученное значение мы присваиваем предопределенному параметру Значение, который и будет передан в базу-приемник.

Безопасный доступ к реквизитам (Защита от ошибок)

Прямое обращение через точку к реквизитам ссылочных полей (ОбъектКоллекции.Номенклатура.Код) таит в себе серьезную опасность для стабильности обмена. Если в базе-источнике в документе окажется строка с незаполненной номенклатурой или «битой ссылкой» (объект не найден), выгрузка аварийно прервется с ошибкой выполнения кода 1С: «Поле объекта не обнаружено (Код)».

Защитим наш код с помощью проверки на заполненность. Посмотрим на пример безопасного кода, который следует использовать в обработчике «Перед выгрузкой» ПКС:


Если ЗначениеЗаполнено(ОбъектКоллекции.Номенклатура) Тогда
    Значение = ОбъектКоллекции.Номенклатура.Код;
Иначе
    Значение = ""; // Передаем пустое значение, чтобы избежать падения выгрузки
    // Альтернативно, если строку без номенклатуры выгружать нельзя:
    // Отказ = Истина; 
КонецЕсли;

Использование переменной Отказ = Истина в обработчике ПКС позволяет пропустить выгрузку конкретного свойства для текущей строки, не прерывая процесс переноса всего документа.

Настройка поиска в ПКО по передаваемому коду

Если приемником для передаваемого значения в ТЧ является ссылочный тип данных (справочник Ссылка: Номенклатура), а не простая строка, то одной передачи кода недостаточно. База-приемник должна понять, как по полученной строке кода найти или создать соответствующий элемент справочника.

Выполним настройку сопоставления по шагам:

  1. Убедимся, что для ПКС «Номенклатура» в табличной части указано соответствующее ПКО (Правило конвертации объекта) для справочника «Номенклатура».
  2. Перейдем в ПКО «Номенклатура».
  3. В списке ПКС этого правила найдем реквизит Код и установим для него флаг «Поиск». Это укажет системе, что поле «Код» является ключевым при идентификации объекта.
  4. Важный нюанс: В самом ПКО «Номенклатура» перейдем на вкладку «Настройки» и снимем флаг «Искать объект по идентификатору (GUID)». Если этого не сделать, система сначала попытается найти объект по УИД (которого у передаваемой строки кода нет) и только потом перейдет к поиску по коду, что в некоторых сценариях может приводить к дублированию элементов.

Альтернативный вариант: Программное формирование ТЧ через КоллекцияОбъектов

Что делать, если вам нужно не просто изменить значение одной колонки, а полностью преобразовать табличную часть в процессе выгрузки? Например, отфильтровать строки (исключить услуги, оставив только товары), пересчитать цены или объединить дублирующиеся позиции. В таких сценариях использовать отдельные ПКС для каждой колонки неудобно.

Для комплексного управления табличной частью мы можем использовать обработчик «Перед обработкой» в правиле конвертации группы свойств (ПКГС) для всей табличной части целиком. В этом обработчике мы можем переопределить параметр КоллекцияОбъектов, передав туда программно созданную или измененную таблицу значений.

Проанализируем пример реализации такой логики:


// Выгружаем исходную табличную часть "Запасы" в Таблицу Значений
ТаблицаЗапасов = Источник.Запасы.Выгрузить();

// Создадим массив для строк, которые подлежат удалению
СтрокиДляУдаления = Новый Массив;

Для Каждого СтрокаТЧ Из ТаблицаЗапасов Цикл
    // Исключаем из переноса услуги (оставляем только товарные позиции)
    Если СтрокаТЧ.Номенклатура.Услуга = Истина Тогда
        СтрокиДляУдаления.Добавить(СтрокаТЧ);
    КонецЕсли;
КонецЦикла;

// Удаляем помеченные строки из таблицы
Для Каждого СтрокаДляУдаления Из СтрокиДляУдаления Цикл
    ТаблицаЗапасов.Удалить(СтрокаДляУдаления);
КонецЦикла;

// Передаем модифицированную таблицу значений в коллекцию для выгрузки
КоллекцияОбъектов = ТаблицаЗапасов;

Чтобы этот механизм отработал корректно, в свойствах правила ПКГС на вкладке «Параметры» обязательно должен быть установлен флаг «Получить из входящих данных». Система автоматически обойдет переданную вами в КоллекцияОбъектов таблицу значений строка за строкой, применяя к ней правила конвертации свойств.

Передача контекста строки через ИсходящиеДанные

Рассмотрим еще один сложный сценарий. Иногда при конвертации строки табличной части требуется передать специфические параметры из этой строки в ПКО подчиненного объекта. Например, при создании новой номенклатуры в базе-приемнике нам нужно установить для нее базовую единицу измерения или ставку НДС, которая указана в текущей строке документа-источника.

Для решения этой задачи в ПКС «Номенклатура» в обработчике «Перед выгрузкой» мы можем объявить структуру ИсходящиеДанные:


ИсходящиеДанные = Новый Структура;
ИсходящиеДанные.Вставить("СтавкаНДСИзДокумента", ОбъектКоллекции.СтавкаНДС);
ИсходящиеДанные.Вставить("СкладВыгрузки", Источник.Склад); // Передаем реквизит шапки документа

После этого на стороне базы-приемника в обработчиках ПКО справочника «Номенклатура» (например, в событии «Перед выгрузкой» или «При загрузке») переданные параметры будут доступны разработчику через предопределенную переменную ВходящиеДанные:


// Пример использования в приемнике в ПКО Номенклатуры
Если ВходящиеДанные <> Неопределено Тогда
    СтавкаНДС = ВходящиеДанные.СтавкаНДСИзДокумента;
КонецЕсли;

Использование связки переменных ОбъектКоллекции, КоллекцияОбъектов и ИсходящиеДанные открывает перед разработчиком неограниченные возможности по трансформации данных табличных частей любой сложности, делая обмен гибким и устойчивым к ошибкам.

← На главную