Как очистить данные регистра сведений по документу перед загрузкой через Конвертацию данных 2.0

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При работе с инструментом «Конвертация данных 2.0» (КД 2.0) разработчики часто сталкиваются с ситуацией, когда данные в базу-приемник передаются не в виде готовых объектов, а через произвольный запрос. Это особенно актуально для регистров сведений, информация в которые поступает из различных источников. Одной из главных проблем в этом случае становится «замусоривание» регистра: при повторной загрузке данных старые записи остаются, а новые добавляются или дублируются.

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

Суть проблемы: почему стандартные методы не подходят

Проанализируем типичную ситуацию. Допустим, мы передаем данные в регистр сведений, где в качестве одного из измерений (или регистратора) указан документ. В источнике мы используем запрос, который возвращает плоскую таблицу: для одного документа может быть 10, 100 или 1000 строк данных. Если мы пропишем очистку в обработчике ПередЗагрузкой или ПриЗагрузке для каждой записи регистра, то получим следующую логику: система загружает первую строку — чистит регистр — записывает строку. Затем загружает вторую строку — снова чистит регистр (удаляя первую загруженную) — записывает вторую. В итоге в базе останется только последняя строка из всего набора.

Нам же необходимо, чтобы при появлении первого упоминания документа в файле загрузки данные в регистре по нему полностью удалились, а все последующие строки этого же документа просто дописывались в чистый регистр.

Решение проблемы через использование глобальных параметров

Рассмотрим наиболее эффективный способ решения этой задачи — использование глобальной структуры Параметры, которая доступна во всех обработчиках КД 2.0 на протяжении всего сеанса загрузки данных. Этот метод позволяет нам «запоминать», для каких документов мы уже произвели очистку в текущей сессии.

Разберем реализацию по шагам.

Шаг 1: Инициализация списка обработанных объектов

Для начала нам нужно подготовить хранилище, где мы будем держать ссылки на уже «очищенные» документы. Лучшим местом для этого является обработчик «Перед загрузкой данных» в настройках самой конвертации. Этот код выполняется один раз в самом начале процесса загрузки.

Инициализируем список значений в глобальной структуре параметров:


// В обработчике "Перед загрузкой данных"
Параметры.Вставить("СписокОчищенныхДокументов", Новый СписокЗначений);

Теперь у нас есть пустой список, к которому мы сможем обращаться из любого ПКО (Правила конвертации объектов).

Шаг 2: Реализация логики очистки в ПКО регистра

Теперь перейдем к самому правилу конвертации, которое отвечает за загрузку записей в регистр сведений. Нам потребуется обработчик «Перед загрузкой». Здесь мы будем проверять, встречался ли нам этот документ ранее в текущем файле обмена.

Предположим, что ссылка на документ-основание передается в свойство Объект (или это регистратор). Алгоритм будет следующим:

  1. Получаем ссылку на документ из входящих данных.
  2. Проверяем наличие этой ссылки в нашем глобальном списке Параметры.СписокОчищенныхДокументов.
  3. Если ссылки нет — производим программную очистку регистра по этому документу и добавляем ссылку в список.
  4. Если ссылка уже есть — ничего не делаем, позволяя системе просто записать новую строку.

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


// Получаем ссылку на документ из свойств загружаемого объекта
// В КД 2.0 параметры объекта доступны через структуру "Объект" или "ПараметрыОбъекта"
ДокументСсылка = Объект.ДокументОснование; 

Если ДокументСсылка <> Неопределено И Не ДокументСсылка.Пустая() Тогда
    
    // Проверяем, чистили ли мы уже регистр по этому документу
    Если Параметры.СписокОчищенныхДокументов.НайтиПоЗначению(ДокументСсылка) = Неопределено Тогда
        
        // Документ встретился впервые, нужно очистить старые записи в регистре
        НаборЗаписей = РегистрыСведений.ИмяВашегоРегистра.СоздатьНаборЗаписей();
        
        // Устанавливаем отбор по нашему документу
        // ВАЖНО: Укажите правильное имя измерения или "Регистратор"
        НаборЗаписей.Отбор.ДокументОснование.Установить(ДокументСсылка);
        
        // Записываем пустой набор (очищаем данные в базе)
        НаборЗаписей.Записать(Истина);
        
        // Добавляем документ в список, чтобы больше его не чистить в этой сессии
        Параметры.СписокОчищенныхДокументов.Добавить(ДокументСсылка);
        
        // Сообщим для отладки (опционально)
        // Сообщить("Регистр очищен по документу: " + ДокументСсылка);
        
    КонецЕсли;

КонецЕсли;

Шаг 3: Технические нюансы работы с набором записей

Выясним причину, по которой мы используем РегистрСведенийНаборЗаписей вместо простого удаления. При использовании НабораЗаписей с установленным отбором и методом Записать(Истина), 1С максимально быстро и эффективно очищает все записи, попадающие под фильтр. Это гораздо надежнее, чем пытаться перебирать записи в цикле.

Важный момент: если ваш регистр сведений является подчиненным регистратору, то очистка через НаборЗаписей по регистратору — это стандартная и безопасная процедура. Если же регистр независимый, убедитесь, что в отборе участвуют все необходимые измерения, чтобы не удалить лишние данные, не относящиеся к текущей загрузке.

Альтернативный подход: Использование идентификатора загрузки

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

Разберем этот сценарий по шагам:

  1. В конфигурации-приемнике в регистр сведений добавляется служебный реквизит ИдентификаторОбмена (тип Число или Строка).
  2. Перед началом загрузки генерируется уникальный номер сессии (например, текущая дата и время).
  3. При загрузке каждой строки этот номер записывается в ИдентификаторОбмена.
  4. В самом конце загрузки (обработчик «После загрузки данных») выполняется запрос к регистру, который выбирает и удаляет все записи по документам, участвовавшим в обмене, у которых ИдентификаторОбмена не равен текущему номеру сессии.

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

Резюме

Мы проанализировали ситуацию и выяснили, что наиболее гибким и «чистым» решением для Конвертации данных 2.0 является комбинация использования структуры Параметры и программного управления набором записей. Этот подход позволяет:

Помните, что при работе с СписокЗначений в памяти, если объем уникальных документов исчисляется сотнями тысяч, стоит следить за потреблением ресурсов сервера. Однако для большинства стандартных задач обмена между базами 1С этот метод является эталонным.

← На главную