Разберем распространенную проблему в экосистеме 1С:Предприятие, связанную с обменом данными. Представим ситуацию: вы настроили синхронизацию между базами. При ручной выгрузке и загрузке через универсальную обработку обмена XML всё работает прекрасно — документы проводятся «на лету». Однако, стоит запустить этот же обмен в автоматическом режиме через план обмена, как документы в базе-приемнике перестают проводиться, сбрасывают свое состояние проведения (распроводятся) и выстраиваются в бесконечную очередь отложенного проведения.
В этой статье мы подробно проанализируем, почему возникает разница между ручным и автоматическим обменом, разберем причины такого поведения платформы и БСП, а также рассмотрим несколько способов решения этой задачи — от простых административных настроек до изменения кода в правилах конвертации данных.
В современных конфигурациях 1С автоматический обмен (через планы обмена) практически всегда работает на базе БСП (Библиотеки стандартных подсистем). Для оптимизации процесса загрузки БСП использует механизм отложенного проведения документов.
Логика работы системы при загрузке пакета данных выглядит следующим образом:
ОбменДанными.Загрузка = Истина. В этом режиме платформа отключает стандартные проверки и обработчики проведения, чтобы данные записались максимально быстро.Проведен = Истина, БСП принудительно сбрасывает его в локальной базе-приемнике в состояние Проведен = Ложь.ДокументыДляПроведения или ОтложенныеДвиженияДокументов).Это сделано для обеспечения ссылочной целостности и высокой производительности. Если проводить документ сразу в момент загрузки, он может не провестись из-за отсутствия связанных объектов (например, договора контрагента или номенклатуры), которые находятся дальше по тексту XML-файла и еще не успели создаться в базе-приемнике.
При ручной загрузке через обработку «Универсальный обмен данными XML» механизмы БСП часто не задействуются напрямую, поэтому код РежимЗаписи = "Проведение" отрабатывает без перехвата со стороны подсистемы обмена.
Автор форума предложил радикальный обходной путь. В правилах конвертации объектов (ПКО) документа в событии После загрузки устанавливается Отказ = Истина, чтобы отменить стандартную запись БСП, после чего документ записывается и проводится вручную.
Рассмотрим пример кода, реализующий данный подход:
// Событие "После загрузки" в ПКО документа
Если Объект.Проведен Тогда
Если Не ОбъектНайден Тогда
// Иначе типовые механизмы могут вызывать ошибки блокировок
Объект.Проведен = Ложь;
КонецЕсли;
Попытка
Объект.Записать(РежимЗаписиДокумента.Проведение);
Исключение
ЗаписьЖурналаРегистрации("ОбменДанными.ОшибкаПроведения",
УровеньЖурналаРегистрации.Ошибка, , ,
"Документ " + Объект + " не проведен: " + ОписаниеОшибки());
КонецПопытки;
Иначе
Объект.Записать(РежимЗаписиДокумента.ОтменаПроведения);
КонецЕсли;
Важное предупреждение: Хотя этот метод решает локальную задачу проведения «здесь и сейчас», он несет в себе серьезные риски. Во-первых, если документ ссылается на аналитику, которая загружается позже в этом же пакете, ручное проведение упадет с ошибкой. Во-вторых, проведение каждого документа «на лету» внутри транзакции загрузки может вызвать колоссальные блокировки базы данных и сильно замедлить процесс обмена.
Чтобы избежать рисков первого метода и сохранить ссылочную целостность, рекомендуется накапливать ссылки на документы в процессе загрузки и проводить их один раз в самом конце, когда весь файл обмена уже прочитан. Разберем этот алгоритм по шагам.
Шаг 1. В обработчике правил конвертации «Перед загрузкой данных» инициализируем таблицу для накопления документов:
Параметры.Вставить("ТаблицаДокументов", Новый ТаблицаЗначений);
Параметры.ТаблицаДокументов.Колонки.Добавить("Ссылка");
Шаг 2. В обработчике ПКО документа «После загрузки» добавляем ссылку на успешно загруженный проведенный документ в нашу таблицу параметров:
Если Объект.Проведен Тогда
НоваяСтрока = Параметры.ТаблицаДокументов.Добавить();
НоваяСтрока.Ссылка = Объект.Ссылка;
КонецЕсли;
Шаг 3. В обработчике правил конвертации «После загрузки данных», когда все объекты гарантированно созданы в базе-приемнике, запускаем их проведение:
Если Параметры.Свойство("ТаблицаДокументов") И Параметры.ТаблицаДокументов.Количество() > 0 Тогда
Для Каждого Строка Из Параметры.ТаблицаДокументов Цикл
ДокументОбъект = Строка.Ссылка.ПолучитьОбъект();
Если ДокументОбъект <> Неопределено И Не ДокументОбъект.Проведен Тогда
Попытка
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
Исключение
Сообщить("Не удалось провести документ: " + Строка.Ссылка + ". Ошибка: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
КонецЕсли;
Часто проблема «огромной портянки» в очереди проведения возникает из-за того, что в базе-приемнике просто отключено автоматическое выполнение регламентных заданий или зависла процедура отложенных движений.
Выполним следующие шаги для проверки интеграции на уровне БСП:
Если вам требуется принудительно запустить выполнение отложенных операций сразу по завершении обмена, можно использовать вызов программных методов БСП в обработчике после загрузки данных:
обОтложенноеПроведение = Обработки.ОбменДаннымиXML.Создать();
обОтложенноеПроведение.ВыполнитьОтложенныеОперацииСДокументами();
Использование штатных механизмов БСП и отложенного проведения позволяет сохранить стабильность системы, избежать блокировок СУБД и гарантировать, что все документы будут проведены корректно и в правильной последовательности.