Как правильно удалять записи из регистра сведений Состав групп ДДУ с помощью Менеджера записи

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

При работе с регистрами сведений в 1С:Предприятие 8 часто возникает задача очистки неактуальных данных. Одной из типичных проблем является ситуация, когда программный код вместо удаления записи либо ничего не делает, либо вовсе перезаписывает данные с неожиданными значениями. В этой статье мы подробно разберем, как корректно использовать объект РегистрСведенийМенеджерЗаписи на примере регистра Состав групп ДДУ, и выясним, почему важно правильно заполнять ключевые поля.

Разбор проблемы: почему запись не удаляется?

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

Проанализируем причины такого поведения:

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

Корректная реализация через Менеджер записи

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


Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |	СоставГруппДДУ.Период КАК Период,
    |	СоставГруппДДУ.Ребенок КАК Ребенок,
    |	СоставГруппДДУ.ГруппаДетскогоУчреждения КАК ГруппаДетскогоУчреждения,
    |	СоставГруппДДУ.Льгота КАК Льгота,
    |	СоставГруппДДУ.СтавкаОплаты КАК СтавкаОплаты,
    |	СоставГруппДДУ.Договор КАК Договор,
    |	СоставГруппДДУ.Актуальность КАК Актуальность
    |ИЗ
    |	РегистрСведений.СоставГруппДДУ КАК СоставГруппДДУ
    |ГДЕ
    |	СоставГруппДДУ.Актуальность = ЛОЖЬ";

Выборка = Запрос.Выполнить().Выбрать();

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

Обратите внимание: в запросе мы явно указали СоставГруппДДУ.Актуальность КАК Актуальность и добавили его в условия ГДЕ. Это гарантирует, что в МенеджерЗаписи попадут именно те строки, которые соответствуют нашему критерию.

Важность использования метода Прочитать()

Хотя при полном заполнении измерений метод Удалить() обычно отрабатывает корректно, хорошей практикой считается вызов метода Прочитать() перед манипуляциями с данными. Это позволяет убедиться, что запись с такими ключами действительно существует в базе.

Разберем по шагам:

  1. Создаем МенеджерЗаписи.
  2. Заполняем измерения (например, Период, Ребенок, ГруппаДетскогоУчреждения).
  3. Вызываем РС.Прочитать().
  4. Если РС.Выбран() возвращает Истина, вызываем РС.Удалить().

Оптимизация: использование Набора записей

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

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


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

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

Рекомендации по работе с регистром Состав групп ДДУ

При выполнении очистки в таких специфических регистрах, как Состав групп ДДУ (часто встречающийся в конфигурациях для бюджетных учреждений), следует помнить о следующих моментах:

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

← На главную