Как правильно пометить документ на удаление в 1С и очистить его движения в регистрах

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

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

Причина, по которой движения документа не уходят из регистров

Проанализируем распространенный сценарий, при котором разработчик пытается напрямую изменить свойства объекта в памяти:


Док2 = Док.ПолучитьОбъект();
Док2.ПометкаУдаления = Истина;
Док2.Проведен = Ложь;

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

Даже если после присвоения свойств вызвать стандартный метод Док2.Записать() без указания режима записи, платформа запишет лишь новые значения реквизитов флагов. Однако сам по себе признак Проведен = Ложь, присвоенный напрямую в коде, не запускает штатный механизм отмены проведения и автоудаления движений по регистрам.

Корректный способ установки пометки на удаление

Для корректного отзыва движений и установки пометки на удаление платформа 1С предоставляет специализированный метод УстановитьПометкуУдаления().

Если документ был проведен, использование метода УстановитьПометкуУдаления(Истина) автоматически выполняет отмену проведения документа, удаляет его записи из связанных регистров (в соответствии с настройками метаданных) и сохраняет объект в базе данных.

Посмотрим на исправленный и рабочий вариант алгоритма:


Для Каждого Итерация Из тзФайл Цикл
    Док = Документы.ВнутреннийЗаказ.НайтиПоНомеру(Итерация.Код, ТекущаяДата());
    
    Если Не ЗначениеЗаполнено(Док) Тогда
        Продолжить;
    КонецЕсли;
    
    ДокОбъект = Док.ПолучитьОбъект();
    ДокОбъект.УстановитьПометкуУдаления(Истина);
КонецЦикла;

Альтернативные способы очистки движений

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

  1. Явный вызов режима отмены проведения:

    Можно явно вызвать отмену проведения через режим записи документа перед его пометкой на удаление:

    
    ДокОбъект.Записать(РежимЗаписиДокумента.ОтменаПроведения);
    ДокОбъект.УстановитьПометкуУдаления(Истина);
    
  2. Очистка коллекций движений документа:

    Если требуется принудительно очистить все наборы записей движений документа программно:

    
    Для Каждого НаборЗаписей Из ДокОбъект.Движения Цикл
        НаборЗаписей.Очистить();
        НаборЗаписей.Записать();
    КонецЦикла;
    
    ДокОбъект.УстановитьПометкуУдаления(Истина);
    
  3. Очистка через набор записей регистратора:

    Для гарантированного сброса записей регистра без изменения самого объекта документа можно очистить набор записей с фильтром по регистратору:

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

Важные нюансы и рекомендации

При написании обработок по работе с документами обратим внимание на следующие ключевые детали:

Проверка заполнения ссылки: Использование функции ПустаяСтрока(Док) для проверки наличия документа некорректно, так как происходят лишние операции приведения типов. Рекомендуется использовать встроенные функции ЗначениеЗаполнено(Док) или метод ссылки Док.Пустая().

Период нумерации: Метод НайтиПоНомеру() ищет документ в периоде нумерации, соответствующем переданной дате. При передаче ТекущаяДата() поиск будет происходить только в текущем периоде (например, в текущем году).

Режим загрузки данных: Если в коде используется флаг ОбменДанными.Загрузка = Истина, платформенные события отмены проведения и обработки очистки движений не вызываются, поэтому движения необходимо очищать вручную.

← На главную