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

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

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

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

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

Во встроенном языке 1С для этого используется метод УстановитьПометкуУдаления(), которому передаётся значение Ложь. Метод доступен у объектов типа «СправочникОбъект», «ДокументОбъект», «ПланСчетовОбъект» и других прикладных объектов, а также у наборов записей регистров. Важно понимать различие: работа идёт с объектом, полученным через ПолучитьОбъект(), а не со ссылкой — у ссылки метода установки пометки нет.

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

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

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

Базовый код: снятие пометки с одного объекта

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

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

Если ОбъектСправочника <> Неопределено Тогда

ОбъектСправочника.УстановитьПометкуУдаления(Ложь);

КонецЕсли;

Проверка на Неопределено обязательна: если ссылка «битая» (объект физически удалён), ПолучитьОбъект() вернёт Неопределено, и обращение к методу вызовет ошибку. Для документов код аналогичен — отличается только тип ссылки.

Если пометку нужно снять у набора записей регистра сведений, логика та же: формируется набор записей с отбором, вызывается УстановитьПометкуУдаления(Ложь). У независимых регистров сведений пометка удаления используется редко, но метод доступен.

Массовое снятие пометки через запрос

Типовая задача — восстановить все помеченные элементы конкретного справочника или документы за период. Сначала запросом выбираются ссылки с условием по реквизиту ПометкаУдаления, затем каждая ссылка обрабатывается в цикле.

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

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

"ВЫБРАТЬ

| Номенклатура.Ссылка КАК Ссылка

|ИЗ

| Справочник.Номенклатура КАК Номенклатура

|ГДЕ

| Номенклатура.ПометкаУдаления = ИСТИНА";

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

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

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

Если Объект <> Неопределено Тогда

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

КонецЕсли;

КонецЦикла;

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

bsl
НачатьТранзакцию();
Попытка
    Пока Выборка.Следующий() Цикл
        Объект = Выборка.Ссылка.ПолучитьОбъект();
        Если Объект <> Неопределено Тогда
            Объект.УстановитьПометкуУдаления(Ложь);
        КонецЕсли;
    КонецЦикла;
    ЗафиксироватьТранзакцию();
Исключение
    ОтменитьТранзакцию();
    ВызватьИсключение;
КонецПопытки;

Особенности для разных типов объектов

Справочники с иерархией и владельцами

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

Документы и проведение

Снятие пометки удаления с документа не восстанавливает его проведение автоматически. После снятия пометки документ остаётся непроведённым, и движения по регистрам отсутствуют. Если требуется вернуть документ в рабочее состояние, после УстановитьПометкуУдаления(Ложь) вызовите Записать(РежимЗаписиДокумента.Проведение) — но только если это действительно нужно по смыслу учёта.

Планы обмена и задачи

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

Права доступа и привилегированный режим

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

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

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

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

После выполнения обработки убедитесь, что пометка действительно снята. Самый надёжный способ — повторный запрос с условием ПометкаУдаления = ИСТИНА: он должен вернуть пустой результат (или только те объекты, которые сознательно оставлены помеченными). Дополнительно откройте несколько объектов в пользовательском режиме и проверьте, что они доступны для редактирования и отображаются без значка пометки.

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

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

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

Запрос по реквизиту ПометкаУдаления
Норма

Выборка помеченных объектов пуста

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

Объекты остались помеченными — возможны ошибки прав или прерывание цикла

Состояние документов
Норма

Документы проведены, движения на месте

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

Документы непроведённые — нужна отдельная запись с проведением

Журнал регистрации
Норма

Нет ошибок записи за время обработки

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

Ошибки отказа в доступе или конфликт блокировок

Альтернативы программному способу

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

Итог

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

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

Частые вопросы

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

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

Что делать, если ПолучитьОбъект() возвращает Неопределено?

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

Снимается ли пометка с подчинённых элементов автоматически?

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

Почему после снятия пометки документ не отражается в отчётах?

Потому что снятие пометки не восстанавливает проведение. Документ становится обычным непроведённым документом без движений. Чтобы он снова участвовал в учёте, запишите его с режимом проведения: Записать(РежимЗаписиДокумента.Проведение).

Можно ли выполнить снятие пометки в фоновом задании?

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

Сработают ли подписки на события при программном снятии пометки?

Да, УстановитьПометкуУдаления инициирует запись объекта, поэтому обработчики ПередЗаписью и ПриЗаписи выполняются. Если в них есть тяжёлая логика или обращения к связанным данным, массовая обработка может существенно замедлиться — это стоит учитывать при оценке времени выполнения.