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