При работе с инструментом «1С:Конвертация данных 2.1» часто возникает задача частичного переноса данных. Например, когда из одной информационной базы в другую нужно передать не весь огромный справочник Номенклатура, а только конкретную ветку (папку) со всеми её вложенными элементами. В рамках данной статьи мы подробно разберем, как реализовать такую выгрузку несколькими способами: от простых настроек в интерфейсе до написания эффективного программного кода в обработчиках правил.
Рассмотрим самый простой способ, который не требует изменения самих правил конвертации в конфигураторе КД. Этот метод идеально подходит для разовых выгрузок или когда состав выгружаемых групп часто меняется.
Проанализируем шаги, которые необходимо выполнить в базе-источнике:
xml).Номенклатура).Ссылка, установим вид сравнения «В иерархии» и выберем нужную группу.Важный нюанс: если при выборе группы система выдает ошибку «Выберите элемент, а не группу!», это означает, что в обработке программно установлено ограничение. Как правило, использование стандартной обработки, встроенной в современные конфигурации (например, БП 3.0 или ЕРП), решает эту проблему — там выбор групп работает корректно.
Выясним, как сделать выгрузку управляемой с помощью параметров. Этот метод удобен, когда мы хотим дать пользователю возможность выбрать группу прямо в интерфейсе выгрузки, но логика фильтрации должна быть жестко прописана в правилах.
Для начала создадим параметр в конфигурации «Конвертация данных»:
ГруппаДляВыгрузки.Теперь проанализируем код, который необходимо разместить в ПКО (Правила конвертации объектов) для нужного справочника. В обработчике ПередВыгрузкой пропишем следующий алгоритм:
Если ЗначениеЗаполнено(Параметры.ГруппаДляВыгрузки) Тогда
// Проверяем, принадлежит ли текущий объект выбранной группе (включая иерархию)
Если НЕ Источник.ПринадлежитЭлементу(Параметры.ГруппаДляВыгрузки) Тогда
Отказ = Истина;
КонецЕсли;
КонецЕсли;
Метод ПринадлежитЭлементу() является крайне эффективным, так как он проверяет вхождение объекта во всю иерархию папок, независимо от уровня вложенности. Однако помните, что при таком подходе система все равно будет перебирать все объекты справочника в базе, что может быть медленно на больших объемах данных.
Рассмотрим наиболее профессиональный и быстрый способ — использование ПВД (Правила выгрузки данных) с типом выборки «Произвольный алгоритм». Вместо того чтобы перебирать каждый объект и проверять его в ПКО, мы сразу получим из базы только нужные данные с помощью запроса.
Разберем реализацию по шагам в обработчике ПВД ПередВыгрузкой:
// Проверяем наличие установленного параметра
Если ЗначениеЗаполнено(Параметры.ГруппаДляВыгрузки) Тогда
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| Номенклатура.Ссылка В ИЕРАРХИИ(&ВыбраннаяГруппа)";
Запрос.УстановитьПараметр("ВыбраннаяГруппа", Параметры.ГруппаДляВыгрузки);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Выгружаем объект по конкретному правилу конвертации
ВыгрузитьПоПравилу(ВыборкаДетальныеЗаписи.Ссылка, , , , "Номенклатура");
КонецЦикла;
// Обязательно устанавливаем Отказ, чтобы стандартная выборка не запустилась
Отказ = Истина;
КонецЕсли;
Преимущества этого метода: использование оператора В ИЕРАРХИИ в запросе на уровне СУБД работает в десятки раз быстрее, чем программный перебор в ПКО. Это критически важно, если в справочнике десятки или сотни тысяч записей.
Проанализируем ситуацию, с которой столкнулись пользователи на форуме: попытка фильтрации по коду родителя. В сообщении 4 предлагался код Если НЕ Источник.Родитель.Код = "Баланс" тогда Отказ = Истина;. Рассмотрим, почему это решение может не сработать:
Родитель обращается только к непосредственному родителю объекта. Если элемент находится внутри подпапки, которая, в свою очередь, лежит в папке "Баланс", это условие не сработает. Именно поэтому следует использовать метод ПринадлежитЭлементу().Источник.Родитель.Код может вернуть Ложь (так как у самой верхней группы родитель пустой), и группа не выгрузится. В итоге элементы в приемнике останутся без родителя и попадут в корень справочника.СправочникСсылка.При частичной выгрузке данных важно обеспечить корректное создание структуры папок в базе-приемнике. Если вы выгружаете только содержимое Группы А, но не выгружаете её родителя (Корневую Группу), убедитесь, что в правилах поиска объектов (ПКО) настроен поиск по наименованию или коду. В противном случае, если GUID групп в базах не совпадают, система может создать дубли папок или некорректно подчинить элементы.
Если ваша задача — перенести элементы, но "сплющить" иерархию (то есть не создавать папки в приемнике), в ПКО в обработчике ПередВыгрузкой следует принудительно очищать родителя:
// Пример: перенос элементов в корень без сохранения папок
Если НЕ Источник.ЭтоГруппа Тогда
Значение = Справочники.Номенклатура.ПустаяСсылка();
КонецЕсли;
Подводя итог, отметим: для разовых задач используйте фильтры в стандартной обработке XML. Для автоматизированных обменов лучше всего подходит произвольный алгоритм в ПВД с использованием запроса и оператора В ИЕРАРХИИ, так как это гарантирует максимальную производительность системы.