Почему в 1С:Комплексная автоматизация документы остаются проведенными при пометке удаления и как очистить «зависшие» движения?

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

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

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

---

Выясняем причины: почему у распроведенных документов остаются движения?

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

Рассмотрим подробнее ключевые факторы, влияющие на появление этой проблемы:

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

---

Как технически возникает состояние «Проведен» + «Помечен на удаление»?

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

Однако этот запрет легко обойти программными методами, умышленно или случайно:

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

---

Пошаговое руководство по исправлению базы данных

Если в вашей базе «1С:Комплексная автоматизация» появились подобные документы, простое групповое перепроведение стандартными средствами может завершиться ошибками блокировок. Проанализируем алгоритм исправления этой ситуации по шагам.

Шаг 1. Исправление статуса «Проведен + Помечен на удаление»

Для того чтобы вернуть такие документы в корректное русло, необходимо использовать внешнюю обработку или запустить код в консоли кода со следующим алгоритмом:

  1. Снять пометку удаления без проверки проведения.
  2. Программно запустить стандартный механизм отмены проведения (чтобы гарантированно очистить все регистры).
  3. Корректно установить пометку удаления заново.

Посмотрим на пример программной реализации этого алгоритма:


Выборка = Документы.ПередачаТоваровМеждуОрганизациями.Выбрать();
Пока Выборка.Следующий() Цикл
    ДокОбъект = Выборка.ПолучитьОбъект();
    
    // Ищем документы в некорректном состоянии
    Если ДокОбъект.Проведен И ДокОбъект.ПометкаУдаления Тогда
        
        Попытка
            // Шаг A: Сбрасываем пометку удаления, записывая объект просто как проведенный
            ДокОбъект.ПометкаУдаления = Ложь;
            ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
            
            // Шаг B: Вызываем штатную отмену проведения для очистки регистров
            ДокОбъект.Записать(РежимЗаписиДокумента.ОтменаПроведения);
            
            // Шаг C: Устанавливаем пометку удаления стандартным безопасным методом
            ДокОбъект.УстановитьПометкуУдаления(Истина);
            
            Сообщить("Документ успешно исправлен: " + ДокОбъект.Ссылка);
        Исключение
            Сообщить("Ошибка исправления документа " + ДокОбъект.Ссылка + ": " + ОписаниеОшибки());
        КонецПопытки;
        
    КонецЕсли;
КонецЦикла;

Шаг 2. Принудительная очистка «зависших» движений по регистрам

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

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


// Определяем очищаемый документ (ссылку)
СсылкаНаДокумент = Документы.ПередачаТоваровМеждуОрганизациями.НайтиПоРеквизиту("Номер", "0000-000001");

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

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

Шаг 3. Проведение Тестирования и Исправления (ТиИ)

После программной очистки и приведения документов к единому логическому статусу крайне важно устранить возможные физические несоответствия на уровне СУБД. Для этого:

  1. Запустите базу данных в режиме Конфигуратора.
  2. Перейдите в меню Администрирование -> Тестирование и исправление...
  3. Установите флаги напротив следующих проверок:
    • «Реиндексация таблиц информационной базы»;
    • «Проверка логической целостности»;
    • «Проверка ссылочной целостности».
  4. В параметрах обработки при обнаружении битых ссылок выберите вариант Очищать ссылки или Создавать объекты (в зависимости от ваших политик восстановления данных).
  5. Нажмите кнопку Выполнить.

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

← На главную