Как правильно программно удалить записи из регистра накопления с отбором?

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

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

Основные принципы работы с набором записей

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

Способ 1: Удаление записей в цикле с проверкой условий

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

Правильнее всего использовать обратный цикл по индексу:


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

Индекс = НаборЗаписей.Количество() - 1;
Пока Индекс >= 0 Цикл
    // Проверяем условие, при котором запись НЕ должна оставаться
    Если Не НаборЗаписей[Индекс].Договор.Организация = Объект.Организация Тогда
        НаборЗаписей.Удалить(Индекс);
    КонецЕсли;
    Индекс = Индекс - 1;
КонецЦикла;

НаборЗаписей.Записать();

Способ 2: Оптимизация для больших объемов данных

Если записей очень много, работа с одним большим НаборЗаписей может вызвать блокировки базы данных и ошибки тайм-аута на SQL Server. В таких случаях рекомендуем использовать более профессиональный подход с запросом и пакетной обработкой:

  1. С помощью запроса выберите все регистраторы, у которых есть записи, подлежащие удалению.
  2. Разбейте полученный список на пакеты (например, по 500-1000 документов).
  3. В цикле по пакету устанавливайте отбор по регистратору, загружайте движения и перезаписывайте набор.

// Пример логики пакетной обработки
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ Регистратор ИЗ РегистрНакопления.Взаиморасчеты 
               ГДЕ Договор.Организация <> &Организация";
Запрос.УстановитьПараметр("Организация", ВыбОрганизация);
Результат = Запрос.Выполнить().Выгрузить();

Для Каждого Стр Из Результат Цикл
    НЗ = РегистрыНакопления.Взаиморасчеты.СоздатьНаборЗаписей();
    НЗ.Отбор.Регистратор.Установить(Стр.Регистратор);
    НЗ.ОбменДанными.Загрузка = Истина; // Ускоряет запись
    НЗ.Записать();
КонецЦикла;

Почему это важно для производительности?

При массовом удалении помните о следующих рекомендациях:

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

← На главную