Часто перед разработчиками встает задача организовать обмен данными между базами 1С (например, из конфигурации 1С:Управление торговлей) с использованием правил Конвертации Данных 2.0 (КД 2). При этом стандартный интерфейс обработки нас не устраивает: мы хотим, чтобы пользователь сам выбирал нужные документы в специальной табличной части на форме, а затем по нажатию кнопки запускалась выгрузка именно этих объектов. Разберем по шагам, как программно инициализировать обработку обмена и передать в нее пользовательский список документов.
Для начала проанализируем ситуацию запуска базовой выгрузки. Нам необходимо программно создать экземпляр обработки УниверсальныйОбменДаннымиXML, передать ей файл с правилами конвертации, указать файл для выгрузки данных и запустить процесс. Рассмотрим подробнее пример кода, который выполняет эту задачу:
// 1. Создаем массив для хранения файлов обмена
МассивФайлов = Новый Массив;
// 2. В цикле обходим правила выгрузки для нашей базы (пример получения правил)
Для Каждого СтрокаПравилВыгрузки Из ИнформационнаяБаза.ПравилаВыгрузкиДанных Цикл
Если СтрокаПравилВыгрузки.Состояние = Перечисления.ОБМ_СостоянияИспользования.НеИспользуется Тогда
Продолжить;
КонецЕсли;
// 3. Получаем двоичные данные правил конвертации (из макета или реквизита)
ПравилоВыгрузки = СтрокаПравилВыгрузки.Правило;
ПравилоКонвертацииДД = ПравилоВыгрузки.ПравилаКонвертации.Получить();
// 4. Сохраняем правила во временный файл на диске
ПутьКПравиламКД = ПолучитьИмяВременногоФайла("xml");
ПравилоКонвертацииДД.Записать(ПутьКПравиламКД);
// 5. Создаем временный файл для выгружаемых данных
ПутьКФайлуДанных = ПолучитьИмяВременногоФайла("xml");
ТекстовыйДокумент = Новый ТекстовыйДокумент;
ТекстовыйДокумент.Записать(ПутьКФайлуДанных);
// 6. Программно создаем обработку обмена
ОбработкаОбмена = Обработки.УниверсальныйОбменДаннымиXML.Создать();
// 6.1 Загружаем правила конвертации из временного файла
ОбработкаОбмена.ЗагрузитьПравилаОбмена(ПутьКПравиламКД, "XMLФайл");
// 6.2 Указываем пути к файлам в реквизитах обработки
ОбработкаОбмена.ИмяФайлаПравилОбмена = ПутьКПравиламКД;
ОбработкаОбмена.ИмяФайлаОбмена = ПутьКФайлуДанных;
// 6.3 Выполняем заполнение параметров выгрузки (если они есть)
Для Каждого СтрокаПараметра Из ОбработкаОбмена.Параметры Цикл
ИмяПараметра = СтрокаПараметра.Ключ;
СтруктураПоиска = Новый Структура("ИмяПараметра", ИмяПараметра);
МассивСтрок = СтрокаПравилВыгрузки.Правило.ПараметрыКонвертации.НайтиСтроки(СтруктураПоиска);
Если МассивСтрок.Количество() > 0 Тогда
ОпределяемыйПараметр = МассивСтрок[0];
Если ЗначениеЗаполнено(ОпределяемыйПараметр.Значение) Тогда
ОбработкаОбмена.Параметры[ИмяПараметра] = ОпределяемыйПараметр.Значение;
Иначе
Рез = Неопределено;
Выполнить(ОпределяемыйПараметр.Алгоритм); // Исполнение произвольного алгоритма
ОбработкаОбмена.Параметры[ИмяПараметра] = Рез;
КонецЕсли;
КонецЕсли;
КонецЦикла;
// 7. Инициализируем значения по умолчанию и запускаем выгрузку
ОбработкаОбмена.ИнициализироватьПервоначальныеЗначенияПараметров();
ОбработкаОбмена.ВыполнитьВыгрузку();
// 8. Читаем результат и добавляем в итоговый массив
ИмяФайла = "Файл_данных.xml";
ДвоичныеДанные = Новый ДвоичныеДанные(ПутьКФайлуДанных);
МассивФайлов.Добавить(Новый Структура("ИмяФайла, ДвоичныеДанные", ИмяФайла, ДвоичныеДанные));
КонецЦикла;
Этот шаблон покрывает базовую потребность в программном запуске. Но выясним причину главного вопроса: как передать табличную часть со списком конкретных документов в эту обработку, чтобы не выгружать все данные подряд? На практике применяется два основных способа решения этой задачи. Посмотрим на пример каждого из них.
Данный подход удобен, если у вас есть доступ к конфигурации «Конвертация данных 2.0» и вы можете изменять сами правила обмена. Для более удобного редактирования алгоритмов и правил подойдёт доработанная конфигурация «Конвертация данных 2.1» с подсказками по обработчикам.
СписокВыгружаемыхДокументов.Перед обработкой напишите алгоритм обхода переданного списка:
Если Параметры.СписокВыгружаемыхДокументов <> Неопределено Тогда
Для Каждого ТекДок Из Параметры.СписокВыгружаемыхДокументов Цикл
// Выгружаем каждый документ, используя стандартный метод КД
ВыгрузитьПоПравилу(ТекДок.Значение);
КонецЦикла;
КонецЕсли;
Теперь вернемся в программный код вашей базы-источника. Перед тем как вызвать метод ВыполнитьВыгрузку(), вам нужно извлечь документы из вашей табличной части и поместить их в СписокЗначений, который затем передать в параметры обработки:
// Формируем список значений из колонки "Документ" вашей табличной части
СписокДок = Новый СписокЗначений;
СписокДок.ЗагрузитьЗначения(ТвояТабличнаяЧасть.ВыгрузитьКолонку("Документ"));
// Передаем сформированный список в параметры обработки обмена
ОбработкаОбмена.Параметры.Вставить("СписокВыгружаемыхДокументов", СписокДок);
// После этого вызываем выполнение обмена
ОбработкаОбмена.ВыполнитьВыгрузку();
Если изменять правила в КД 2 нельзя или нецелесообразно, проанализируем альтернативный путь. Внутри обработки УниверсальныйОбменДаннымиXML формируется дерево правил выгрузки — свойство ТаблицаПравилВыгрузки. К каждому правилу привязан внутренний построитель отчета, отвечающий за отборы. Мы можем обратиться к нему программно и установить отбор по нашему списку.
СписокЗначений.ЗагрузитьПравилаОбмена() обращаемся к таблице правил и находим нужную строку (ПВД).Ссылка.Разберем этот код подробнее:
// 1. Подготавливаем список документов
СписокДок = Новый СписокЗначений;
СписокДок.ЗагрузитьЗначения(ТвояТабличнаяЧасть.ВыгрузитьКолонку("Документ"));
// 2. Загружаем правила (обязательно до настройки отборов)
ОбработкаОбмена.ЗагрузитьПравилаОбмена(ПутьКПравиламКД, "XMLФайл");
// 3. Ищем строку ПВД по имени (например, правило называется "РеализацияТоваровУслуг")
СтрокаПравила = ОбработкаОбмена.ТаблицаПравилВыгрузки.Строки[0].Строки.Найти("ИмяВашегоПВД", "Имя");
Если СтрокаПравила <> Неопределено Тогда
// Включаем флажок использования данного правила
СтрокаПравила.Включить = Истина;
// Добавляем новый элемент отбора по реквизиту "Ссылка"
ЭлементОтбора = СтрокаПравила.НастройкиПостроителя.Отбор.Добавить("Ссылка");
ЭлементОтбора.ВидСравнения = ВидСравнения.ВСписке;
ЭлементОтбора.Значение = СписокДок;
ЭлементОтбора.Использование = Истина;
КонецЕсли;
// В некоторых релизах обработки требуется принудительно обновить настройки
ОбработкаОбмена.ОбновитьНастройкиПостроителяВТаблицеДляВыгрузки();
// 4. Запускаем выгрузку
ОбработкаОбмена.ВыполнитьВыгрузку();
Оба представленных варианта отлично справляются с задачей. Первый способ дает большую гибкость на уровне самих правил конвертации, тогда как второй способ является универсальным и позволяет управлять отборами исключительно из кода базы-источника, не затрагивая конфигурацию Конвертации данных. Выбирайте тот, который лучше подходит под архитектуру вашей интеграции! Если в дальнейшем для баз с готовыми правилами потребуется постоянная синхронизация, можно автоматизировать регулярный обмен данными по расписанию.