Очистка независимого регистра сведений: от одной строки до всего регистра

· 9 мин

Содержание

Одну запись независимого регистра сведений проще всего удалить руками: откройте регистр через Главное меню → Все функции → Регистры сведений, выделите строку и нажмите Delete. Для массовой очистки нужен код: пустой набор записей с отбором по измерениям, записанный с замещением, удаляет все попавшие под отбор строки.

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

Чем запись независимого регистра отличается от записи документа

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

Запись такого регистра определяется ключом:

  • 📅 Период — если регистр периодический (по дню, месяцу, году и т. д.);
  • 🔑 все измерения — например, «Номенклатура» и «Тип цен»;
  • 📦 ресурсы и реквизиты — это уже данные записи, в ключ они не входят.

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

Сравнение с регистром, подчинённым регистратору:

ПризнакНезависимый регистрПодчинённый регистратору
Кто пишет записиПользователь, обработка, кодТолько документ при проведении
Удаление строки в спискеМожно, при наличии правНельзя — список только для чтения
Как убрать записиУдалить строку или очистить наборомОтменить проведение или удалить документ
Ключ записиПериод + измеренияРегистратор + номер строки

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

Режим записи видно в конфигураторе: откройте регистр в дереве метаданных, вкладка «Основные». Без доступа к конфигуратору косвенный признак — в списке регистра есть колонка «Регистратор».

Удаление записи регистра сведений вручную через «Все функции»

Этот способ подходит, когда нужно убрать одну или несколько строк и вы видите их в списке. Программирование не нужно.

Как включить меню «Все функции»

  1. Откройте Главное меню (кнопка с тремя полосками в левом верхнем углу).
  2. Выберите Сервис → Параметры.
  3. Поставьте флажок «Отображать команду “Все функции”» и нажмите «Применить».

В свежих версиях платформы этот пункт может называться «Режим технического специалиста» или «Функции для технического специалиста» — смысл тот же.

Пошаговое удаление строки

  1. Главное меню → Все функции.
  2. Раскройте ветку «Регистры сведений» и откройте нужный регистр двойным щелчком.
  3. Найдите строку. Удобнее через поиск (Ctrl+F) или отбор по колонке: Ещё → Настроить список, вкладка «Отбор».
  4. Выделите строку. Несколько строк — с зажатым Ctrl или Shift.
  5. Нажмите Delete или выберите команду удаления в меню Ещё.
  6. Подтвердите удаление в вопросе программы.

Запись удаляется сразу и безвозвратно. Пометки удаления для регистров нет.

Перед удалением сохраните то, что собираетесь стереть: Ещё → Вывести список, затем сохраните табличный документ в Excel. Если ошиблись, по этому файлу строку можно восстановить вручную.

Права пользователя

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

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

Найти записи консолью запросов и удалить их

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

Порядок работы такой:

  1. Откройте консоль запросов (внешняя обработка из комплекта поставки или любая привычная вам).
  2. Напишите выборку по регистру с нужными условиями.
  3. Проверьте количество строк и выборочно — их содержимое.
  4. Перенесите условия из запроса в код удаления или в отбор списка.

Пример запроса: все цены по одному типу цен, установленные до начала года.

ВЫБРАТЬ
    Цены.Период КАК Период,
    Цены.Номенклатура КАК Номенклатура,
    Цены.ТипЦен КАК ТипЦен,
    Цены.Цена КАК Цена
ИЗ
    РегистрСведений.ЦеныНоменклатуры КАК Цены
ГДЕ
    Цены.ТипЦен = &ТипЦен
    И Цены.Период < &НачалоГода

Имена регистра и полей здесь условные. В вашей конфигурации посмотрите точные имена в конструкторе запроса — он показывает поля регистра списком.

Многие консоли запросов имеют режим выполнения произвольного кода. Если он есть, найденные записи можно удалить там же — кодом из следующего раздела. Сам запрос при этом остаётся только инструментом отбора.

Программное удаление: менеджер записи и набор записей

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

Код выполняйте на сервере: в форме обработки — в процедуре с директивой &НаСервере. Объекты регистров на тонком клиенте недоступны.

Одна запись: менеджер записи

Заполните все поля ключа и вызовите Удалить():

&НаСервере
Процедура УдалитьОднуЗапись(Номенклатура, ТипЦен, ДатаПериода)

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

    МенеджерЗаписи.Прочитать();
    Если МенеджерЗаписи.Выбран() Тогда
        МенеджерЗаписи.Удалить();
    КонецЕсли;

КонецПроцедуры

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

Группа записей: пустой набор с отбором

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

&НаСервере
Процедура УдалитьЦеныТовара(Номенклатура)

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

КонецПроцедуры

Как это работает: Записать(Истина) означает «запиши с замещением». Платформа удаляет все записи, подходящие под отбор, и записывает содержимое набора. Набор пуст — значит, остаётся только удаление.

Отбор можно ставить по нескольким измерениям и по периоду:

НаборЗаписей.Отбор.Номенклатура.Установить(Номенклатура);
НаборЗаписей.Отбор.ТипЦен.Установить(ТипЦен);
НаборЗаписей.Отбор.Период.Установить(ДатаПериода);

