Почему в РИБ при пометке документа на удаление в центральной базе в периферийных узлах не удаляются движения?

Программист 1С v8.3 (Управляемые формы) Управленческий учет Торговля и дистрибуция
← На главную

В распределенных информационных базах (РИБ) часто возникает ситуация, когда стандартные механизмы платформы ведут себя не так, как ожидается, особенно в самописных конфигурациях. Типичная проблема: бухгалтер в центральном узле помечает документ на удаление, в центре движения по регистрам исчезают, но после синхронизации в периферийном узле документ помечается на удаление, а его "хвосты" в виде записей в регистрах накопления или сведений остаются. Проанализируем ситуацию, выясним причины и разберем по шагам, как это исправить.

Разберем основную причину: Режим загрузки данных

При обмене данными через РИБ платформа 1С использует специализированный режим записи объектов. Проанализируем свойство ОбменДанными.Загрузка. Когда данные приходят из другого узла, этому свойству устанавливается значение Истина. Это делается для того, чтобы:

  1. Избежать бесконечного зацикливания обмена (чтобы измененный объект не регистрировался к отправке обратно).
  2. Игнорировать прикладные проверки в процедурах ПередЗаписью и ПриЗаписи, которые могут помешать загрузке (например, контроль остатков).
  3. Ускорить процесс записи.

Важный момент: в режиме загрузки стандартный механизм очистки движений при пометке удаления может не срабатывать, если он завязан на логику, которая обходится этим флагом. Если ваш документ в узле просто записывается с новым признаком ПометкаУдаления, но при этом не происходит вызов процедуры отмены проведения, движения останутся в базе "навсегда".

Проанализируем состав плана обмена

Выясним причину, по которой движения регистра могут игнорироваться. Если документ включен в состав плана обмена, а регистр (например, ОстаткиТоваров) — нет, то платформа при обмене передает только состояние самого документа. В штатном режиме РИБ это означает, что записи регистра в периферийном узле живут своей жизнью.

Рассмотрим ситуацию подробнее: когда в центре документ помечается на удаление, платформа удаляет его движения. Но так как регистр не в плане обмена, информация об удалении этих строк не попадает в пакет обмена. В узел приходит только измененный "заголовок" документа с пометкой на удаление. Если в коде конфигурации нет явной команды на очистку движений при получении такого документа, движения останутся актуальными, хотя документ уже будет помечен как недействительный.

Где искать код, отвечающий за обмен?

Если конфигурация не типовая, обмен может быть реализован через подписки на события или специализированные модули. Проанализируем, где может прятаться логика перепроведения или записи документа при обмене:

  1. Подписки на события: Ищите подписки на события ПриЗаписи или ПередЗаписью для вашего документа. Обратите внимание на те, где в обработчике проверяется Источник.ОбменДанными.Загрузка.
  2. Модуль объекта документа: Проверьте процедуры ПередЗаписью и ПриЗаписи. Возможно, там стоит условие Если ОбменДанными.Загрузка Тогда Возврат; КонецЕсли;, которое блокирует очистку движений.
  3. План обмена: В модуле плана обмена могут быть переопределены процедуры обработки получения данных.

Как программно исправить очистку движений при загрузке

Если мы обнаружили, что документ при загрузке помечается на удаление, но сохраняет движения, нам необходимо вмешаться в процесс записи. Рассмотрим пример кода, который можно разместить в подписке на событие ПриЗаписи документа.

Посмотрим на пример реализации очистки движений:


Процедура ПриЗаписиДокументаДляОбмена(Источник, Отказ) Экспорт
    
    // Нас интересует только режим загрузки из другого узла
    Если Не Источник.ОбменДанными.Загрузка Тогда
        Возврат;
    КонецЕсли;
    
    // Проверяем, что документ помечен на удаление
    Если Источник.ПометкаУдаления Тогда
        
        // Нам нужно вручную очистить движения по конкретному регистру
        // Создаем набор записей регистра, по которому "зависли" движения
        НаборЗаписей = РегистрыНакопления.ОстаткиТоваров.СоздатьНаборЗаписей();
        НаборЗаписей.Отбор.Регистратор.Установить(Источник.Ссылка);
        
        // Читаем текущие движения (если они есть)
        НаборЗаписей.Прочитать();
        
        // Если движения существуют, очищаем их
        Если НаборЗаписей.Количество() > 0 Тогда
            НаборЗаписей.Очистить();
            НаборЗаписей.Записать();
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

Этот код принудительно очищает записи в регистре ОстаткиТоваров, если документ загружается с пометкой на удаление. Обратите внимание, что мы используем НаборЗаписей, так как это самый быстрый и надежный способ работы с движениями документа.

Проанализируем свойство «Удаление движений» в метаданных

Выясним, как настроены свойства самого документа в конфигураторе. Откройте свойства документа Переоценка и перейдите на закладку "Движения". Рассмотрим поле "Удаление движений". Там может быть три варианта:

В случае с РИБ, если документ приходит сразу помеченным на удаление, он может миновать стадию "отмены проведения", и тогда автоматика не сработает. Проанализируем ситуацию: если в коде обмена используется метод Источник.Записать(РежимЗаписиДокумента.Запись) вместо Источник.УстановитьПометкуУдаления(Истина), то классические триггеры удаления движений могут не активироваться.

Рекомендации по поиску места в коде

Если вы не знаете, где именно происходит магия обмена, воспользуйтесь глобальным поиском (Ctrl+Shift+F). Проанализируем ключевые фразы, которые помогут найти "виновника":

Важное предостережение: Будьте осторожны при программной очистке движений. Если в вашей системе настроен сложный обмен, при котором движения должны приходить отдельными объектами (хотя в данном случае это не так, раз регистра нет в плане обмена), вы можете спровоцировать расхождение данных. Но в вашей ситуации, когда регистр не является частью РИБ, ручная очистка в момент пометки удаления документа — это единственный верный путь сохранить целостность остатков в узлах.

Итоги

Мы проанализировали проблему "зависших" движений в РИБ и выяснили, что она кроется в сочетании режима загрузки данных и отсутствия регистра в составе плана обмена. Разберем краткий алгоритм действий для исправления:

  1. Убеждаемся, что регистр ОстаткиТоваров действительно не должен быть в плане обмена.
  2. Находим подписку на событие ПриЗаписи для документа Переоценка.
  3. Внедряем проверку на ОбменДанными.Загрузка и ПометкаУдаления.
  4. Программно очищаем НаборЗаписей регистра с отбором по регистратору.

Следование этим шагам позволит вам синхронизировать состояние базы в центре и в узлах, исключив ошибки в отчетах по остаткам товаров.

← На главную