Как очистить данные объекта в 1С:Предприятие

· 9 мин

Содержание

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

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

Любое массовое удаление делают на копии базы или после резервного копирования. Удаление помеченных и прямое Удалить() необратимы.

Удаление и очистка — это разные операции

Сначала разведём термины, потому что от этого зависит выбор инструмента.

  • 🗑 Удаление объекта — объект (элемент справочника, документ) физически исчезает из базы. В 1С это двухшаговый безопасный процесс: сначала пометка на удаление, потом удаление помеченных с контролем ссылок.
  • 🧹 Очистка данных — объект остаётся, но обнуляется его содержимое: затирается значение реквизита, удаляются строки табличной части, снимаются движения регистров.
  • ✂️ Прямое удаление — объект удаляется сразу, без проверки ссылок. Применяется только в коде и только когда вы точно знаете, что на объект никто не ссылается.

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

СпособГдеКонтроль ссылокОбратимость
Пометка на удалениеинтерфейс / код—снимается в один клик
Удаление помеченныхинтерфейсестьнеобратимо
Удалить()только коднетнеобратимо
Очистка реквизита / строкинтерфейс / код—обратимо руками
Очистка движений регистраинтерфейс (проведение) / код—восстанавливается перепроведением

Пометка на удаление и удаление помеченных через интерфейс

Штатный способ убрать элемент справочника или документ из базы — в два шага.

Шаг 1. Пометить на удаление. В списке или в форме объекта выделите строку и нажмите клавишу Del, либо в контекстном меню выберите пункт установки пометки удаления. У объекта появится значок перечёркнутого элемента. На этом этапе он ещё в базе и его видно во всех ссылках.

Шаг 2. Удалить помеченные. Запустите обработку Администрирование → Обслуживание → Удаление помеченных объектов. Если пункта не видно, откройте через Главное меню → Все функции → Стандартные → Удаление помеченных объектов — этот путь есть в любой конфигурации на управляемых формах.

Обработка работает в двух режимах:

  1. Автоматическое удаление — находит все помеченные объекты, проверяет ссылки и удаляет то, на что никто не ссылается.
  2. Выборочное удаление — вы сами отмечаете галочками, что именно удалить.

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

Пометку удобно ставить сразу на группу: в списке выделите несколько строк мышью с зажатым Ctrl или Shift и нажмите Del — пометка встанет на все выделенные объекты разом. Снимается она так же — повторным нажатием Del на помеченной строке.

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

Удаление объектов программно: с контролем ссылок и без

В обработках и в фоновых заданиях удаление пишут кодом. Два метода — две степени риска.

Пометить на удаление программно (безопасно, удаление произойдёт потом штатной обработкой):

Элемент = Справочники.Номенклатура.НайтиПоКоду("00-0001").ПолучитьОбъект();
Элемент.ПометитьНаУдаление(Истина);

Прямое удаление (сразу и без проверки ссылок):

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

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

Выборка объектов запросом перед удалением

Чтобы удалить группу объектов по условию, список отбирают запросом, а затем удаляют в цикле. Запросом удалить нельзя — язык запросов только читает данные.

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
|    Таблица.Ссылка КАК Ссылка
|ИЗ
|    Справочник.Номенклатура КАК Таблица
|ГДЕ
|    Таблица.ПометкаУдаления";

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    Объект = Выборка.Ссылка.ПолучитьОбъект();
    Объект.Удалить();
КонецЦикла;

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

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

Пока Выборка.Следующий() Цикл
    Попытка
        Выборка.Ссылка.ПолучитьОбъект().Удалить();
    Исключение
        Сообщить("Не удалён: " + Выборка.Ссылка + " — " + ОписаниеОшибки());
    КонецПопытки;
КонецЦикла;

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

Очистка реквизита и табличной части

Очистить отдельный реквизит объекта — значит присвоить ему пустое значение, а потом записать объект:

Объект.Комментарий = "";
Объект.Контрагент = Справочники.Контрагенты.ПустаяСсылка();
Объект.Записать();

Строки табличной части затирает метод Очистить():

Объект.Товары.Очистить();

Очистка движений в регистрах накопления

Остатки и обороты в регистрах накопления формируют документы при проведении. Поэтому очистить движения можно двумя путями.

Через интерфейс — отменой проведения. Откройте документ, снимите проведение (команда снятия проведения в форме). Движения по всем регистрам удалятся автоматически. Это обратимо: перепроведёте документ — движения вернутся.

Кодом — через набор записей. Когда нужно снять движения конкретного регистратора, не трогая сам документ, создают пустой набор записей с отбором по регистратору и записывают его:

Набор = РегистрыНакопления.ТоварыНаСкладах.СоздатьНаборЗаписей();
Набор.Отбор.Регистратор.Установить(ДокументСсылка);
Набор.Записать();

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

Набор.Прочитать();
Набор.Очистить();
Набор.Записать();

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

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

С регистрами сведений есть нюанс: они бывают подчинённые регистратору и независимые. У подчинённого записи, как и у регистра накопления, привязаны к документу — чистятся отбором по регистратору. У независимого регистратора нет, отбор ставят по его измерениям:

