Как очистить данные объекта в 1С:Предприятие
Содержание
Очистить объект в 1С можно пятью разными действиями, и путают их постоянно. Пометка на удаление, физическое удаление, затирание реквизита, обнуление движений регистра и очистка таблицы значений в коде — это пять не связанных операций. Выбрать не ту — значит либо не удалить ничего, либо снести то, на что ссылаются другие документы.
Ниже — где в интерфейсе ставить пометку и запускать удаление помеченных, как удалить объект программно с контролем ссылок и без него, как затереть движения в регистрах накопления и как очистить временные таблицы в запросе. И что делать с размером базы, который после удаления почему-то не уменьшился.
Любое массовое удаление делают на копии базы или после резервного копирования. Удаление помеченных и прямое Удалить() необратимы.
Удаление и очистка — это разные операции
Сначала разведём термины, потому что от этого зависит выбор инструмента.
- 🗑 Удаление объекта — объект (элемент справочника, документ) физически исчезает из базы. В 1С это двухшаговый безопасный процесс: сначала пометка на удаление, потом удаление помеченных с контролем ссылок.
- 🧹 Очистка данных — объект остаётся, но обнуляется его содержимое: затирается значение реквизита, удаляются строки табличной части, снимаются движения регистров.
- ✂️ Прямое удаление — объект удаляется сразу, без проверки ссылок. Применяется только в коде и только когда вы точно знаете, что на объект никто не ссылается.
Разница принципиальная. Если документ провёл движения и на него ссылаются регистры, его нельзя просто «удалить» — сначала снимают проведение, иначе в базе останутся висячие ссылки. Платформа защищает от этого контролем ссылочной целостности, но только при штатном удалении помеченных, а не при прямом Удалить().
| Способ | Где | Контроль ссылок | Обратимость |
|---|---|---|---|
| Пометка на удаление | интерфейс / код | — | снимается в один клик |
| Удаление помеченных | интерфейс | есть | необратимо |
Удалить() | только код | нет | необратимо |
| Очистка реквизита / строк | интерфейс / код | — | обратимо руками |
| Очистка движений регистра | интерфейс (проведение) / код | — | восстанавливается перепроведением |
Пометка на удаление и удаление помеченных через интерфейс
Штатный способ убрать элемент справочника или документ из базы — в два шага.
Шаг 1. Пометить на удаление. В списке или в форме объекта выделите строку и нажмите клавишу Del, либо в контекстном меню выберите пункт установки пометки удаления. У объекта появится значок перечёркнутого элемента. На этом этапе он ещё в базе и его видно во всех ссылках.
Шаг 2. Удалить помеченные. Запустите обработку Администрирование → Обслуживание → Удаление помеченных объектов. Если пункта не видно, откройте через Главное меню → Все функции → Стандартные → Удаление помеченных объектов — этот путь есть в любой конфигурации на управляемых формах.
Обработка работает в двух режимах:
- Автоматическое удаление — находит все помеченные объекты, проверяет ссылки и удаляет то, на что никто не ссылается.
- Выборочное удаление — вы сами отмечаете галочками, что именно удалить.
Если на помеченный объект кто-то ссылается, платформа покажет список «мест использования»: какие документы или справочники держат ссылку. Пока вы не уберёте пометку с этих объектов или не перепривяжете ссылки, удаление не пройдёт — это и есть контроль ссылочной целостности, который спасает базу от битых ссылок.
Пометку удобно ставить сразу на группу: в списке выделите несколько строк мышью с зажатым Ctrl или Shift и нажмите Del — пометка встанет на все выделенные объекты разом. Снимается она так же — повторным нажатием Del на помеченной строке.
Перед нажатием «Удалить» в режиме выборочного удаления разверните дерево связей и прочитайте, что именно хочет удалить платформа заодно с вашим объектом. Иногда в зависимостях оказывается нужный документ.
Удаление объектов программно: с контролем ссылок и без
В обработках и в фоновых заданиях удаление пишут кодом. Два метода — две степени риска.
Пометить на удаление программно (безопасно, удаление произойдёт потом штатной обработкой):
Элемент = Справочники.Номенклатура.НайтиПоКоду("00-0001").ПолучитьОбъект();
Элемент.ПометитьНаУдаление(Истина);
Прямое удаление (сразу и без проверки ссылок):
Объект = Ссылка.ПолучитьОбъект();
Объект.Удалить();
Удалить() не проверяет, ссылается ли кто-то на объект. После него в других документах могут остаться ссылки на несуществующий объект — в формах они отображаются как «<Объект не найден>». Поэтому прямое удаление допустимо только когда вы сами гарантировали отсутствие ссылок.
Выборка объектов запросом перед удалением
Чтобы удалить группу объектов по условию, список отбирают запросом, а затем удаляют в цикле. Запросом удалить нельзя — язык запросов только читает данные.
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Таблица.Ссылка КАК Ссылка
|ИЗ
| Справочник.Номенклатура КАК Таблица
|ГДЕ
| Таблица.ПометкаУдаления";
Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
Объект = Выборка.Ссылка.ПолучитьОбъект();
Объект.Удалить();
КонецЦикла;
В этом примере отбираются уже помеченные элементы, из каждой ссылки получается объект и удаляется. Такой цикл в рабочей базе выполняют только в монопольном или заведомо спокойном режиме — иначе чужие сеансы будут натыкаться на удаляемые объекты.
Удаление может упасть на любом объекте — например, если его уже удалил другой сеанс или он заблокирован. Чтобы цикл не прерывался на первой же ошибке, каждую итерацию оборачивают в Попытка:
Пока Выборка.Следующий() Цикл
Попытка
Выборка.Ссылка.ПолучитьОбъект().Удалить();
Исключение
Сообщить("Не удалён: " + Выборка.Ссылка + " — " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
На больших объёмах удаляйте порциями по несколько тысяч объектов, а не всё одним заходом: длинная транзакция держит блокировки и раздувает журнал регистрации. После каждой порции делайте паузу или фиксируйте результат.
Очистка реквизита и табличной части
Очистить отдельный реквизит объекта — значит присвоить ему пустое значение, а потом записать объект:
Объект.Комментарий = "";
Объект.Контрагент = Справочники.Контрагенты.ПустаяСсылка();
Объект.Записать();
Строки табличной части затирает метод Очистить():
Объект.Товары.Очистить();
Очистка движений в регистрах накопления
Остатки и обороты в регистрах накопления формируют документы при проведении. Поэтому очистить движения можно двумя путями.
Через интерфейс — отменой проведения. Откройте документ, снимите проведение (команда снятия проведения в форме). Движения по всем регистрам удалятся автоматически. Это обратимо: перепроведёте документ — движения вернутся.
Кодом — через набор записей. Когда нужно снять движения конкретного регистратора, не трогая сам документ, создают пустой набор записей с отбором по регистратору и записывают его:
Набор = РегистрыНакопления.ТоварыНаСкладах.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(ДокументСсылка);
Набор.Записать();
Пустой набор с отбором замещает собой все записи регистратора — то есть стирает их. Если нужно сначала прочитать, а потом очистить в памяти:
Набор.Прочитать();
Набор.Очистить();
Набор.Записать();
Прямое затирание движений в обход проведения рассинхронизирует документ и его записи. После такой операции отчёты по остаткам покажут не то, что в документе. Применяйте только при осознанном исправлении данных, а не вместо снятия проведения.
Срезы последних и первых — это не хранимые таблицы, а виртуальные таблицы регистра сведений, которые платформа строит на лету из его записей. Их не чистят отдельно: чтобы изменился срез, меняют сами записи регистра сведений тем же набором записей.
С регистрами сведений есть нюанс: они бывают подчинённые регистратору и независимые. У подчинённого записи, как и у регистра накопления, привязаны к документу — чистятся отбором по регистратору. У независимого регистратора нет, отбор ставят по его измерениям:
Набор = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
Набор.Отбор.Номенклатура.Установить(ТоварСсылка);
Набор.Записать();
Пустой набор с таким отбором сотрёт все записи цен по этой номенклатуре, не затрагивая остальные.
Очистка таблиц значений, массивов и временных таблиц
Здесь речь не о базе, а об объектах в памяти во время работы кода.
Таблица значений, массив, список, соответствие очищаются одноимённым методом — он удаляет все элементы, оставляя саму структуру:
ТаблицаТоваров.Очистить(); // строки удалены, колонки остались
Массив.Очистить();
Соответствие.Очистить();
Чтобы убрать и описание колонок таблицы значений, отдельно чистят коллекцию колонок: ТаблицаТоваров.Колонки.Очистить().
Временные таблицы запроса живут в менеджере временных таблиц. Их удаляют оператором УНИЧТОЖИТЬ в пакетном запросе либо закрытием менеджера:
Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
// ... запрос с ПОМЕСТИТЬ ВремТовары ...
Запрос.Текст = "УНИЧТОЖИТЬ ВремТовары";
Запрос.Выполнить();
// либо разом все таблицы менеджера:
Запрос.МенеджерВременныхТаблиц.Закрыть();
Закрыть() уничтожает все временные таблицы менеджера и освобождает память. Если менеджер не закрыть явно, таблицы освободятся сами при уничтожении объекта, но в длинных обработках лучше закрывать вручную, чтобы не держать данные зря.
В пакетном запросе временную таблицу удобно уничтожать сразу после последнего пакета, который её использует, — так память не распухает на больших выборках.
Что делать с размером базы после удаления
Типичная ловушка: удалили помеченные объекты, а файл базы остался прежнего размера. Так и должно быть — платформа не уменьшает физический размер хранилища автоматически.
Для файловой базы (.1CD) порядок такой:
- Завершите все сеансы — файловую базу сжимают монопольно.
- Запустите
Конфигуратор → Администрирование → Тестирование и исправление. - Отметьте пункт сжатия таблиц информационной базы и выполните проверку.
Сжатие физически уменьшает файл за счёт освободившегося после удаления места.
Для клиент-серверной базы на СУБД размер таблиц так не возвращается — пустое место внутри таблиц остаётся занятым на уровне сервера баз данных. Освобождение места — это задача администратора СУБД (перестроение индексов, сжатие на стороне сервера), и делается оно штатными средствами самой СУБД, а не из 1С. Из конфигуратора на серверной базе Тестирование и исправление чинит логику данных и пересоздаёт таблицы при реструктуризации, но файл базы данных на диске сам по себе не ужимает.
Отдельно стоит журнал регистрации. Удаление объектов его не трогает — все записи о действиях пользователей остаются и могут занимать больше самой базы. Если место на диске съел именно журнал, его сокращают в конфигураторе: Администрирование → Настройка журнала регистрации, где задаётся глубина хранения, и отдельной командой сокращения журнала до указанной даты. Это не влияет на учётные данные, только на историю событий.
Тестирование и исправление останавливает работу пользователей и может идти долго на большой базе. Запускайте в нерабочее время и только с актуальной резервной копией.
Перед массовой очисткой пройдитесь по короткому списку — он убережёт от необратимых ошибок:
Типичные ошибки при очистке данных
Ошибки здесь стоят дорого, потому что почти всё необратимо.
- ❌ Прямое
Удалить()вместо пометки. Без контроля ссылок в базе появляются битые ссылки «<Объект не найден>». Если не уверены в связях — только пометка и штатное удаление помеченных. - ❌ Затирание движений вместо снятия проведения. Документ и его записи расходятся, отчёты врут. Для обычной отмены движений снимайте проведение документа.
- ❌ Ожидание, что база сразу похудеет. После удаления помеченных размер не падает сам: файловую сжимают через
Тестирование и исправление, серверную — средствами СУБД. - ❌ Массовое удаление в рабочее время. Цикл удаления в живой базе конфликтует с чужими сеансами и блокировками. Делайте в монополии или когда никто не работает .
- ❌ Удаление без резервной копии. Отменить
Удалить()и удаление помеченных нечем, кроме как восстановлением из бэкапа.
Частые вопросы
Можно ли отменить удаление помеченных объектов?
Чем `ПометитьНаУдаление(Истина)` отличается от `Удалить()`?
ПометитьНаУдаление только ставит пометку — объект остаётся в базе, удаление произойдёт позже штатной обработкой с контролем ссылок. Удалить() стирает объект сразу и без проверки ссылок.Как очистить движения документа, не удаляя сам документ?
Почему после удаления данных база не уменьшилась в размере?
Как удалить сразу много помеченных объектов из кода?
ПометкаУдаления, в цикле получите объект через ПолучитьОбъект() и вызовите Удалить(). Запускайте в монопольном режиме и после резервного копирования.