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

Программист
← На главную

При настройке обмена данными между базами 1С через "Конвертацию Данных 2.0" часто возникает задача: как обеспечить полное соответствие данных в регистре сведений приемника данным из источника? Стандартная загрузка легко добавляет и изменяет записи, но что делать, если в источнике часть данных была удалена? В приемнике эти "лишние" записи остаются, нарушая целостность данных. Проанализируем ситуацию, когда при проведении или отмене проведения документа-источника нужно не просто добавить/изменить, а полностью синхронизировать набор записей в регистре сведений приемника, включая удаление устаревших.

Рассмотрим два основных подхода для решения этой задачи (в дополнение к инструменту выгрузка и загрузка данных XML адаптивная): создание специального правила для очистки записей и передача полного набора данных через параметры объекта.

Метод 1: Отправка команды на очистку через отдельное правило

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

Разберем по шагам, как реализовать перенос объектов 1С с корректной синхронизацией:

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

Посмотрим на пример кода для обработчика ПослеЗагрузки:


// Создаем новый набор записей для нашего регистра
НЗ = РегистрыСведений.ИмяВашегоРегистра.СоздатьНаборЗаписей();

// Устанавливаем отбор по ключевым измерениям.
// Значения для отбора (Объект.Измерение1, Объект.Измерение2) 
// придут из источника по правилам конвертации свойств, которые мы создали.
НЗ.Отбор.Измерение1.Установить(Объект.Измерение1);
НЗ.Отбор.Измерение2.Установить(Объект.Измерение2);

// Записываем пустой набор. Это действие удалит все записи, 
// соответствующие установленному отбору.
НЗ.Записать(); 

// Устанавливаем отказ в Истина, чтобы система не пыталась записать 
// сам "пустой" объект-приемник. Нам нужен был только код в обработчике.
Отказ = Истина;

Важный момент: когда вызывать это правило? Его нужно вызывать:

Крайне важно обратить внимание на типы данных! Если тип значения, которое вы устанавливаете в отбор (например, Объект.Измерение1), не совпадет с типом измерения регистра, отбор не сработает корректно. В худшем случае, если значение окажется Неопределено, отбор по этому измерению не установится, и вы рискуете удалить гораздо больше записей, чем планировали. Как гласит известная шутка: "Каждый программист 1С хотя бы раз в своей карьере должен удалить важный регистр сведений". Будьте внимательны и всегда тщательно тестируйте обмен на копиях баз.

Метод 2: Передача данных и флага очистки через параметры

Это более гибкий и мощный подход. Вся логика по обновлению регистра сведений концентрируется в одном месте — в обработчике После загрузки основного объекта (например, документа). Идея в том, чтобы не выгружать записи регистра напрямую, а сложить их в специальный параметр и передать вместе с документом.

Проанализируем шаги реализации:

  1. Настройка ПКС для передачи в параметр. В ПКО для вашего документа создайте ПКС для данных регистра. Назовите приемник, например, "ДанныеРС", и установите флаг "Передавать данные в параметр".
  2. Подготовка данных в источнике. В ПКО документа в обработчике события Перед выгрузкой напишите код, который получит актуальные данные для регистра сведений.

    Здесь возможны два сценария:

    • Данные есть: выполните запрос, выгрузите результат в таблицу значений и присвойте эту таблицу переменной Значение.
    • Данных нет (их нужно удалить в приемнике): если запрос вернул пустой результат, создайте структуру со специальным флагом, например, Новый Структура("ПростоОчистить", Истина) и присвойте ее переменной Значение.
  3. Обработка параметра в приемнике. В ПКО документа в обработчике события После загрузки получаем и анализируем наш параметр.

Примерный код для обработчика После загрузки (по логике это удаление движений документов по переданному фильтру):


// Проверяем, что параметры объекта были переданы
Если ПараметрыОбъекта <> Неопределено И ПараметрыОбъекта.Свойство("ДанныеРС") Тогда

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

КонецЕсли;

Этот метод считается более надежным, так как он выполняет операцию "полного замещения" данных за один шаг. Сначала полностью очищаются старые записи по отбору, а затем записываются новые. Это гарантирует, что в базе-приемнике будет точная копия данных из источника.

Важные моменты и лучшие практики

← На главную