Как удалить помеченные на удаление объекты в закрытом периоде без перепроведения базы

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

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

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

Причина возникновения проблемы

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

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

Для решения нашей задачи нам нужно научиться обходить эти механизмы в исключительных случаях.

Способ 1. Использование режима загрузки данных (программный метод)

Самый надежный способ внести изменения в документ закрытого периода без последствий — это использование свойства ОбменДанными.Загрузка. Рассмотрим подробнее этот механизм. Когда мы устанавливаем этот флаг в значение Истина перед записью объекта, платформа отключает большинство проверок, включая проверку даты запрета и автоматическую регистрацию изменений в последовательностях.

Рассмотрим пример кода, который очищает ссылку на удаляемый объект в документе «Списание с расчетного счета», не затрагивая границы периода:


// СсылкаНаДокумент - это документ, который ссылается на удаляемый объект
ОбъектДокумента = СсылкаНаДокумент.ПолучитьОбъект();

// Очищаем реквизит, который содержит ссылку на помеченный объект
// Например, это может быть ДокументОснование или Сделка
ОбъектДокумента.ДокументОснование = Неопределено;

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

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

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

Способ 2. Применение специализированных обработок

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

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

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

Способ 3. Прямое удаление без контроля ссылок (Крайний метод)

Существует метод платформы Удалить(), который физически удаляет запись из таблицы базы данных, игнорируя наличие ссылок в других документах. Посмотрим на этот процесс критически: если вы удалите «Поступление», на которое ссылается «Списание», то в «Списании» в поле ссылки появится надпись <Объект не найден>....

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

Способ 4. Исправление статуса регламентных операций

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

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

Рассмотрим, как изменить состояние операции программно:


МенеджерЗаписи = РегистрыСведений.СостояниеРегламентныхОпераций.СоздатьМенеджерЗаписи();
МенеджерЗаписи.Период = ДатаЗакрытогоПериода;
МенеджерЗаписи.Организация = НашаОрганизация;
МенеджерЗаписи.РегламентнаяОперация = СсылкаНаОперацию; // Например, ПересчетИтогов
МенеджерЗаписи.Прочитать();

Если МенеджерЗаписи.Выбран() Тогда
    МенеджерЗаписи.Состояние = Перечисления.СостоянияРегламентныхОпераций.Выполнено;
    МенеджерЗаписи.Записать();
КонецЕсли;

Рекомендации по выполнению работ

При выполнении подобных манипуляций мы рекомендуем придерживаться строгого регламента:

  1. Всегда делайте архивную копию базы данных перед любыми программными изменениями в закрытых периодах.
  2. Сначала протестируйте очистку ссылки на одном документе и убедитесь, что в мониторе закрытия месяца статус периода не изменился.
  3. Используйте метод с ОбменДанными.Загрузка = Истина как основной и наиболее безопасный для платформы 1С.
  4. Если удаляемых объектов много, напишите небольшую обработку, которая будет обходить массив помеченных объектов, искать ссылки на них через НайтиПоСсылкам() и очищать их в режиме загрузки.

Таким образом, мы выяснили, что удаление объектов в закрытых периодах без перепроведения вполне возможно. Главное — использовать специализированные инструменты записи объектов, которые позволяют обходить стандартную бизнес-логику системы, предназначенную для обычных пользователей.

← На главную