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