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