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

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

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

Постановка задачи и выбор инструмента

Рассмотрим ситуацию: у нас есть независимый непериодический регистр сведений (например, АналитикаУчетаПоПартнерам или ГруппыЗначенийДоступа). Нам необходимо удалить запись, имея на руках ссылку на объект (например, на Партнера). В 1С существует два основных способа решения этой задачи:

  1. Использование менеджера записи (объект РегистрСведенийМенеджерЗаписи). Подходит, когда нужно удалить одну конкретную запись, для которой известны значения абсолютно всех измерений.
  2. Использование набора записей (объект РегистрСведенийНаборЗаписей). Оптимален, когда нужно удалить одну или несколько записей по определенному фильтру (отбору).

Способ №1: Удаление через Менеджер записи

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

Разберем по шагам, как это реализовать в коде:


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

// Заполняем КЛЮЧЕВЫЕ поля (измерения). 
// Если хотя бы одно измерение не будет заполнено, система не найдет запись.
Запись.Организация = ВыбраннаяОрганизация;
Запись.Партнер     = ВыбранныйПартнер;

// Важный нюанс: перед удалением запись рекомендуется "прочитать"
Запись.Прочитать();

Если Запись.Выбранный() Тогда
    // Если запись найдена в базе, удаляем её
    Запись.Удалить();
КонецЕсли;

Почему запись может не удалиться? Если вы заполнили только часть измерений (например, только Партнер, проигнорировав Организация), метод Прочитать() не найдет запись, а метод Удалить() либо ничего не сделает, либо выдаст ошибку (в зависимости от контекста). Система должна однозначно понимать, какую именно строчку в таблице БД нужно стереть.

Способ №2: Удаление через Набор записей

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

Рассмотрим пример реализации:


// Создаем набор записей
Набор = РегистрыСведений.ГруппыЗначенийДоступа.СоздатьНаборЗаписей();

// Устанавливаем отбор по нужному измерению
Набор.Отбор.ЗначениеДоступа.Установить(ПартнерСсылка);

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

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

Разбор сложных случаев и специфических регистров

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

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

Сравнение методов: что выбрать?

Выясним, какой подход лучше использовать в различных сценариях:

Используйте Набор записей, если:

Используйте Менеджер записи, если:

Важное предостережение: Будьте предельно осторожны при использовании НаборЗаписей без установки Отбора. Если вызвать Набор.Записать() у набора без фильтров, система полностью очистит весь регистр сведений, так как фильтр "пустой" соответствует всем записям в таблице. Всегда проверяйте, что отбор установлен и он корректен.

Таким образом, для большинства задач программного удаления наиболее безопасным и удобным инструментом является РегистрСведенийНаборЗаписей с четко установленным фильтром по ведущим измерениям.

← На главную