Как удалить записи из периодического независимого регистра сведений при удалении элемента справочника

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

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

Разбираем работу свойства Ведущее

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

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

Важные моменты использования свойства «Ведущее»:

  1. Записи удаляются платформой автоматически при окончательном удалении (стирании) ссылки из базы.
  2. Включение этого свойства автоматически создает индекс по данному измерению, что полезно для поиска, но может незначительно замедлить запись при огромных объемах данных.
  3. Если вам нужно, чтобы записи исчезали именно в момент установки пометки на удаление, свойство Ведущее вам не поможет — придется писать код.

Программное удаление записей через НаборЗаписей

Если нам необходимо программно управлять составом регистра, мы используем объект РегистрСведенийНаборЗаписей. Это универсальный и наиболее правильный способ работы с независимыми регистрами. Рассмотрим пошагово, как правильно настроить отбор и выполнить удаление.

Предположим, у нас есть регистр УстановкаПроектовДляНоменклатуры, где измерение НоменклатураПроекта ссылается на справочник Номенклатура. Нам нужно очистить все записи по конкретной позиции.

Проанализируем правильный алгоритм:


// Создаем объект набора записей
НаборЗаписей = РегистрыСведений.УстановкаПроектовДляНоменклатуры.СоздатьНаборЗаписей();

// Устанавливаем фильтр по интересующему нас элементу
НаборЗаписей.Отбор.НоменклатураПроекта.Установить(СсылкаНаНоменклатуру);

// Записываем пустой набор, что фактически удаляет все записи, подходящие под отбор
НаборЗаписей.Записать(Истина);

Обратите внимание на метод Записать(Истина). Параметр Истина означает, что текущие записи в базе данных, соответствующие установленному отбору, будут полностью замещены содержимым набора. Так как мы не добавляли в набор никаких строк после установки отбора, в базу «запишется пустота», а старые данные удалятся.

Выясняем причины, почему Набор записей может быть пустым

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

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

Посмотрим на пример ошибочного кода, который часто встречается на форумах:


НаборЗаписей = РегистрыСведений.УстановкаПроектовДляНоменклатуры.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.НоменклатураПроекта.Значение = Ссылка;
НаборЗаписей.Отбор.НоменклатураПроекта.Использование = Истина;
НаборЗаписей.Прочитать(); // Если записей нет в БД на этот момент, набор будет пуст

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

Особенности периодических регистров

Поскольку мы рассматриваем периодический регистр, важно помнить о поле Период. Когда мы устанавливаем отбор только по измерению Номенклатура, метод Записать(Истина) удалит всю историю изменений по этой номенклатуре за все даты. Если логика вашей задачи требует удаления записи только на конкретную дату, вам придется добавить в отбор и период:


НаборЗаписей.Отбор.Период.Установить(НужнаяДата);
НаборЗаписей.Отбор.НоменклатураПроекта.Установить(Ссылка);
НаборЗаписей.Записать(Истина);

Где лучше разместить код удаления?

Выясним наиболее подходящее место для размещения логики очистки регистра. У нас есть два основных варианта:

1. Модуль объекта справочника

Мы можем использовать обработчик ПередЗаписью. Это удобно, так как мы имеем доступ к свойству ПометкаУдаления. Проанализируем пример:


Процедура ПередЗаписью(Отказ)
    Если ПометкаУдаления Тогда
        // Здесь вызываем процедуру удаления записей из регистра
        УдалитьЗаписиИзРегистра(Ссылка);
    КонецЕсли;
КонецПроцедуры

2. Подписки на события

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

Резюмируем: Для автоматического удаления записей при физическом удалении используйте флаг Ведущее. Для удаления при пометке на удаление используйте НаборЗаписей с установленным отбором в обработчиках событий или подписках. Помните, что метод Записать(Истина) без предварительного чтения — самый быстрый способ полной очистки данных регистра по заданному фильтру.

← На главную