Разработка и Конфигурация · 11 мин
Как программно пометить объект на удаление в 1С
Как программно установить и снять пометку удаления в 1С: метод УстановитьПометкуУдаления, работа со ссылками, контроль ссылочной целостности, примеры кода и типичные ошибки.
Пометка на удаление — штатный механизм 1С, который не стирает данные физически, а лишь фиксирует намерение удалить объект. Программно это делается одним методом — УстановитьПометкуУдаления(), вызываемым у объекта (не у ссылки). Физическое удаление выполняется отдельно — через обработку «Удаление помеченных объектов» или метод УдалитьОбъекты.
Разница между «пометить» и «удалить» принципиальна: помеченный объект остаётся в базе, его можно восстановить, а ссылки на него продолжают работать. Поэтому пометка — безопасный способ подготовить данные к чистке, особенно в рабочих базах, где ошибка с физическим удалением необратима.
Ниже разобраны: синтаксис метода, работа со ссылками и объектами, пометка документов и справочников, снятие пометки, контроль ссылочной целостности и типичные ошибки разработчиков.
Как работает пометка на удаление в 1С
Каждый ссылочный объект (справочник, документ, план видов характеристик и т.д.) имеет служебный реквизит ПометкаУдаления типа «Булево». Когда реквизит установлен в Истина, платформа визуально вычёркивает объект в списках, исключает его из стандартных подборов, но хранит в таблицах базы данных.
Пометка не блокирует объект полностью: проведённые документы при пометке отменяют проведение (если используется штатная обработка), движения по регистрам удаляются, но сам документ и ссылки на него остаются. Это позволяет безопасно «отключить» данные, не разрушая целостность базы.
Физическое удаление — отдельный этап. Платформа проверяет, нет ли в базе ссылок на помеченный объект, и удаляет только те объекты, на которые никто не ссылается (либо все подряд в режиме без контроля, что опасно).
Базовый синтаксис: метод УстановитьПометкуУдаления
Метод вызывается у объектного значения, а не у ссылки. Типовой код выглядит так:
ОбъектЭлемент = СсылкаНаЭлемент.ПолучитьОбъект();
ОбъектЭлемент.УстановитьПометкуУдаления(Истина);
Параметр метода: Истина — установить пометку, Ложь — снять её. Метод сам записывает объект, отдельный вызов Записать() не требуется.
Для документов метод имеет второй необязательный параметр — режим отмены проведения. Если документ проведён, платформа по умолчанию отменит проведение при установке пометки:
ДокОбъект = СсылкаНаДокумент.ПолучитьОбъект();
ДокОбъект.УстановитьПометкуУдаления(Истина); // проведение отменится автоматически
Типовая ошибка новичков — попытка вызвать метод у ссылки: Ссылка.УстановитьПометкуУдаления(Истина) вызовет ошибку, потому что у объекта типа «СправочникСсылка» такого метода нет. Сначала обязательно получаем объект.
// Пометить элемент справочника на удаление
ЭлементОбъект = СсылкаНаЭлемент.ПолучитьОбъект();
ЭлементОбъект.УстановитьПометкуУдаления(Истина);
// Снять пометку
ЭлементОбъект = СсылкаНаЭлемент.ПолучитьОбъект();
ЭлементОбъект.УстановитьПометкуУдаления(Ложь);Как пометить объект по ссылке или из запроса
На практике чаще всего нужно пометить не один известный объект, а набор, отобранный по условию. Стандартная схема — запрос для получения ссылок и цикл с установкой пометки:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|ГДЕ
| НЕ Номенклатура.ПометкаУдаления
| И Номенклатура.ЭтоГруппа = ЛОЖЬ";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
ЭлементОбъект = Выборка.Ссылка.ПолучитьОбъект();
ЭлементОбъект.УстановитьПометкуУдаления(Истина);
КонецЦикла;
При массовой обработке имеет смысл выполнять пометку в транзакции или хотя бы пакетами, чтобы при сбое не получить частично обработанный набор. Также полезно предварительно фильтровать уже помеченные объекты (НЕ ПометкаУдаления), чтобы не выполнять лишние записи.
Для очень больших объёмов (сотни тысяч элементов) учитывайте, что ПолучитьОбъект() и запись каждого элемента — это отдельные обращения к базе. На клиент-серверных базах такая обработка может идти долго; запускайте её в фоновом задании и в нерабочее время.
- 1Сформируйте запрос, отбирающий ссылки на нужные объекты
- 2Исключите в запросе уже помеченные элементы (НЕ ПометкаУдаления)
- 3В цикле получайте объект через Ссылка.ПолучитьОбъект()
- 4Вызовите УстановитьПометкуУдаления(Истина) для каждого объекта
- 5Проверьте результат запросом по реквизиту ПометкаУдаления
- 6Выполните физическое удаление штатной обработкой с контролем ссылок
Особенности для разных типов объектов
Документы
При пометке проведённого документа платформа отменяет проведение и очищает движения по регистрам. Если документ участвует в последовательностях, граница последовательности может сместиться — учитывайте это при пометке документов за закрытые периоды.
Справочники с иерархией и владельцами
Пометка родительской группы не помечает автоматически вложенные элементы — их нужно обрабатывать отдельно. Подчинённые справочники (с владельцем) тоже помечаются самостоятельно, если только это не предусмотрено логикой конфигурации.
Предопределённые элементы
Предопределённые элементы справочников и планов счетов штатно не удаляются — платформа блокирует их пометку в типовых конфигурациях и при физическом удалении. Программно пометить их можно, но физически удалить штатными средствами не получится, а попытки обойти ограничение ломают код, обращающийся к предопределённым именам.
Снятие пометки и восстановление объекта
Пока объект не удалён физически, пометку можно снять тем же методом с параметром Ложь:
ЭлементОбъект = СсылкаНаЭлемент.ПолучитьОбъект();
ЭлементОбъект.УстановитьПометкуУдаления(Ложь);
Для документа после снятия пометки проведение не восстанавливается автоматически — документ останется непроведённым, и его нужно провести заново, если это требуется. Это частая причина «пропавших» оборотов в отчётах после восстановления документов.
Проверить текущее состояние пометки можно без получения объекта — прямо по ссылке: Ссылка.ПометкаУдаления. Это быстрый способ отбора, не создающий объект в памяти.
Физическое удаление и контроль ссылочной целостности
Штатный путь — обработка «Удаление помеченных объектов» (в типовых конфигурациях: раздел «Администрирование» → «Обслуживание»). Она работает в двух режимах: автоматическое удаление всех помеченных объектов и выборочное удаление с просмотром. Обработка показывает, какие объекты не могут быть удалены из-за ссылок на них, и где именно эти ссылки находятся.
Программно удаление выполняется методом глобального контекста УдалитьОбъекты(МассивСсылок, ПроверятьСсылки). Второй параметр определяет, проверять ли ссылочную целостность. Режим без проверки (Ложь) создаёт в базе «битые ссылки» — значения вида «Объект не найден», которые ломают отчёты и обмены.
Безопасная последовательность для рабочей базы: сначала пометить объекты, дать пользователям поработать несколько дней (пометку всегда можно снять), затем выполнить удаление с контролем ссылок и разобрать объекты, которые не удалились.
Типичные ошибки и ограничения
Самые частые проблемы при программной пометке связаны с непониманием объектной модели платформы и с правами доступа.
Ещё одно ограничение — обмены данными. В базах, участвующих в РИБ или обменах через планы обмена, пометка на удаление регистрируется как изменение и уходит в другие узлы. Физическое удаление объектов, уже отправленных в обмен, может привести к рассинхронизации, поэтому чистку в распределённых системах планируют отдельно.
Наконец, пометка не освобождает место в базе: физический размер таблиц уменьшится только после удаления помеченных объектов и, для некоторых СУБД, после реорганизации таблиц.
Как проверить результат
Все целевые объекты имеют ПометкаУдаления = Истина
Часть объектов не помечена — проверьте права и условия отбора
Документы непроведённые, движения отсутствуют
Движения остались — проведение не было отменено, проверьте логику
Объекты удалены или показан список ссылок, мешающих удалению
Массовые ошибки удаления без диагностики — вероятно, отключён контроль ссылок
FAQ
Можно ли пометить объект на удаление без получения объекта, только по ссылке?
Нет, штатного метода у ссылки нет — ПолучитьОбъект() обязателен. Альтернатива для массовых операций — прямая запись в таблицы средствами СУБД, но это неподдерживаемый и опасный путь, нарушающий лицензионные ограничения и логику платформы.
Чем УстановитьПометкуУдаления отличается от метода Удалить()?
УстановитьПометкуУдаления ставит признак, объект остаётся в базе и восстановим. Метод Удалить() у объекта удаляет запись физически и сразу, без контроля ссылок — после него все ссылки на объект превращаются в «Объект не найден». В рабочих базах Удалить() применять не рекомендуется.
Почему после снятия пометки документ не появился в отчётах?
Потому что при пометке было отменено проведение, а снятие пометки его не восстанавливает. Найдите документ и проведите его заново — движения и данные отчётов вернутся.
Как пометить все элементы группы справочника вместе с подгруппами?
Используйте в запросе условие иерархии: Ссылка В ИЕРАРХИИ(&Группа). Запрос вернёт саму группу, все вложенные группы и элементы, после чего в цикле установите пометку каждому объекту.
Объект помечен, но не удаляется обработкой «Удаление помеченных объектов». Что делать?
Обработка показывает список мест использования — объектов, ссылающихся на удаляемый. Откройте их, замените или очистите ссылки (либо пометьте ссылающиеся объекты тоже), затем повторите удаление.
Нужны ли особые права для программной пометки?
Да. У пользователя должны быть права на изменение объекта и на пометку удаления (роли с правами «Удаление»/«Интерактивная пометка удаления» для соответствующего вида объектов). При их отсутствии код завершится ошибкой нарушения прав доступа.
Что важно запомнить
Пометка ставится методом УстановитьПометкуУдаления(Истина) у объекта, полученного через ПолучитьОбъект(); снимается тем же методом с Ложь. Физическое удаление — отдельный этап с контролем ссылочной целостности. Перед массовыми операциями делайте резервную копию, а в рабочих базах сначала помечайте, давайте время на проверку и только потом удаляйте.