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