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