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

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

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

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

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

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

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

Два принципиально разных способа удаления в 1С

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

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

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

Пометка на удаление через УстановитьПометкуУдаления

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

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

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

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

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

КонецЕсли;

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

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

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

Непосредственное удаление методом Удалить()

Метод Удалить() объекта удаляет запись из базы физически, минуя этап пометки. Этот метод не выполняет проверку ссылочной целостности — платформа просто удаляет строку из таблицы, а все существующие ссылки на объект превращаются в битые.

ЭлементСправочника = Справочники.Номенклатура.НайтиПоКоду("ТСТ-001");

Если Не ЭлементСправочника.Пустая() Тогда

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

СпрОбъект.Удалить();

КонецЕсли;

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

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

Проверка ссылок перед удалением

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

МассивСсылок = Новый Массив;

МассивСсылок.Добавить(ЭлементСправочника);

НайденныеСсылки = НайтиПоСсылкам(МассивСсылок);

Если НайденныеСсылки.Количество() = 0 Тогда

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

СпрОбъект.Удалить();

Иначе

Сообщить("Объект используется в " + НайденныеСсылки.Количество() + " местах, удаление отменено");

КонецЕсли;

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

Физическое удаление помеченных объектов

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

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

// Выполняется на сервере, требуются права администратора

УдалитьПомеченныеОбъекты();

Объекты, на которые есть ссылки, платформа не удалит — они останутся помеченными. Это нормальное поведение: чтобы удалить цепочку связанных объектов, нужно пометить на удаление все связанные элементы, либо сначала очистить ссылки в ссылающихся объектах.

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

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

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

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

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

Типичные ошибки и ограничения

Частая ошибка — вызов Удалить() у ссылки вместо объекта. Ссылка — это только идентификатор; методы удаления доступны у объекта, полученного через ПолучитьОбъект(). Вызов метода у ссылки вызовет ошибку исполнения.

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

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

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

Проверка результата и откат изменений

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

Откатить пометку на удаление просто: УстановитьПометкуУдаления(Ложь). Откатить физическое удаление штатными средствами невозможно — только восстановление из резервной копии. Поэтому перед любой массовой операцией удаления делайте выгрузку базы (dt) или снапшот на стороне СУБД.

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

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

Поиск объекта по ссылке после удаления
Норма

Ссылка не найдена, Пустая() возвращает Истину

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

Объект по-прежнему открывается — удаление не выполнено

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

НайтиПоСсылкам() возвращает пустую таблицу

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

В документах отображается «Объект не найден»

Пометка удаления у документа
Норма

ПометкаУдаления = Истина, проведение снято

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

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

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

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

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

Почему УдалитьПомеченныеОбъекты() не удаляет часть объектов?

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

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

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

Можно ли удалить объект без прав администратора?

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

Что делать, если после удаления появились записи «Объект не найден»?

Это битые ссылки — следствие прямого удаления без проверки. Нужно найти все места через НайтиПоСсылкам() (по сохранившейся ссылке из журнала, если она известна) или запустить тестирование и исправление базы с проверкой ссылочной целостности, затем очистить или заменить битые ссылки обработкой.

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

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

Итог

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

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