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

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

Как программно удалить запись регистра сведений в 1С

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

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

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

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

Как устроено удаление записей регистра сведений

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

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

Удаление одной записи через набор записей

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

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

НаборЗаписей.Отбор.Номенклатура.Установить(НоменклатураСсылка);

НаборЗаписей.Отбор.ТипЦен.Установить(ТипЦенСсылка);

НаборЗаписей.Записать(); // записей нет — под отбор попавшие строки удалятся

Ключевой момент: набор ничего не читаем и не заполняем. Если перед записью вызвать Прочитать() и очистить набор — результат будет тем же, но лишнее чтение замедлит операцию. Для удаления чтение не требуется.

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

Удаление через менеджер записи

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

МенеджерЗаписи = РегистрыСведений.КурсыВалют.СоздатьМенеджерЗаписи();

МенеджерЗаписи.Период = ДатаКурса;

МенеджерЗаписи.Валюта = ВалютаСсылка;

МенеджерЗаписи.Прочитать();

Если МенеджерЗаписи.Выбран() Тогда

МенеджерЗаписи.Удалить();

КонецЕсли;

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

Массовое удаление: по измерению, за период, полная очистка

Чтобы удалить все записи по одному значению измерения (например, все данные по контрагенту), установите отбор только по этому измерению и запишите пустой набор. Для периодического регистра можно ограничить диапазон дат через отбор по полю «Период» с видом сравнения.

Для полной очистки регистра отбор не устанавливается вообще — пустой набор записывается без отборов, и таблица регистра очищается целиком:

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

НаборЗаписей.Записать(); // регистр очищен полностью

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

Порядок безопасного массового удаления
  1. 1
    Сформируйте запрос, выбирающий записи по нужному условию, и проверьте количество — оно должно совпадать с ожиданием
  2. 2
    Сделайте резервную копию базы или выгрузите удаляемые записи
  3. 3
    Удаляйте порциями: выбрали пакет ключей — удалили набором с отбором — зафиксировали транзакцию
  4. 4
    После завершения повторно выполните контрольный запрос: записей по условию быть не должно

Особенности периодических регистров и регистров с регистратором

Периодический регистр сведений

В периодическом регистре часть ключа записи — поле «Период». Чтобы удалить конкретную запись, отбор по периоду нужно установить точно на дату записи. Если установить только отбор по измерению, удалятся записи по этому измерению за все периоды. Для удаления за интервал используйте отбор с видом сравнения «БольшеИлиРавно» и «МеньшеИлиРавно» по полю Период.

Регистр, подчинённый регистратору

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

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

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

НаборЗаписей.Записать();

Учтите: если документ проведён, при следующем его перепроведении записи появятся снова. Поэтому для регистров с регистратором корректнее работать с самим документом, а не с записями напрямую.

Типичные ошибки и как их избежать

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

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

Третья группа проблем — права и транзакционность. У пользователя, от имени которого выполняется код, должны быть права на изменение регистра; в клиент-серверном варианте массовое удаление стоит выполнять в фоновом задании, чтобы не блокировать интерфейс и не упираться в таймауты.

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

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

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

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ КОЛИЧЕСТВО(*) КАК КоличествоЗаписей

|ИЗ РегистрСведений.ЦеныНоменклатуры КАК Цены

|ГДЕ Цены.Номенклатура = &Номенклатура";

Запрос.УстановитьПараметр("Номенклатура", НоменклатураСсылка);

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

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

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

Запрос с условием отбора после удаления
Норма

Возвращает 0 записей

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

Записи остались — отбор в коде не совпал с условием проверки

Контрольный запрос без условия
Норма

Остались записи с другими значениями измерений

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

Регистр пуст полностью — отбор был установлен неверно

Связанные документы-регистраторы
Норма

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

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

Записи появились снова после перепроведения документа

Часто задаваемые вопросы

Можно ли удалить запись регистра сведений через «Удалить()» у ссылки?

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

Как удалить записи регистра сведений за определённый период?

Для периодического регистра установите два элемента отбора по полю «Период» с видами сравнения «БольшеИлиРавно» (начало интервала) и «МеньшеИлиРавно» (конец интервала), затем запишите пустой набор записей.

Что будет, если записать пустой набор без отбора?

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

Почему после удаления записи появились снова?

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

Можно ли откатить удаление, если ошибся с отбором?

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

Что быстрее для больших объёмов: набор записей или запрос?

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

Итог

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

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