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