Почему не работает НеЗамещатьОбъект при синхронизации данных 1С и как это исправить

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

При настройке обмена данными между конфигурациями 1С часто возникает задача: запретить изменение документов, которые уже были перенесены и проведены в базе-приемнике. Стандартный механизм для этого в программном коде правил обмена (созданных в «Конвертации данных 2.0») — использование переменной НеЗамещатьОбъект в обработчике события ПриЗагрузке. Однако разработчики часто сталкиваются с ситуацией, когда этот код идеально работает в обработке «Универсальный обмен данными в формате XML», но полностью игнорируется при запуске той же выгрузки через типовую «Синхронизацию данных».

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

Суть проблемы и используемый программный код

Типичный сценарий настройки выглядит следующим образом. В конфигурации «Конвертация данных» для конкретного правила конвертации объекта (ПКО) в событии ПриЗагрузке прописывается логика:


// Если объект найден в базе-приемнике и он уже проведен, 
// устанавливаем флаг запрета замещения данных
НеЗамещатьОбъект = ОбъектНайден И Объект.Ссылка.Проведен;

Разберем, что здесь происходит. Переменная ОбъектНайден — это флаг, который платформа устанавливает в значение Истина, если по полям поиска (например, по Уникальному Идентификатору или набору реквизитов) объект в базе-приемнике был успешно обнаружен. Свойство Объект.Ссылка.Проведен позволяет нам проверить статус этого документа непосредственно в базе-приемнике. Если оба условия выполняются, мы присваиваем НеЗамещатьОбъект = Истина.

Ожидаемое поведение: платформа прочитает данные из файла обмена, увидит этот флаг и пропустит этап записи объекта, сохранив его текущее состояние в приемнике нетронутым. Но при использовании синхронизации этого не происходит, и проведенные документы в приемнике перезаписываются («слетает» ручная правка, меняются суммы и т.д.).

Разбор причины: Архитектура синхронизации в современных конфигурациях

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

В современных конфигурациях, использующих механизмы БСП, логика разделена. Чтобы обмен работал быстро и безопасно, база-источник отвечает за выгрузку, а база-приемник — за загрузку. При этом обработчики событий, которые должны выполняться в приемнике, берутся из правил, загруженных в саму базу-приемник.

Когда вы настраиваете синхронизацию в источнике и загружаете туда файл правил xml, вы обновляете только логику выгрузки. Обработчик ПриЗагрузке относится к логике приемника. Если в настройках синхронизации базы-приемника остались старые типовые правила, они понятия не имеют о вашем новом коде с НеЗамещатьОбъект. Программа просто использует те алгоритмы, которые прописаны в её локальных настройках синхронизации.

Решение: Настройка «Правил корреспондента»

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

  1. Откройте базу-приемник (ту, в которой документы не должны замещаться).
  2. Перейдите в раздел Администрирование — Синхронизация данных.
  3. Выберите нужную настройку синхронизации и откройте Параметры синхронизации данных.
  4. Найдите пункт меню Загрузить правила обмена. В некоторых конфигурациях это может называться «Настройка правил конвертации».
  5. Обратите внимание, что там часто предлагается выбор: «Правила для этой базы» и «Правила для базы-корреспондента».
  6. Вам необходимо подменить правила именно в части, касающейся загрузки в текущую базу. Загрузите модифицированный файл правил в соответствующий раздел.

После этого база-приемник «узнает» о существовании вашего обработчика ПриЗагрузке и начнет корректно интерпретировать переменную НеЗамещатьОбъект.

Нюансы работы переменной НеЗамещатьОбъект

Выясним некоторые важные технические моменты, которые влияют на стабильность обмена:

1. Только для найденных объектов. Флаг НеЗамещатьОбъект работает исключительно в случае, если 1С смогла сопоставить объект из файла с объектом в базе. Если объект новый (не найден), установка этого флага будет проигнорирована, и система создаст новый элемент. Это логично, так как «не замещать» можно только то, что уже существует.

2. Отличие от Отказ = Истина. Использование НеЗамещатьОбъект — это «мягкий» способ пропуска записи. Процесс загрузки файла при этом не прерывается, и в журнале регистрации не фиксируются ошибки. Если же использовать Отказ = Истина в том же событии, загрузка данного объекта будет прервана как ошибочная, что может привести к накоплению логов ошибок в мониторе синхронизации.

3. Проблема «зацикливания» регистрации. Важно понимать, что происходит в базе-источнике. Если в источнике документ изменили, он регистрируется к обмену. Он выгружается, попадает в приемник, приемник видит НеЗамещатьОбъект = Истина и ничего не делает. Но при следующем сеансе обмена источник снова может попытаться выгрузить этот документ, если регистрация не была очищена.

Для решения этой проблемы иногда требуется добавить логику на стороне источника в событие ПередВыгрузкой, чтобы вообще не выгружать документы, которые в приемнике уже считаются «финализированными» (хотя получить информацию о статусе документа в другой базе в момент выгрузки без веб-сервисов затруднительно).

Альтернативный метод: Использование подписки на события

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

Рассмотрим пример реализации в событии ПередЗаписью документа в базе-приемнике:


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

Однако стоит помнить, что программная установка Отказ = Истина в подписке при загрузке данных может вызвать критическую остановку обмена для этого пакета данных. Поэтому использование НеЗамещатьОбъект в правилах считается более предпочтительным и правильным с точки зрения архитектуры «Конвертации данных».

Проблема кэширования правил

Посмотрим на ситуацию, когда вы все сделали правильно: обновили правила в источнике, обновили «правила корреспондента» в приемнике, но флаг все равно не срабатывает. Часто причиной является агрессивное кэширование правил обмена платформой 1С.

Проанализируем действия для очистки кэша:

Итоги

Подведем итог нашему разбору. Основная причина, по которой НеЗамещатьОбъект не работает в синхронизации — это ожидание системой правил загрузки именно на стороне приемника.

Краткий чек-лист для исправления:

  1. Убедитесь, что код НеЗамещатьОбъект = ОбъектНайден И Объект.Ссылка.Проведен; написан именно в ПКО в событии ПриЗагрузке.
  2. Сохраните правила в файл xml.
  3. В базе-приемнике зайдите в настройки синхронизации и загрузите эти правила как Правила корреспондента.
  4. Выполните тестовую синхронизацию и убедитесь, что проведенные документы перестали затираться.

Такой подход позволит вам гибко управлять процессом обмена, защищая данные от случайного перезатирания и сохраняя целостность учета в базе-приемнике.

← На главную