Отбор в наборе — только на равенство. Условие «период раньше даты» или «сумма меньше нуля» через отбор набора не задать. Для таких случаев нужна связка «запрос + удаление», о ней ниже.

Набор без единого установленного отбора, записанный с замещением, удаляет ВСЕ записи регистра. Иногда это именно то, что нужно. Но чаще это последствие забытой строки с Установить().

Записи по сложному условию

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

&НаСервере
Процедура УдалитьСтарыеЦены(ТипЦен, НачалоГода)

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    |    Цены.Период,
    |    Цены.Номенклатура,
    |    Цены.ТипЦен
    |ИЗ
    |    РегистрСведений.ЦеныНоменклатуры КАК Цены
    |ГДЕ
    |    Цены.ТипЦен = &ТипЦен
    |    И Цены.Период < &НачалоГода";
    Запрос.УстановитьПараметр("ТипЦен", ТипЦен);
    Запрос.УстановитьПараметр("НачалоГода", НачалоГода);

    Выборка = Запрос.Выполнить().Выбрать();
    Пока Выборка.Следующий() Цикл
        МенеджерЗаписи = РегистрыСведений.ЦеныНоменклатуры.СоздатьМенеджерЗаписи();
        ЗаполнитьЗначенияСвойств(МенеджерЗаписи, Выборка);
        МенеджерЗаписи.Удалить();
    КонецЦикла;

КонецПроцедуры

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

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

Что именно нужно удалить?

Удаление большого объёма записей без зависаний

Удаление сотен тысяч строк одним циклом — плохая идея. Пользователи упираются в блокировки, а при сбое посередине непонятно, что успело удалиться.

Режете по измерению, а не по строке

Если записи группируются по измерению, удаляйте наборами: один Записать(Истина) на значение измерения. Запросом соберите список значений (ВЫБРАТЬ РАЗЛИЧНЫЕ Номенклатура …), затем для каждого — пустой набор с отбором. Тысяча товаров — тысяча операций вместо, скажем, ста тысяч.

Порции и транзакции

Когда удалять приходится построчно, группируйте удаление по 500–1000 записей в одной транзакции:

РазмерПорции = 1000;
Счетчик = 0;
НачатьТранзакцию();
Попытка
    Пока Выборка.Следующий() Цикл
        МенеджерЗаписи = РегистрыСведений.ЦеныНоменклатуры.СоздатьМенеджерЗаписи();
        ЗаполнитьЗначенияСвойств(МенеджерЗаписи, Выборка);
        МенеджерЗаписи.Удалить();
        Счетчик = Счетчик + 1;
        Если Счетчик % РазмерПорции = 0 Тогда
            ЗафиксироватьТранзакцию();
            НачатьТранзакцию();
        КонецЕсли;
    КонецЦикла;
    ЗафиксироватьТранзакцию();
Исключение
    ОтменитьТранзакцию();
    ВызватьИсключение;
КонецПопытки;

Если код упадёт, откатится только текущая порция. Уже зафиксированные порции останутся удалёнными — при повторном запуске запрос просто их не найдёт.

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

У набора и менеджера записи есть свойство ОбменДанными.Загрузка. Если установить его в Истина до записи, не выполняются обработчики ПередЗаписью и ПриЗаписи модуля набора записей:

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

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

Когда запускать

  • 🕘 Массовое удаление — в нерабочее время или когда в базе мало пользователей.
  • 🔁 В распределённой базе (РИБ) удаления тоже уходят в обмен. Убедитесь, что очистка нужна во всех узлах.
  • 💾 Перед очисткой регистра целиком сделайте резервную копию базы: выгрузку .dt или бэкап СУБД в клиент-серверном варианте.

Ошибки при удалении записей и как их не допустить

Почти все проблемы сводятся к неверному ключу или неверному отбору.

Диагностика: выберите симптом

Ещё два правила, которые спасают данные:

  1. Перед любым массовым удалением запустите тот же отбор запросом и посмотрите число строк. Если ждали 300, а получили 30 000 — остановитесь.
  2. Отлаживайте код на копии базы. Ошибку в отборе на копии вы увидите сразу, а на рабочей базе — когда пользователи не найдут цены.

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

Можно ли восстановить удалённую запись регистра сведений?
Встроенной корзины нет. Восстановить можно из резервной копии базы или вручную, если вы заранее выгрузили строки через «Ещё → Вывести список».
Удалит ли обработка «Удаление помеченных объектов» записи регистра?
Нет. Она работает с объектами, у которых есть пометка удаления: справочниками, документами. У записей регистра сведений пометки нет.
Чем удаление записи отличается от очистки ресурса?
Удаление убирает строку вместе с ключом. Если записать строку с пустым ресурсом, ключ останется, и для периодического регистра срез последних вернёт пустое значение вместо предыдущего.
Что будет со срезом последних после удаления записи периодического регистра?
Срез начнёт возвращать предыдущую по дате запись с тем же набором измерений. Если предыдущей нет — значения по этому ключу не будет вовсе.
Нужен ли монопольный доступ для удаления записей?
Нет. Удаление записей — обычная запись данных, она работает при подключённых пользователях. Монопольный режим нужен для изменения структуры базы, а не для правки данных.