При работе с крупными прикладными решениями на платформе «1С:Предприятие 8.3», такими как «1С:Комплексная автоматизация» (КА) или «1С:ERP Управление предприятием», технические специалисты часто сталкиваются с аномалиями в поведении документов. Одна из самых парадоксальных ситуаций — когда документ одновременно имеет статус «Проведен» и «Помечен на удаление», либо когда после отмены проведения у документа остаются активные движения по регистрам накопления или сведений.
В этой статье мы подробно проанализируем причины возникновения таких ошибок, разберем архитектурные особенности работы механизмов «Интеркампани» и платформенные нюансы перезаписи объектов, а также предоставим готовые инструменты для исправления базы данных.
---
Для начала разберем ситуацию, когда документ успешно распроведен в интерфейсе пользователя (имеет статус «Не проведен»), но при этом отчеты или консоль запросов показывают, что движения по регистрам все еще существуют. В решениях класса ERP и КА это чаще всего происходит со следующими типами документов:
Рассмотрим подробнее ключевые факторы, влияющие на появление этой проблемы:
Резервы товаров организаций. Когда одна организация продает товар, фактически принадлежащий другому юридическому лицу внутри холдинга, система фиксирует это как «долг» по резервам. Документ «Передача товаров между организациями» вводится для того, чтобы этот долг перекрыть.
Алгоритмы закрытия месяца и контроля резервов стремятся сбалансировать остатки глобально на конец периода. При некорректной или непоследовательной отмене проведения цепочки документов «Реализация — Передача» платформа может не очистить записи в регистре Резервы товаров организаций, так как первоисточник (реализация) все еще активен и требует обеспечения.УдалениеДвижений в конфигураторе. Платформа предлагает три режима:
Удалять автоматически — движения очищаются платформой при отмене проведения;Удалять автоматически при отмене проведения — очистка происходит только при явном вызове транзакции отмены проведения;Не удалять автоматически — управление движениями полностью возложено на код разработчика в модуле документа.---
В обычном режиме работы (через интерактивный интерфейс) платформа «1С:Предприятие 8» жестко блокирует возможность одновременно установить пометку удаления на проведенный документ. Стандартный метод УстановитьПометкуУдаления(Истина) сначала инициирует транзакцию отмены проведения документа ОбработкаУдаленияПроведения, очищает регистры, и только затем записывает признак удаления.
Однако этот запрет легко обойти программными методами, умышленно или случайно:
ПометкаУдаления = Истина напрямую через список реквизитов и запускает выполнение, обработка выполняет прямую запись объекта в базу данных. В этот момент платформенные проверки обходятся, документ помечается на удаление, но транзакция снятия с проведения не запускается. Как результат — движения остаются на месте, а документ приобретает «двойственный» статус.
ДокументОбъект.ОбменДанными.Загрузка = Истина;
Этот флаг указывает платформе, что объект переносится «как есть» из другого источника. Платформа отключает подписки на события, проверки бизнес-логики и транзакционные ограничения. Если в файле обмена документ имел пометку удаления, но в текущей базе он был проведен — после записи вы получите проведенный документ с пометкой удаления.---
Если в вашей базе «1С:Комплексная автоматизация» появились подобные документы, простое групповое перепроведение стандартными средствами может завершиться ошибками блокировок. Проанализируем алгоритм исправления этой ситуации по шагам.
Для того чтобы вернуть такие документы в корректное русло, необходимо использовать внешнюю обработку или запустить код в консоли кода со следующим алгоритмом:
Посмотрим на пример программной реализации этого алгоритма:
Выборка = Документы.ПередачаТоваровМеждуОрганизациями.Выбрать();
Пока Выборка.Следующий() Цикл
ДокОбъект = Выборка.ПолучитьОбъект();
// Ищем документы в некорректном состоянии
Если ДокОбъект.Проведен И ДокОбъект.ПометкаУдаления Тогда
Попытка
// Шаг A: Сбрасываем пометку удаления, записывая объект просто как проведенный
ДокОбъект.ПометкаУдаления = Ложь;
ДокОбъект.Записать(РежимЗаписиДокумента.Запись);
// Шаг B: Вызываем штатную отмену проведения для очистки регистров
ДокОбъект.Записать(РежимЗаписиДокумента.ОтменаПроведения);
// Шаг C: Устанавливаем пометку удаления стандартным безопасным методом
ДокОбъект.УстановитьПометкуУдаления(Истина);
Сообщить("Документ успешно исправлен: " + ДокОбъект.Ссылка);
Исключение
Сообщить("Ошибка исправления документа " + ДокОбъект.Ссылка + ": " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
Если документ уже распроведен (или даже помечен на удаление), но движения в физических таблицах базы данных все еще присутствуют (например, по регистру Резервы товаров организаций), можно прибегнуть к радикальному, но эффективному методу — программной очистке набора записей регистра с отбором по регистратору.
Рассмотрим пример кода для принудительной очистки движений конкретного документа по определенному регистру:
// Определяем очищаемый документ (ссылку)
СсылкаНаДокумент = Документы.ПередачаТоваровМеждуОрганизациями.НайтиПоРеквизиту("Номер", "0000-000001");
Если Не СсылкаНаДокумент.Пустая() Тогда
// Создаем набор записей нужного регистра с отбором по нашему документу
НаборЗаписей = РегистрыНакопления.РезервыТоваровОрганизаций.СоздатьНаборЗаписей();
НаборЗаписей.Отбор.Регистратор.Установить(СсылкаНаДокумент);
// Очищаем набор и записываем пустой набор в базу данных
НаборЗаписей.Очистить();
Попытка
НаборЗаписей.Записать(Истина); // Параметр Истина замещает существующие движения пустым набором
Сообщить("Движения документа " + СсылкаНаДокумент + " успешно очищены.");
Исключение
Сообщить("Не удалось очистить движения: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
Важное замечание: Применение этого метода требует осторожности. Перед запуском подобных обработок в рабочей базе обязательно сделайте резервную копию (бэкап) базы данных!
После программной очистки и приведения документов к единому логическому статусу крайне важно устранить возможные физические несоответствия на уровне СУБД. Для этого:
Очищать ссылки или Создавать объекты (в зависимости от ваших политик восстановления данных).Этот комплекс мер позволит полностью оздоровить базу данных, избавиться от «фантомных» записей в регистрах накопления и исключить ошибки при последующих расчетах себестоимости в «1С:Комплексная автоматизация».