При необходимости корректировки данных в регистрах накопления 1С часто возникает задача удаления конкретных записей, соответствующих определенным критериям. В отличие от простых операций, массовая правка движений требует понимания того, как платформа работает с наборами записей и итогами регистра.
Важно помнить, что объект РегистрНакопленияНаборЗаписей при записи выполняет полную перезапись данных, соответствующих установленному отбору. Если вы установили Отбор.Регистратор, вызвали Прочитать(), удалили строки из набора и нажали Записать(), платформа удалит старые движения и запишет только те, что остались в наборе. Это делает механизм удобным, но требует осторожности при работе с большими объемами данных.
Когда нам нужно удалить только те записи, которые не соответствуют определенному условию (например, по реквизиту организации в договоре), мы должны прочитать набор и отфильтровать строки. Важнейший технический нюанс: нельзя удалять строки из коллекции в обычном цикле Для каждого, так как это нарушает итерацию и приводит к пропуску элементов.
Правильнее всего использовать обратный цикл по индексу:
НаборЗаписей = РегистрыНакопления.Взаиморасчеты.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(Объект.Документ);
НаборЗаписей.Прочитать();
Индекс = НаборЗаписей.Количество() - 1;
Пока Индекс >= 0 Цикл
// Проверяем условие, при котором запись НЕ должна оставаться
Если Не НаборЗаписей[Индекс].Договор.Организация = Объект.Организация Тогда
НаборЗаписей.Удалить(Индекс);
КонецЕсли;
Индекс = Индекс - 1;
КонецЦикла;
НаборЗаписей.Записать();
Если записей очень много, работа с одним большим НаборЗаписей может вызвать блокировки базы данных и ошибки тайм-аута на SQL Server. В таких случаях рекомендуем использовать более профессиональный подход с запросом и пакетной обработкой:
// Пример логики пакетной обработки
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ РАЗЛИЧНЫЕ Регистратор ИЗ РегистрНакопления.Взаиморасчеты
ГДЕ Договор.Организация <> &Организация";
Запрос.УстановитьПараметр("Организация", ВыбОрганизация);
Результат = Запрос.Выполнить().Выгрузить();
Для Каждого Стр Из Результат Цикл
НЗ = РегистрыНакопления.Взаиморасчеты.СоздатьНаборЗаписей();
НЗ.Отбор.Регистратор.Установить(Стр.Регистратор);
НЗ.ОбменДанными.Загрузка = Истина; // Ускоряет запись
НЗ.Записать();
КонецЦикла;
При массовом удалении помните о следующих рекомендациях:
ОбменДанными.Загрузка = Истина отключает проведение по итогам и проверку ссылочной целостности, что существенно ускоряет операцию.LOCK все же возникает, разбейте транзакцию на мелкие части.Разбирая данные ситуации, мы видим, что наиболее эффективным подходом является не просто удаление, а полное формирование «правильного» набора движений с последующей записью. Такой подход минимизирует риски возникновения «битых» данных и обеспечивает стабильную работу системы.