Как избавиться от движений по документам, помеченным на удаление

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

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

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

Почему возникают движения у помеченных документов?

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

Прежде чем переходить к решению, давайте выясним причину возникновения данной ошибки. В объектной модели 1С за состояние проведения отвечает реквизит Проведен (Posted). Когда мы помечаем документ на удаление через интерфейс, система автоматически вызывает процедуру ОтменаПроведения. Однако, если изменение пометки удаления выполнялось программно с помощью метода УстановитьПометкуУдаления(Истина) без дополнительных проверок или если свертка базы проводилась «прямыми» запросами к базе данных, свойство Проведен может остаться в значении Истина при установленной пометке удаления.

Разберем основные методы решения этой задачи — от самых простых (встроенных) до программных способов, требующих написания кода.

Способ 1. Программная очистка движений (Самый надежный)

Программный метод является наиболее гибким, так как позволяет точечно воздействовать на регистры, не затрагивая лишние данные. Рассмотрим алгоритм действий. Вместо того чтобы пытаться перепроводить документы, можно использовать решение для массовой очистки регистров в один клик. Мы будем напрямую очищать наборы записей регистров, где регистратором выступает наш проблемный документ.

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


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

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

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

Способ 2. Оптимизация через отключение итогов

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

Разберем по шагам правильную последовательность действий для массовой очистки:

  1. Отключение итогов: Используем метод УстановитьИспользованиеИтогов(Ложь) для всех регистров, по которым будут удаляться движения.
  2. Выполнение очистки: Запускаем программный код из первого способа.
  3. Включение итогов: Возвращаем использование итогов методом УстановитьИспользованиеИтогов(Истина).
  4. Полный пересчет: Выполняем пересчет итогов через Конфигуратор (меню "Администрирование" -> "Тестирование и исправление" -> "Пересчет итогов") или программно.

Такой подход сокращает время обработки в десятки раз, так как 1С не будет тратить ресурсы на обновление итогов после каждого удаленного документа.

Способ 3. Групповая обработка объектов

Если вы не хотите писать код, можно воспользоваться типовой обработкой «Групповое изменение реквизитов» (в современных конфигурациях на БСП она находится в разделе «Администрирование» — «Обслуживание»).

Рассмотрим порядок действий в этой обработке:

  1. Выбираем тип документов, у которых остались движения.
  2. Добавляем фильтр: Пометка удаления = Да И Проведен = Да.
  3. В «Дополнительных настройках» (кнопка внизу) устанавливаем флаги «Изменять служебные реквизиты» и «Работать в режиме записи "Обмен данными"».
  4. Находим реквизит Проведен и устанавливаем ему значение Ложь.

Важно: Этот способ сработает только в том случае, если логика платформы при снятии флага Проведен инициирует очистку движений. В ряде случаев (особенно в старых версиях 7.7 или при специфических настройках v8) может потребоваться сначала переустановить пометку удаления.

Способ 4. Многопоточная обработка

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

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

Нюансы «Тестирования и исправления» (ТиИ)

Автор вопроса упоминал возможность использования «ТиС» (имея в виду Тестирование и Исправление). Проанализируем, поможет ли это. Стандартные процедуры ТиИ, такие как «Проверка логической целостности» или «Очистка ссылок», эффективны только в том случае, если записи в регистрах ссылаются на несуществующие (физически удаленные) объекты. Если же документ существует, но просто помечен на удаление, ТиИ может не посчитать его движения мусором.

Однако процедура «Пересчет итогов» обязательна к выполнению ПОСЛЕ программной очистки движений, если вы отключали итоги для скорости. Без этого отчеты (Оборотно-сальдовая ведомость и другие) будут показывать неверные данные, так как они берут информацию из итоговых таблиц, а не из таблиц оборотов.

Заключение и рекомендации

Подводя итог, можно сказать: самый быстрый и безопасный способ — это программная очистка наборов записей с отключенными итогами. Выясним основные правила предосторожности:

Выполнив эти шаги, вы полностью очистите базу от последствий некорректной свертки и обеспечите корректность бухгалтерских отчетов.

← На главную