К статье
Практический материал

Разработка и Конфигурация · 10 мин

Как программно пометить на удаление документ в 1С

Как программно пометить документ на удаление в 1С: методы УстановитьПометкуУдаления и ПолучитьОбъект, работа с проведёнными документами, права и типичные ошибки.

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

Ключевой момент: пометку нельзя установить на ссылку напрямую — нужно получить объект документа методом ПолучитьОбъект(), вызвать у него УстановитьПометкуУдаления() и при необходимости записать изменения. Ниже разобраны рабочие варианты кода, особенности для проведённых документов, контроль прав и типичные ошибки.

Основной способ: УстановитьПометкуУдаления

Стандартный сценарий выглядит так: у вас есть ссылка на документ (например, полученная запросом или из формы списка), вы получаете по ней объект и меняете пометку.

ДокументСсылка = Документы.РеализацияТоваровУслуг.НайтиПоНомеру("000001", ТекущаяДатаСеанса());

Если Не ДокументСсылка.Пустая() Тогда

ДокументОбъект = ДокументСсылка.ПолучитьОбъект();

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

КонецЕсли;

Метод УстановитьПометкуУдаления(Истина) устанавливает пометку, а УстановитьПометкуУдаления(Ложь) — снимает её. Второй параметр метода используется редко: он управляет тем, нужно ли автоматически отменять проведение, и в типовых сценариях достаточно одного аргумента.

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

Чтение текущего состояния пометки

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

Если ДокументСсылка.ПометкаУдаления Тогда

// документ уже помечен

КонецЕсли;

При массовой проверке эффективнее запрос: он не создаёт объектов вообще и позволяет отобрать сразу все помеченные или, наоборот, непомеченные документы.

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| Реализация.Ссылка

|ИЗ

| Документ.РеализацияТоваровУслуг КАК Реализация

|ГДЕ

| НЕ Реализация.ПометкаУдаления

| И Реализация.Дата < &ДатаОтсечки";

Запрос.УстановитьПараметр("ДатаОтсечки", ДобавитьМесяц(ТекущаяДатаСеанса(), -12));

Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл

ДокументОбъект = Выборка.Ссылка.ПолучитьОбъект();

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

КонецЦикла;

Особенности для проведённых документов

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

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

Обратная операция — снятие пометки — не восстанавливает проведение автоматически. После УстановитьПометкуУдаления(Ложь) документ останется непроведённым, и его нужно провести заново: ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение).

Пометка в транзакции и массовая обработка

При массовой пометке рекомендуется оборачивать операции в транзакцию — либо одну общую, либо порционную (например, по 100–500 документов). Единая транзакция на десятки тысяч документов может привести к длительным блокировкам и тайм-аутам на сервере СУБД.

НачатьТранзакцию();

Попытка

Пока Выборка.Следующий() Цикл

ДокументОбъект = Выборка.Ссылка.ПолучитьОбъект();

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

КонецЦикла;

ЗафиксироватьТранзакцию();

Исключение

ОтменитьТранзакцию();

ВызватьИсключение ОписаниеОшибки();

КонецПопытки;

Для больших объёмов в клиент-серверном варианте правильнее выносить обработку в фоновое задание, чтобы не блокировать сеанс пользователя. В управляемых формах для этого используются методы длительных операций БСП или ФоновыеЗадания.Выполнить.

Порядок действий для массовой пометки
  1. 1
    Сделайте резервную копию базы или работайте на копии
  2. 2
    Сформируйте запросом список ссылок с нужными отборами
  3. 3
    Проверьте список глазами: нет ли лишних документов
  4. 4
    Запустите цикл с ПолучитьОбъект() и УстановитьПометкуУдаления(Истина) в транзакции
  5. 5
    Проверьте результат выборкой по реквизиту ПометкаУдаления
  6. 6
    При необходимости выполните физическое удаление штатной обработкой

Права, блокировки и контроль ссылочной целостности

