Перенос данных между конфигурациями 1С часто начинается с простой выгрузки через «Универсальный обмен данными XML». Однако с ростом базы данных выгрузка всего справочника (например, 5000 и более сотрудников) становится неэффективной и долгой. Основная сложность возникает, когда правила конвертации данных (КД 2.1) используют произвольный запрос, а нам нужно настроить автоматический обмен, который будет переносить только изменения. Разберем по шагам, как решить эту задачу, используя механизмы планов обмена и подписок на события.
В типичной ситуации программист создает ПВД (Правила выгрузки данных) в КД 2.1, где данные собираются сложным запросом из нескольких источников: справочника СотрудникиОрганизаций, регистра сведений ФИОФизЛиц, кадровых регистров и т.д. При попытке подключить план обмена возникает дилемма: план обмена регистрирует изменения конкретных объектов (ссылок), а наш запрос «не знает» о регистрации и каждый раз пытается выбрать всё. Кроме того, если сотрудник уволен, он может просто перестать попадать в выборку запроса, и в базе-приемнике информация о нем никогда не обновится.
Рассмотрим самый надежный способ — интеграцию обмена через механизм Планов обмена. Даже если в правилах конвертации (ПКО) источник пустой (данные берутся из выборки запроса), мы можем использовать план обмена для фильтрации этого запроса.
Шаг 1. Создание плана обмена. Создадим новый план обмена (например, ОбменУИТ). В состав плана включим справочник СотрудникиОрганизаций. Важный момент: авторегистрацию лучше выключить, если мы хотим полностью контролировать процесс.
Шаг 2. Регистрация изменений через подписки. Чтобы данные уходили в обмен при любых изменениях (смена фамилии, прием, увольнение), создадим подписку на события ПриЗаписи для справочников СотрудникиОрганизаций, ФизическиеЛица и соответствующих регистров. В обработчике подписки пропишем код регистрации:
Процедура ПриЗаписиОбъектаДляОбмена(Источник, Отказ) Экспорт
// Определяем сотрудника, которого нужно зарегистрировать
СсылкаНаСотрудника = "";
Если ТипЗнч(Источник) = Тип("СправочникОбъект.СотрудникиОрганизаций") Тогда
СсылкаНаСотрудника = Источник.Ссылка;
ИначеЕсли ТипЗнч(Источник) = Тип("СправочникОбъект.ФизическиеЛица") Тогда
// Находим сотрудника по физлицу
// (здесь должен быть ваш запрос для поиска ссылки)
КонецЕсли;
Если ЗначениеЗаполнено(СсылкаНаСотрудника) Тогда
УзелОбмена = ПланыОбмена.ОбменУИТ.НайтиПоКоду("КодВашегоУзла");
ПланыОбмена.ЗарегистрироватьИзменения(УзелОбмена, СсылкаНаСотрудника);
КонецЕсли;
КонецПроцедуры
Шаг 3. Изменение правил в КД 2.1. Теперь в ПВД нам нужно изменить логику формирования ВыборкаДанных. Вместо того чтобы выбирать всех, мы обратимся к таблице изменений плана обмена. Рассмотрим пример кода в обработчике «Перед выгрузкой» в ПВД:
// Получаем массив зарегистрированных ссылок
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Изменения.Ссылка КАК Сотрудник
|ИЗ
| Справочник.СотрудникиОрганизаций.Изменения КАК Изменения
|ГДЕ
| Изменения.Узел = &Узел";
Запрос.УстановитьПараметр("Узел", УзелОбмена);
ТаблицаИзменений = Запрос.Выполнить().Выгрузить();
МассивСсылок = ТаблицаИзменений.ВыгрузитьКолонку("Сотрудник");
// Теперь используем этот массив как параметр в вашем основном запросе
// который собирает ФИО, табельный номер и т.д.
// Результат запроса помещаем в ВыборкаДанных
ВыборкаДанных = ВашОсновнойЗапросСФильтромПоМассиву(МассивСсылок);
Проанализируем ситуацию с уволенными. Если запрос просто исключает уволенных сотрудников (например, фильтром по состоянию), то в базе-приемнике они останутся висеть как работающие. Это критическая ошибка.
Рекомендуемый подход: Изменим запрос в УПП так, чтобы он всегда выдавал список сотрудников, по которым есть изменения в плане обмена, независимо от их статуса. В ПКО добавим свойство ПометкаУдаления или Статус. Если в УПП сотрудник уволен, в приемник передаем Истина для пометки удаления. Таким образом, в базе УИТ справочник Пользователи будет актуализироваться (элементы будут помечаться на удаление, но не удаляться физически).
Если работа с таблицами изменений плана обмена кажется сложной, рассмотрим альтернативный вариант с использованием независимого регистра сведений ОчередьОбмена.
ОчередьОбмена с одним измерением Объект (ЛюбаяСсылка).Этот метод проще в отладке, так как мы всегда видим в консоли запросов, кто именно «стоит в очереди» на выгрузку.
Выясним, как запустить этот процесс без участия человека. Для этого используется штатная обработка УниверсальныйОбменДаннымиXML. Мы можем создать небольшую процедуру в модуле приложения или в специальном общем модуле:
Процедура ВыполнитьОбменНаСервере() Экспорт
Обработка = Обработки.УниверсальныйОбменДаннымиXML.Создать();
Обработка.ИмяФайлаПравил = "C:\Exchange\Rules.xml";
Обработка.ИмяФайлаСообщенияОбмена = "C:\Exchange\Data.xml";
Обработка.РежимОбмена = "Выгрузка";
// Если используем план обмена, указываем узел
Узел = ПланыОбмена.ОбменУИТ.НайтиПоКоду("УИТ");
Обработка.УзелДляВыгрузкиИзменений = Узел;
// Выполняем выгрузку
Обработка.ВыполнитьВыгрузку();
// После выгрузки механизм обмена сам очистит регистрацию
// для этого узла, если все прошло успешно.
КонецПроцедуры
Данную процедуру необходимо вызвать из регламентного задания, настроив расписание (например, раз в сутки в 01:00).
Рассмотрим еще несколько советов для стабильной работы обмена:
Объект.Записать() только в случае, если данные действительно изменились. Это снизит нагрузку на базу-приемник.Посмотрим на результат: вместо ежедневной двухминутной записи 5000 строк, система будет обрабатывать только 5–10 изменившихся объектов за несколько секунд. Это сделает обмен незаметным для пользователей и гарантирует актуальность данных в целевой системе 1С:УИТ.