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