Набор = РегистрыСведений.ЦеныНоменклатуры.СоздатьНаборЗаписей();
Набор.Отбор.Номенклатура.Установить(ТоварСсылка);
Набор.Записать();

Пустой набор с таким отбором сотрёт все записи цен по этой номенклатуре, не затрагивая остальные.

Очистка таблиц значений, массивов и временных таблиц

Здесь речь не о базе, а об объектах в памяти во время работы кода.

Таблица значений, массив, список, соответствие очищаются одноимённым методом — он удаляет все элементы, оставляя саму структуру:

ТаблицаТоваров.Очистить();   // строки удалены, колонки остались
Массив.Очистить();
Соответствие.Очистить();

Чтобы убрать и описание колонок таблицы значений, отдельно чистят коллекцию колонок: ТаблицаТоваров.Колонки.Очистить().

Временные таблицы запроса живут в менеджере временных таблиц. Их удаляют оператором УНИЧТОЖИТЬ в пакетном запросе либо закрытием менеджера:

Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
// ... запрос с ПОМЕСТИТЬ ВремТовары ...

Запрос.Текст = "УНИЧТОЖИТЬ ВремТовары";
Запрос.Выполнить();

// либо разом все таблицы менеджера:
Запрос.МенеджерВременныхТаблиц.Закрыть();

Закрыть() уничтожает все временные таблицы менеджера и освобождает память. Если менеджер не закрыть явно, таблицы освободятся сами при уничтожении объекта, но в длинных обработках лучше закрывать вручную, чтобы не держать данные зря.

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

Что делать с размером базы после удаления

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

Для файловой базы (.1CD) порядок такой:

  1. Завершите все сеансы — файловую базу сжимают монопольно.
  2. Запустите Конфигуратор → Администрирование → Тестирование и исправление.
  3. Отметьте пункт сжатия таблиц информационной базы и выполните проверку.

Сжатие физически уменьшает файл за счёт освободившегося после удаления места.

Для клиент-серверной базы на СУБД размер таблиц так не возвращается — пустое место внутри таблиц остаётся занятым на уровне сервера баз данных. Освобождение места — это задача администратора СУБД (перестроение индексов, сжатие на стороне сервера), и делается оно штатными средствами самой СУБД, а не из 1С. Из конфигуратора на серверной базе Тестирование и исправление чинит логику данных и пересоздаёт таблицы при реструктуризации, но файл базы данных на диске сам по себе не ужимает.

Отдельно стоит журнал регистрации. Удаление объектов его не трогает — все записи о действиях пользователей остаются и могут занимать больше самой базы. Если место на диске съел именно журнал, его сокращают в конфигураторе: Администрирование → Настройка журнала регистрации, где задаётся глубина хранения, и отдельной командой сокращения журнала до указанной даты. Это не влияет на учётные данные, только на историю событий.

Тестирование и исправление останавливает работу пользователей и может идти долго на большой базе. Запускайте в нерабочее время и только с актуальной резервной копией.

Перед массовой очисткой пройдитесь по короткому списку — он убережёт от необратимых ошибок:

Перед массовым удалением
Выполнено: 0 / 5

Типичные ошибки при очистке данных

Ошибки здесь стоят дорого, потому что почти всё необратимо.

  • ❌ Прямое Удалить() вместо пометки. Без контроля ссылок в базе появляются битые ссылки «<Объект не найден>». Если не уверены в связях — только пометка и штатное удаление помеченных.
  • ❌ Затирание движений вместо снятия проведения. Документ и его записи расходятся, отчёты врут. Для обычной отмены движений снимайте проведение документа.
  • ❌ Ожидание, что база сразу похудеет. После удаления помеченных размер не падает сам: файловую сжимают через Тестирование и исправление, серверную — средствами СУБД.
  • ❌ Массовое удаление в рабочее время. Цикл удаления в живой базе конфликтует с чужими сеансами и блокировками. Делайте в монополии или когда никто не работает .
  • ❌ Удаление без резервной копии. Отменить Удалить() и удаление помеченных нечем, кроме как восстановлением из бэкапа.

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

Можно ли отменить удаление помеченных объектов?
Нет. Удаление помеченных необратимо. Единственный способ вернуть объекты — восстановить базу из резервной копии, сделанной до удаления. Поэтому бэкап обязателен.
Чем `ПометитьНаУдаление(Истина)` отличается от `Удалить()`?
ПометитьНаУдаление только ставит пометку — объект остаётся в базе, удаление произойдёт позже штатной обработкой с контролем ссылок. Удалить() стирает объект сразу и без проверки ссылок.
Как очистить движения документа, не удаляя сам документ?
Снимите проведение документа — движения по всем регистрам удалятся, а документ останется. Программно это делается записью пустого набора записей регистра с отбором по регистратору.
Почему после удаления данных база не уменьшилась в размере?
Платформа не сжимает хранилище автоматически. Файловую базу сжимают пунктом тестирования и исправления в конфигураторе, место в серверной базе освобождает администратор средствами СУБД.
Как удалить сразу много помеченных объектов из кода?
Отберите их запросом по условию ПометкаУдаления, в цикле получите объект через ПолучитьОбъект() и вызовите Удалить(). Запускайте в монопольном режиме и после резервного копирования.