При разработке на платформе 1С:Предприятие часто возникает ситуация, когда в результате поиска (например, через метод НайтиПоСсылкам) или из формы списка мы получаем объект типа РегистрСведенийКлючЗаписи. Несмотря на то, что этот объект однозначно идентифицирует запись в базе данных, у него нет встроенного метода Удалить(). Это часто ставит начинающих разработчиков в тупик. В этой статье мы подробно разберем, как правильно использовать ключ записи для удаления данных, проанализируем различия между основными программными объектами регистров и выясним, каких ошибок стоит избегать, чтобы не потерять важную информацию.
Для начала проанализируем, почему в 1С существует три разных типа объектов для работы с регистрами сведений. Без этого понимания выбор правильного метода удаления будет неочевидным.
Если наш регистр является независимым, самый простой и читаемый способ — использовать МенеджерЗаписи. Рассмотрим, как связать полученный ключ с менеджером и выполнить удаление. Проанализируем универсальный подход, который будет работать на всех версиях платформы, начиная с 8.1 и заканчивая актуальными релизами 8.3.
Для этого мы создаем экземпляр менеджера записи и «переносим» в него значения измерений из ключа. Самый надежный способ сделать это — воспользоваться функцией ЗаполнитьЗначенияСвойств.
// Предположим, ПереданныйКлюч — это объект типа РегистрСведенийКлючЗаписи
МенеджерЗаписи = РегистрыСведений.НазваниеВашегоРегистра.СоздатьМенеджерЗаписи();
// Копируем значения измерений из ключа в менеджер
ЗаполнитьЗначенияСвойств(МенеджерЗаписи, ПереданныйКлюч);
// Удаляем запись из базы данных
МенеджерЗаписи.Удалить();
Важный нюанс: В некоторых версиях платформы (особенно в 8.3) у менеджера записи есть метод Заполнить(), который может принимать ключ записи напрямую. Однако, как показывает практика обсуждений на форумах, в старых конфигурациях или специфических сборках этот метод может отсутствовать или работать некорректно. Поэтому использование ЗаполнитьЗначенияСвойств считается «золотым стандартом» надежности.
Рассмотрим ситуацию, когда нам нужно удалить запись, но мы хотим быть уверены в производительности или работаем с более сложной логикой. Удаление через НаборЗаписей технически выглядит как запись пустого набора с установленным фильтром по измерениям.
Выясним, как это работает на практике. Когда мы устанавливаем отбор в наборе записей и вызываем метод Записать(), система заменяет в базе данных все записи, подходящие под этот отбор, на те, что содержатся в наборе. Если набор пуст — записи просто удаляются.
НаборЗаписей = РегистрыСведений.НазваниеВашегоРегистра.СоздатьНаборЗаписей();
// Устанавливаем фильтры по всем измерениям, которые есть в ключе
НаборЗаписей.Отбор.Измерение1.Установить(ПереданныйКлюч.Измерение1);
НаборЗаписей.Отбор.Измерение2.Установить(ПереданныйКлюч.Измерение2);
// Если регистр периодический, не забудьте про Период
// НаборЗаписей.Отбор.Период.Установить(ПереданныйКлюч.Период);
// Записываем пустой набор (параметр Истина означает замещение данных)
НаборЗаписей.Записать(Истина);
Этот метод особенно эффективен, если вам нужно удалить не одну запись, а группу записей, объединенных общим значением какого-либо измерения.
Проанализируем опасный метод, который часто встречается в коде новичков и может привести к катастрофической потере данных. Речь идет о получении всех «нужных» записей запросом, выгрузке их в таблицу и последующей загрузке этой таблицы в набор записей для «очистки» старых данных.
В чем заключается опасность? Представим сценарий:
НаборЗаписей и записываете его.Результат: 101-я запись будет безвозвратно удалена, так как она не попала в ваш запрос, а набор записей при записи заменяет все данные в рамках установленного отбора (или вообще все данные в регистре, если отбор не установлен).
Вывод: Никогда не используйте полную перезапись регистра для удаления конкретных строк. Всегда используйте точечные отборы в наборе записей или менеджер записи.
Если ваш регистр сведений имеет режим записи «Подчинение регистратору», то ни метод с МенеджерЗаписи, ни прямая установка отборов по измерениям в наборе записей не позволят вам удалить строку. В таких регистрах жизнь записи жестко связана с документом-регистратором.
Чтобы удалить запись в таком случае, мы должны действовать по следующему алгоритму:
Прочитать()).Выясним, какой способ быстрее. Если вам нужно удалить одну запись, разница между менеджером и набором минимальна. Однако, если задача стоит в удалении 10 000 записей по списку ключей, выполнение МенеджерЗаписи.Удалить() в цикле будет крайне медленным. Каждое такое удаление — это отдельная транзакция и отдельное обращение к серверу БД.
В целях оптимизации рекомендуем:
НаборЗаписей.НачатьТранзакцию() и ЗафиксироватьТранзакцию().&НаСервере), так как объекты МенеджерЗаписи и НаборЗаписей недоступны на тонком клиенте.Подводя итог, можно сказать, что наиболее универсальным и безопасным способом удаления записи по ключу является использование Менеджера записи с предварительным заполнением через ЗаполнитьЗначенияСвойств. Это решение прозрачно, надежно и легко поддается отладке.