При переходе между конфигурациями, например, с УТ 10.3 на УТ 11 (поможет перенос документов из УТ 10.3 в УТ 11), а также при настройке обмена между КА 2.5 и WMS 5, мы часто сталкиваемся с задачей частичной миграции данных. Типичная ситуация: есть документ, содержащий сотни строк номенклатуры, но перенести в новую базу нужно только определенные позиции (например, только товары определенной группы или категории). Казалось бы, задача тривиальная — поставить условие и отказать в выгрузке лишних строк. Однако на практике разработчики сталкиваются с тем, что база-приемник «раздувается» от мусорных данных.
В этой статье мы подробно разберем, почему простой отказ от выгрузки строки не спасает от переноса ссылочных объектов, и как грамотно использовать механизмы «Конвертации данных 2.0» (КД 2) для решения этой задачи. Весь процесс разработки правил, начиная с групповой загрузки метаданных и заканчивая оптимизацией правил регистрации, требует глубокого понимания внутренних механизмов платформы.
Давайте проанализируем стандартный подход, который первым приходит в голову. У нас есть Правило Конвертации Объектов (ПКО) для документа. Внутри него есть папка (группа свойств), соответствующая табличной части, например, Товары. В этой группе настроено Правило Конвертации Свойств (ПКС) для номенклатуры.
Часто мы пытаемся решить задачу фильтрации следующим образом: заходим в обработчик ПередВыгрузкой конкретного ПКС или группы и пишем код вроде:
Если Не НужнаяНоменклатура(ОбъектКоллекции.Номенклатура) Тогда
Отказ = Истина;
КонецЕсли;
Логически это кажется верным: строка в документ-приемник не попадает. Но при анализе выгрузки мы обнаруживаем неприятный сюрприз: сама номенклатура, которая была в этой «отказной» строке, все равно выгрузилась в файл обмена и создалась в базе-приемнике (или обновилась). Если таких строк тысячи, обмен становится неоправданно тяжелым. Разобраться в причинах и найти проблемные места в структуре правил помогает портативный обозреватель правил конвертации.
Почему так происходит?
Механизм КД 2 работает следующим образом:
ПередВыгрузкой конкретной строки.Отказ = Истина, механизм выгрузки по ссылке (рекурсивная выгрузка) уже «захватил» эти объекты в очередь на обработку.Чтобы избежать захвата лишних ссылок, нам нужно перехватить управление до того, как стандартный механизм КД начнет перебирать строки табличной части источника. Для этого в КД 2 существует мощный инструмент — переопределение входящих данных через переменную КоллекцияОбъектов.
Рассмотрим алгоритм действий по шагам.
Нам необходимо работать не с конкретным ПКС (свойством), а с ПГКС (Правилом Конвертации Группы Свойств), которое отвечает за выгрузку всей табличной части. Обычно в дереве правил это выглядит как папка с именем табличной части (например, «Товары»).
В правилах конвертации найдите ПКО вашего документа. Найдите группу свойств, соответствующую табличной части. Откройте обработчик ПередОбработкой этой группы.
В этом обработчике мы должны программно получить данные табличной части, отфильтровать их и подсунуть конвертации уже «чистый» набор данных. В этом случае КД будет итерироваться только по нашей подготовленной коллекции, и ссылки из удаленных строк даже не попадут в поле зрения механизма выгрузки.
Давайте посмотрим на пример кода, который нужно разместить в обработчике ПередОбработкой. Чтобы сделать написание и отладку таких обработчиков удобнее, многие разработчики встраивают в конфигурацию специальный редактор кода для КД 2.
// 1. Выгружаем "сырую" табличную часть источника в Таблицу Значений
ТаблицаТоваров = Источник.Товары.Выгрузить();
// 2. Создаем массив для хранения строк, подлежащих удалению
СтрокиКУдалению = Новый Массив;
// 3. Проходим по таблице и ищем лишние строки
Для Каждого СтрокаТЧ Из ТаблицаТоваров Цикл
// Ваше условие фильтрации. Например, номенклатура не в той папке
Если НЕ СтрокаТЧ.Номенклатура.ПринадлежитЭлементу(Параметры.НужнаяГруппа) Тогда
СтрокиКУдалению.Добавить(СтрокаТЧ);
КонецЕсли;
КонецЦикла;
// 4. Удаляем лишние строки из ТЗ
Для Каждого СтрокаУдаления Из СтрокиКУдалению Цикл
ТаблицаТоваров.Удалить(СтрокаУдаления);
КонецЦикла;
// 5. САМОЕ ГЛАВНОЕ: Подменяем стандартную коллекцию
КоллекцияОбъектов = ТаблицаТоваров;
Важные нюансы этого метода:
КоллекцияОбъектов, КД понимает: «Ага, мне не нужно лезть в Источник.Товары, я буду брать данные из этой переменной».КоллекцияОбъектов уже нет «мусорных» строк, конвертация никогда не обратится к лишней номенклатуре. Следовательно, правило выгрузки по ссылке для них не сработает.В обсуждениях иногда предлагают использовать два разных правила выгрузки для номенклатуры:
Идея состоит в том, чтобы динамически подменять имя правила (ИмяПКО) в зависимости от условия. Однако этот метод имеет существенные недостатки:
Для корректной частичной выгрузки табличных частей документов в 1С:Конвертация данных 2.0:
Отказ = Истина внутри цикла обработки строк (в ПКС) — это не остановит выгрузку зависимых объектов.ПередОбработкой у группы свойств (табличной части).КоллекцияОбъектов.Этот подход гарантирует чистоту данных в приемнике и высокую скорость обмена. Такой подход особенно важен, когда стоит задача создания «легких» правил обмена для высоконагруженных систем.