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