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