У пользователя, от имени которого выполняется код, должны быть права на изменение документа. Если прав не хватает, платформа выдаст ошибку нарушения прав доступа при записи. Также срабатывают даты запрета изменения данных: документ в закрытом периоде программно пометить не удастся без отключения или обхода контроля, что должно быть осознанным решением администратора.

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

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

Типичные ошибки
01
Вызов УстановитьПометкуУдаления у ссылки вместо объекта — метод есть только у объекта документа
02
Ожидание, что пометка сразу удалит документ — физическое удаление выполняется отдельной обработкой
03
Массовая пометка без транзакции и без логирования ошибок — при сбое состояние базы непредсказуемо
04
Игнорирование даты запрета изменения данных — обработка падает на закрытых периодах
05
Снятие пометки без повторного проведения — документ остаётся непроведённым и выпадает из отчётов

Альтернатива: непосредственное удаление

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

Во всех остальных случаях безопасная цепочка выглядит так: программная пометка → проверка результата → штатное удаление помеченных объектов с контролем целостности. Это дольше, но исключает появление битых ссылок в учётных данных.

Сравнение вариантов

УстановитьПометкуУдаления(Истина)

Штатный безопасный способ. Документ остаётся в базе, проверка ссылок — при физическом удалении. Подходит почти всегда.

Объект.Удалить()

Немедленное физическое удаление без контроля ссылок. Только для служебных сценариев с гарантией отсутствия ссылок.

Обработка «Удаление помеченных объектов»

Финальный этап: удаляет помеченные объекты с проверкой ссылочной целостности. Запускается вручную или регламентно.

Проверка результата

После выполнения обработки убедитесь, что пометка установлена именно на те документы, которые планировались. Самый простой способ — запрос по реквизиту ПометкаУдаления с теми же отборами, что использовались в обработке: количество помеченных должно совпасть с количеством обработанных.

Дополнительно проверьте, что проведённые документы действительно распровелись: у помеченного документа реквизит Проведен должен быть равен Ложь. Если обработка затрагивала регистры — сверьте контрольные остатки до и после, чтобы оценить влияние на учёт.

Контрольные точки

Как проверить результат

Реквизит ПометкаУдаления у обработанных ссылок
Норма

Равен Истина у всех документов из списка

Тревожный признак

Часть документов не помечена — смотрите журнал ошибок обработки

Реквизит Проведен
Норма

Ложь у всех помеченных проведённых ранее документов

Тревожный признак

Проведен = Истина у помеченного документа — возможна ошибка записи

Ссылки на документ из других объектов
Норма

Ссылки отсутствуют или известны и будут обработаны

Тревожный признак

Есть неучтённые ссылки — физическое удаление будет заблокировано

Часто задаваемые вопросы

Можно ли пометить документ на удаление без получения объекта?

Нет. Метод УстановитьПометкуУдаления существует только у объекта документа, поэтому вызов ПолучитьОбъект() обязателен. Читать текущее значение пометки через ссылку можно, а менять — только через объект.

Что происходит с движениями документа при установке пометки?

При пометке проведённого документа платформа автоматически отменяет проведение, и все движения по регистрам удаляются. Отдельно вызывать отмену проведения не нужно.

Как снять пометку на удаление программно?

Получите объект и вызовите УстановитьПометкуУдаления(Ложь). Учтите, что документ при этом не проведётся автоматически — если он был проведён, запишите его с режимом проведения отдельно.

Почему возникает ошибка при установке пометки в закрытом периоде?

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

Удалит ли пометка документ физически из базы?

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

Чем опасен метод Удалить() у объекта документа?

Метод удаляет документ немедленно и без проверки ссылок. Если на документ ссылаются другие объекты, в них останутся битые ссылки, что приведёт к ошибкам в отчётах и обработках. Используйте его только в служебных сценариях с гарантией отсутствия ссылок.

Итог

Что важно запомнить

Пометка на удаление устанавливается только через объект документа: ПолучитьОбъект() → УстановитьПометкуУдаления(Истина). Проведённый документ при этом распроводится автоматически. Массовую обработку выполняйте в транзакции, на копии базы, с логированием ошибок, а физическое удаление оставляйте штатной обработке с контролем ссылочной целостности.