При настройке обмена данными между конфигурациями 1С с помощью инструмента «Конвертация данных 2.0» (КД 2.0) разработчики часто сталкиваются с необходимостью выгружать не все документы определенного типа, а только те, которые соответствуют конкретному критерию. Типичный пример — документ ПередачаТоваров (Передача товаров), который в зависимости от вида операции может отражать как передачу сырья в переработку, так и передачу готовой продукции заказчику. Если нам нужно перенести только один конкретный вид операции, стандартная выгрузка «в лоб» перенесет абсолютно все документы.
В этой статье мы подробно разберем, как правильно реализовать такой отбор, проанализируем типичные ошибки начинающих разработчиков и рассмотрим четыре эффективных способа решения задачи: от простых интерактивных настроек до оптимизированных запросов в правилах выгрузки.
Прежде чем перейти к правильным методикам, давайте разберем типичные ошибки, которые часто совершают разработчики на форумах (в частности, в сообщениях 11 и 13).
Ошибка №1: Написание запроса внутри ПКС (Правила конвертации свойства) для номера
Попытка переопределить выгрузку всего документа, написав запрос внутри ПКС для реквизита Номер — это грубейшая архитектурная ошибка. ПКС отвечает исключительно за заполнение конкретного реквизита (свойства) объекта в базе-приемнике. Попытка поместить туда тяжелый запрос с фильтрацией по виду операции приводит к ошибкам сопоставления типов, нарушению структуры XML-файла и полной неработоспособности выгрузки. Свойства объекта должны конвертироваться только тогда, когда сам объект уже прошел фильтрацию и допущен к выгрузке.
Ошибка №2: Неоптимальное использование «Отказ = Истина» в ПКО (Правила конвертации объектов)
Решение написать в обработчике «Перед выгрузкой» ПКО условие вида:
Если Источник.ВидОперации <> Перечисления.ВидыОперацийПередачаТоваров.ИзПереработки Тогда
Отказ = Истина;
КонецЕсли;
хоть и является рабочим, имеет два огромных недостатка:
---
Для того чтобы не читать лишние объекты из базы данных, правильнее всего применить фильтрацию на самом первом этапе — в ПВД (Правила выгрузки данных). Мы выберем запросом только нужные нам документы и передадим их платформе для последующей конвертации.
Разберем по шагам, как это настроить:
ПередачаТоваров.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПередачаТоваров.Ссылка КАК Ссылка
|ИЗ
| Документ.ПередачаТоваров КАК ПередачаТоваров
|ГДЕ
| ПередачаТоваров.ВидОперации = &ВидОперации";
Запрос.УстановитьПараметр("ВидОперации", Перечисления.ВидыОперацийПередачаТоваров.ИзПереработки);
// Результат запроса передаем в предопределенную переменную ВыборкаДанных
ВыборкаДанных = Запрос.Выполнить().Выбрать();
Важный нюанс: При использовании предопределенной переменной ВыборкаДанных в ПВД, в соответствующем ПКО на вкладке «Настройки» рекомендуется установить флаг «Не запоминать выгруженные объекты» (либо вручную определять КлючВыгружаемыхДанных в ПКО), чтобы избежать избыточного кэширования в памяти.
Если вы хотите полностью контролировать процесс выгрузки вручную без автоматического обхода выборки, в том же обработчике «Перед обработкой» ПВД можно использовать явный вызов метода ВыгрузитьПоПравилу:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПередачаТоваров.Ссылка КАК Ссылка
|ИЗ
| Документ.ПередачаТоваров КАК ПередачаТоваров
|ГДЕ
| ПередачаТоваров.ВидОперации = &ВидОперации";
Запрос.УстановитьПараметр("ВидОперации", Перечисления.ВидыОперацийПередачаТоваров.ИзПереработки);
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
// Выгружаем каждый документ по конкретному правилу конвертации объектов
ВыгрузитьПоПравилу(Выборка.Ссылка, , , , "ПередачаТоваров");
КонецЦикла;
// Устанавливаем Отказ = Истина, чтобы стандартный механизм выборки ПВД не запускался
Отказ = Истина;
---
Если документов в базе относительно немного (например, несколько сотен или тысяч) и производительность не является критическим фактором, мы можем обойтись без написания сложных запросов. Мы выполним фильтрацию прямо в ПВД, но в событии «Перед выгрузкой». Это убережет базу от проблем с «битыми» ссылками при выгрузке по ссылкам из других объектов.
В ПВД для нашего документа в событии «Перед выгрузкой» напишем простой код:
Если Объект.ВидОперации <> Перечисления.ВидыОперацийПередачаТоваров.ИзПереработки Тогда
Отказ = Истина;
КонецЕсли;
Обратите внимание: В контексте обработчиков ПВД проверяемый элемент доступен через предопределенную переменную Объект, в то время как в обработчиках ПКО используется переменная Источник. Не путайте их при написании кода!
---
Если вам требуется быстро настроить обмен и вы не хотите вносить изменения в код правил обмена (или правила закрыты для редактирования), можно воспользоваться стандартными возможностями выгрузки. При использовании стандартной обработки «Универсальный обмен данными в формате XML» (V8Exchan82.epf) вы можете наложить фильтр интерактивно:
Передача товаров.При старте выгрузки платформа самостоятельно сформирует оптимальный SQL-запрос к СУБД с учетом указанного отбора. Это самый простой способ, не требующий навыков программирования.
---
Жесткое прописывание конкретного вида операции в коде правил (как в Способах 1 и 2) считается плохой практикой разработки. Если завтра требования бизнеса изменятся и нужно будет выгружать другой вид операции, вам придется заново открывать «Конвертацию данных», менять код правил, сохранять их и обновлять на узлах обмена.
Правильнее сделать этот отбор динамическим с помощью параметров конвертации:
ОтборВидОперации.
Если ЗначениеЗаполнено(Параметры.ОтборВидОперации)
И Объект.ВидОперации <> Параметры.ОтборВидОперации Тогда
Отказ = Истина;
КонецЕсли;
Теперь при запуске выгрузки в режиме «1С:Предприятие» на вкладке «Параметры выгрузки» пользователь сможет самостоятельно выбрать нужный вид операции из списка. Если параметр оставить пустым, правила выгрузят все документы без ограничений.
---
Мы проанализировали четыре различных подхода к фильтрации данных при обмене. Подведем итоги совместной работы: