Почему не отменяется регистрация изменений регистра сведений в РИБ и как это исправить?

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

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

Рассмотрим подробно причины такого поведения платформы 1С:Предприятие и разберем корректный способ удаления регистрации изменений независимых регистров сведений.

Анализ проблемы: почему метод не выдает ошибку, но не снимает регистрацию

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

Разберем типичные ошибки при программном снятии регистрации:

  1. Установка отбора по измерениям без признака «Основной отбор»: Если в объекте НаборЗаписей устанавливается отбор по измерениям, для которых в метаданных не взведен флаг «Основной отбор», либо пропускается одно из обязательных измерений с этим флагом, платформа не может сопоставить созданный набор с записью в таблице изменений. В результате метод исполняется «вхолостую» — без ошибок, но и без физического удаления регистрации.
  2. Запрос к основной таблице регистра вместо таблицы изменений: При выборе данных непосредственно из физической таблицы РегистрСведений.<ИмяРегистра> система выбирает все записи, но их комбинации могут не совпадать с реальным составом ключей в таблице изменений. Правильнее обращаться к виртуальной таблице изменений РегистрСведений.<ИмяРегистра>.Изменения.
  3. Лишний вызов метода Прочитать(): Для удаления записи из таблицы изменений считывать данные регистра в память не требуется. Достаточно сформировать объект НаборЗаписей, корректно заполнить его отбор и передать в метод удаления регистрации.

Шаг 1. Проверка настроек метаданных регистра

Выясним, какие именно измерения участвуют в формировании ключа регистрации. Для этого выполним следующие действия в конфигураторе:

  1. Откроем дерево метаданных и найдем нужный регистр сведений.
  2. Перейдем в ветку Измерения.
  3. Откроем свойства каждого измерения и проверим флаг «Основной отбор».

Запомним только те измерения, у которых данный флаг установлен. Именно по ним и только по ним необходимо устанавливать значения в свойстве Отбор набора записей.

Шаг 2. Правильная выборка зарегистрированных изменений

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	ТаблицаИзменений.Узел КАК Узел,
    |	ТаблицаИзменений.Измерение1 КАК Измерение1,
    |	ТаблицаИзменений.Измерение2 КАК Измерение2
    |ИЗ
    |	РегистрСведений.ВашРегистрСведений.Изменения КАК ТаблицаИзменений
    |ГДЕ
    |	ТаблицаИзменений.Узел = &УзелДляОбработки";

Запрос.УстановитьПараметр("УзелДляОбработки", УзелДляОбработки);
РезультатЗапроса = Запрос.Выполнить();
Выборка = РезультатЗапроса.Выбрать();

Шаг 3. Удаление регистрации изменений в цикле

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


Пока Выборка.Следующий() Цикл

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

КонецЦикла;

Обратите внимание: метод Набор.Прочитать() вызываться не должен. Передача сформированного набора записей с отбором по ключевым измерениям в ПланыОбмена.УдалитьРегистрациюИзменений() полностью очищает запись о регистрации для данного ключа.

Альтернативные способы решения проблемы

Рассмотрим другие варианты решения задачи без написания собственного кода:

  1. Типовая обработка БСП «Регистрация изменений для обмена данными»: Входит в состав большинства типовых конфигураций. Позволяет интерактивно открыть список зарегистрированных объектов по узлам, отфильтровать нужные записи регистра сведений и массово отменить их регистрацию.
  2. Полная отмена регистрации по узлу: Если необходимо полностью очистить все изменения по объекту для узла, можно передать метаданные регистра без создания набора записей:
    
    ПланыОбмена.УдалитьРегистрациюИзменений(УзелДляОбработки, Метаданные.РегистрыСведений.ВашРегистрСведений);
    
  3. Настройка авторегистрации: Если записи не должны регистрироваться автоматически при записи регистра, в составе Плана Обмена для данного регистра сведений рекомендуется установить параметр Авторегистрация в значение Запретить и управлять регистрацией вручную через ПланыОбмена.ЗарегистрироватьИзменения().
← На главную